elasticsearch源码分析---discovery模块
来源:互联网 发布:gif制作软件中文版 编辑:程序博客网 时间:2024/05/17 22:00
根据guice的注册绑定机制,discovery的绑定顺序是这样的:
InternalNode中添加DiscoveryModule:
modules.add(new DiscoveryModule(settings));
DiscoveryModule中创建了LocalDiscoveryModule(不分析)或者ZenDiscoveryModule:
public Iterable<? extends Module> spawnModules() { Class<? extends Module> defaultDiscoveryModule; if (DiscoveryNode.localNode(settings)) { defaultDiscoveryModule = LocalDiscoveryModule.class; } else { defaultDiscoveryModule = ZenDiscoveryModule.class; } return ImmutableList.of(Modules.createModule(settings.getAsClass(DISCOVERY_TYPE_KEY, defaultDiscoveryModule, "org.elasticsearch.discovery.", "DiscoveryModule"), settings)); }
ZenDiscoveryModule中将Discovery Class绑定到了ZenDiscovery Class
protected void bindDiscovery() { bind(Discovery.class).to(ZenDiscovery.class).asEagerSingleton(); }
InternalNode中启动DiscoveryService:
DiscoveryService discoService = injector.getInstance(DiscoveryService.class).start();
DiscoveryService最终绑定到哪里呢?在ZenDiscovery Class上:
@Inject public DiscoveryService(Settings settings, Discovery discovery) { super(settings); this.discovery = discovery; this.initialStateTimeout = componentSettings.getAsTime("initial_state_timeout", TimeValue.timeValueSeconds(30)); }看,是在Discovery这个类中,因此最终落在ZenDiscovery上。
DiscoveryService启动过程就是启动ZenDiscovery,如下:
protected void doStart() throws ElasticsearchException { initialStateListener = new InitialStateListener(); discovery.addListener(initialStateListener); discovery.start(); logger.info(discovery.nodeDescription()); }
ZenDiscovery除了共用transport等其他模块外,还有以下几个辅助类:
this.electMaster = new ElectMasterService(settings); nodeSettingsService.addListener(new ApplySettings()); this.masterFD = new MasterFaultDetection(settings, threadPool, transportService, this); this.masterFD.addListener(new MasterNodeFailureListener()); this.nodesFD = new NodesFaultDetection(settings, threadPool, transportService); this.nodesFD.addListener(new NodeFailureListener()); this.publishClusterState = new PublishClusterStateAction(settings, transportService, this, new NewClusterStateListener(), discoverySettings); this.pingService.setNodesProvider(this); this.membership = new MembershipAction(settings, transportService, this, new MembershipListener());NodeFaultDetection:检测其他集群节点的状态(master节点使用)
在其中维护了一张Node和NodeFD的映射关系,注册了PingRequestHandler和FDConnectionListener(根据setting设定),以及处理逻辑。
private final ConcurrentMap<DiscoveryNode, NodeFD> nodesFD = newConcurrentMap();updateNodes用来更新以上数据结构:
public void updateNodes(DiscoveryNodes nodes) { DiscoveryNodes prevNodes = latestNodes; this.latestNodes = nodes; if (!running) { return; } DiscoveryNodes.Delta delta = nodes.delta(prevNodes); for (DiscoveryNode newNode : delta.addedNodes()) { if (newNode.id().equals(nodes.localNodeId())) { // no need to monitor the local node continue; } if (!nodesFD.containsKey(newNode)) { nodesFD.put(newNode, new NodeFD()); threadPool.schedule(pingInterval, ThreadPool.Names.SAME, new SendPingRequest(newNode)); } } for (DiscoveryNode removedNode : delta.removedNodes()) { nodesFD.remove(removedNode); } }
通过比较当前集群中nodes和上一个记录的集群中nodes来确定新加入或者删除的node,本地节点无需监控。最终在nodesFD中的节点就是当前需要检测的节点。
MasterNodeDetection:检测master节点的状态(非master节点使用)
ElectMasterService:选举master节点。
现在来看一下ZenDiscovery的启动流程:
protected void doStart() throws ElasticsearchException { Map<String, String> nodeAttributes = discoveryNodeService.buildAttributes(); // note, we rely on the fact that its a new id each time we start, see FD and "kill -9" handling final String nodeId = DiscoveryService.generateNodeId(settings); localNode = new DiscoveryNode(settings.get("name"), nodeId, transportService.boundAddress().publishAddress(), nodeAttributes, version); latestDiscoNodes = new DiscoveryNodes.Builder().put(localNode).localNodeId(localNode.id()).build(); nodesFD.updateNodes(latestDiscoNodes); pingService.start(); // do the join on a different thread, the DiscoveryService waits for 30s anyhow till it is discovered asyncJoinCluster(); }
NodeFaultDetection实例nodesFD会更新维护的map结构(新节点加入了,或许这个时刻有些节点也被删除了,获取新的delta关系)
然后启动加入本地节点的流程asyncJoinCluster,最终调用到innerJoinCluster:
大致逻辑是先findMaster,如果是master是自己,做标识并启动NodesFaultDetection来监控其余节点,发布自己是master节点的消息,如果不是自己,循环连接master节点,直到连接成功,向master节点发送要求加入cluster的消息,启动MasterFaultDetection,来监控master节点的状态。
findMaster会确定master节点:对各个节点发送ping信息,根据返回的节点属性还获取可能的master节点(过滤client节点,过滤data但是不是master的节点)。判断当前获取的具有master节点资格的数据是否符合最小master节点数目,如果不符合,说明还有节点没有启动,返回null,继续等待节点启动直到符合最小master节点数目位置。下边出现了两种情况:如果在节点的ping信息返回中含有master节点,则在这些ping信息中包含的master节点中确定一个master节点返回,如果在节点的ping信息中无master节点,则在具有master节点资格的节点中选举一个作为master节点。选举策略有ElectMasterService负责。
- elasticsearch源码分析---discovery模块
- elasticsearch源码分析之discovery(七)
- elasticsearch源码分析之discovery(七)
- elasticsearch源码分析---threadpool模块
- elasticsearch源码分析--transport模块
- Elasticsearch模块功能之-自动发现(Discovery)
- Elasticsearch模块功能之-自动发现(Discovery)
- Prometheus 实战于源码分析之discovery
- elasticsearch zen discovery
- elasticsearch源码分析---TransportClient
- discovery分析
- elasticsearch源码分析--启动进程
- elasticsearch源码分析---索引数据
- Elasticsearch源码分析十二--过滤器
- elaticsearch之discovery模块
- SocketServer模块源码分析
- Provision Discovery流程分析
- elasticsearch集群发现机制:Zen Discovery
- 程序员神吐槽,说出那些苦逼的日子!
- SecureCRT
- ALV颜色设置
- OpenStack Heat总结之:icehouse版本中Heat的简单介绍(转)
- 如何成为一名优秀的CTO(首席技术官)
- elasticsearch源码分析---discovery模块
- 数据挖掘笔记-文本情感简单判断
- sql server函数
- Cocos2dx-3.0-rc0版本Lua的配置与使用
- Cobol License Manager Error; 'Unable to open License Key database'
- OC语言--内存管理
- 论优秀程序员需要的品/质
- DLAN初步了解
- 剑指offer 面试题15 找到单链表倒数第k个结点