ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。ES能提供强大的索引能力,很大一方面原因是由多个分布在不同机器的es实例组成集群对外提供服务,这种可以横向扩展的机制可以极大提升服务能力。每一个es实例都是基于Lucene的独立服务,负责本地分片上数据的索引和查询,如果掌握了ES的是实现细节,就会对es所具有的特性有一个本质的认识。

我们会先基于ES2.3.2源码来理清楚ES的启动流程,然后介绍下ES节点(Node)的内部结构,最后再分析下ES插件机制并举一个安全插件的开发示例。

1.ES节点启动流程

org.elasticsearch.Elasticsearch.main
org.elasticsearch.bootstrap
{
启动用户线程keepAliveThread
导入环境变量和配置参数
创建pid文件
检查(jvm环境,安全、等等)
nodeBuilder.build()
node.start();
keepAliveThread.start();
}

2.Node启动

Node()
{
更新setting和environment
构造pluginsService并动态加载plugin @2.1
加载并初始化modules(PluginsModule/ClusterModule/RestModule/TransportModule/ActionModule等)
使用guice构造各modules
构造client对象(performing actions/operations against the cluster
} Node start()
{
构造services和plugins实例。 @2.2
TransportService启动 @2.3
DiscoveryService启动 @2.4
HttpServerTransport绑定地址,开始监听 @2.5
}

可以看到node的初始化过程主要包括三部分,第一是配置node环境,第二是启动插件服务(es提供了插件功能来进行扩展功能,这也是它的一个亮点),加载需要的插件,最后就是通过guice加载各个模块,启动各个服务。

先说一下插件加载过程。每个node在加载各个模块前,会首先加载所需要的插件,如果有些插件加载不成功node会启动失败。这里会加载三类插件:首先是配置插件,配置到节点配置文件中插件,如分词插件等;然后查找classpath中能找到的插件,这些插件一般防止在plugin文件夹中;最后是加载site插件,site插件是不涉及java代码的纯网站式插件,如监控插件head,bigdesk等。任何使用者都可以开发自己需要的插件,只要按着elasticsearch相关版本的插件开发规范来实现即可。接下来首先说一下启动各个模块的过程。elasticsearch各个功能模块实现的非常好,解耦非常完美,很多模块都实现了生命周期接口,只有启动它才能够对外提供服务,它的启动过程也是功能模块初始化的过程。因此,node节点的启动过程也就是这些模块初始化的过程。

@2.1 构造pluginsService并动态加载plugin

依次调用各插件的OnModule方法。在OnModule方法内部可以针对多种model来依次操作,比如下面的添加过滤器或者替换TransportService。

为RestModule添加一个过滤器;
public void onModule(RestModule module) {module.addRestAction(AuthorityRestFilter.class);}
为actionModels添加自定义过滤器AuthorityActionFilter;
public void onModule(final ActionModule module) {module.registerFilter(AuthorityActionFilter.class);}

使用自定义AuthorityTransportService来代替默认的TransportService;
public void onModule(final TransportModule module) { module.setTransportService(AuthorityTransportService.class, name());
}
 

@2.2启动各项服务

for (Class<? extends LifecycleComponent> plugin : pluginsService.nodeServices()) {
injector.getInstance(plugin).start();// 加载插件中的自定义服务并启动
} //通过guice获取各个模块的service接口并启动
injector.getInstance(MappingUpdatedAction.class).setClient(client);
injector.getInstance(IndicesService.class).start();
injector.getInstance(IndexingMemoryController.class).start();
injector.getInstance(IndicesClusterStateService.class).start();
injector.getInstance(IndicesTTLService.class).start();
injector.getInstance(SnapshotsService.class).start();
injector.getInstance(SnapshotShardsService.class).start();
injector.getInstance(RoutingService.class).start();
injector.getInstance(SearchService.class).start();
injector.getInstance(MonitorService.class).start();
injector.getInstance(RestController.class).start(); // TODO hack around circular dependencies problems
injector.getInstance(GatewayAllocator.class).setReallocation(injector.getInstance(ClusterService.class), injector.getInstance(RoutingService.class)); injector.getInstance(ResourceWatcherService.class).start();
injector.getInstance(GatewayService.class).start();

@2.3 用于集群内节点间通信的引擎

基于netty实现的tcp引擎 NettyTransport 来构造客户端BootStrap,用于和其它ES节点间的通信。如果是server模式,还要启动ServerBootstrap用于接收其它客户端发来的请求

public class NettyTransport extends AbstractLifecycleComponent<Transport> implements Transport

@2.4 发现功能

发现功能主要用于节点启动后发现集群,master向所有节点发布集群状态,选举master节点并引发集群节点变得事件

@2.5 对外提供http服务的引擎

使用netty实现的 http 引擎 
public class NettyHttpServerTransport extends AbstractLifecycleComponent<HttpServerTransport> implements HttpServerTransport

3.ES实例退出

shutdownhook触发
node.close,停止各种服务、插件、脚本、线程池
CountDownLatch减一,keepAliveThread退出
删除pid文件

最新文章

  1. 站内全文检索服务来了,Xungle提供免费全文检索服务
  2. ZeroMQ接口函数之 :zmq_msg_init_data - 从一个指定的存储空间中初始化一个ZMQ消息对象的数据
  3. swiper
  4. eclipse生成uml
  5. WebService的原理和过程
  6. nginx 配置高并发
  7. hdu 1829-A Bug&#39;s LIfe(简单带权并查集)
  8. HDU1009 FatMouse&#39; Trade
  9. LINUX 内核月报 taobao
  10. Mozilla 构建系统(转)
  11. WebForms vs. MVC
  12. word使用新技能
  13. [转]ubuntu下解压zip文件
  14. geeksforgeeks-Array-Rotate and delete
  15. Paget Object 设计模式编写selenium测试用例
  16. 牛客多校10 D Rikka with Prefix Sum 不是数据结构
  17. centos/rhel 7 几个最重要变化(systemd,firewalld,networkmanager,文件系统)
  18. 比较完整的URL验证
  19. SGU---102 欧拉函数
  20. SlickEdit V21 2016 破解教程,win linux mac

热门文章

  1. svn服务器用户名密码更改后,如何更新本地用户名密码
  2. JAVA上传文件到FTP上
  3. Linux C++获取磁盘剩余空间和可用空间
  4. 《Head First设计模式》读书笔记
  5. 「算法笔记」CRT 与 exCRT
  6. CapstoneCS5265设计替代CH7211 |Type-C转HDMI2.0方案|替代CH7211
  7. Java初学者作业——定义客户类(Customer),客户类的属性包括:姓名、年龄、电话、余额、账号和密码;方法包括:付款。
  8. JavaScript交互式网页设计 • 【第2章 JavaScript函数与事件】
  9. nginx rewrite 基础
  10. 初识python: 生成器并行(做包子,吃包子)