Overseer也可以称为cluster leader,也就是集群的主,与shard leader有着很大的区别,shard leader主要是为了保证collection数据的一致性,而Overseer则是为了保证集群操作以及数据的安全性。
Overseer的选举
在看Overseer如何工作之前,我们先看一下怎么才能成为Overseer?
成为Overseer必须要经过选举,我们先大概说一下solr Overseer的选举过程,有一点要明确的是,solr集群中每个实例连接上来都会在/overseer_elect/election
下创建临时顺序节点( Ephemeral Sequential),每个临时节点的名字组成有以下几部分:
- 会话ID(Session ID)
- 节点名(Node Name)
- 序号(SEQ)
当集群中没有Overseer的时候,就会基于/overseer_elect/election
下的临时顺序节点进行主的选举(可以阅读LeaderElector.java)。
关于Overseer的选举重点关注这两个方法: - LeaderElector::joinElection()
- ElectionWatcher::process()
通过这两个方法,我们不难发现Overseer的选举,可能在两种情况出发,第一种就是有节点加入: - 将当前节点注册上去(后面可能参与选举)
- 检测当前节点是不是主,即获取
/overseer_elect/election
下的所有节点并排序(seq从小到大),序号最小的就是主 - 如果发现自己是主,则会进入主的处理流程,即OvereerElectionContext::runLeaderProcess()
- 如果自己不是主,则会注册对主节点的Watcher,即ElectionWatcher
再来看看ElectionWatcher::process(),也就是说当关注的主节点出现异常了,那么Zookeeper就会向所有节点推送Watcher事件,进入到process流程,其实process做的事情和上面有点重复:
- 检测当前节点是不是主,即获取
/overseer_elect/election
下的所有节点并排序(seq从小到大),序号最小的就是主 - 如果发现自己是主,则会进入主的处理流程,即OvereerElectionContext::runLeaderProcess()
- 如果自己不是主,则会注册对主节点的Watcher,即ElectionWatcher
梳理了Overseer的选举,下面就来看一下成为Overseer的节点在干嘛。
Overseer在做什么?
成为了Overseer做的第一节点事情就是把自己主的这个信息做个见证,也就是在/overseer_elect/leader
中记录节点信息,内容大致如下:
{"id":"${session_id}-${node_name}-n_${seq_id}"}
下面就是Overseer做自己本分的事情了,Overseer节点会启动Overseer线程(进入到Overseer.java中),
Overseer在行使自己权利之前,还是先要确认一下自己的身份,避免自己越权。其实从上面的逻辑看,该节点99.99%就是主了,但是在一个分布式环境下,我们永远是没办法相信网络是可靠的,所以还是慎重为好。
一旦确认好自己是主了,那么进入循环,不断的从workQueue(DistributedQueue)中读取消息,然后处理消息。至于workQueue(DistributedQueue)的我们后面说,这边先略过。
每一个消息都会对应一个operation
,该operation
主要分为两类:
CollectionAction
这一类主要是对Collection的操作,具体有:
- CREATE,创建Collection
- DELETE,删除Collection
- CREATE_SHARD,为Collection创建shard
- DELETE_SHARD,删除shard
- ADD_REPLICA,新增replica
- ADD_REPLICA_PROP,为replica添加配置
- DELETE_REPLICA_PROP
- BLANCE_SHARD_UNIQUE
- MODIFY_COLLECTION
- MIGRATE_STATE_FORMAT
OverseerAction
- STATE,集群状态变更
- LEADER,shard leader信息变更
- DELETE_CORE,删除replica
- ADD_ROUTING_RULE,添加文档路由规则
- REMOVE_ROUTING_RULE,删除文档路由规则
- UPDATE_SHARD_STATE,更新shard状态
- QUIT,让Overseer线程退出(目前不清楚具体目的)
- DOWN_NODE,某个节点状态置为down
这上面就是Overseer主要做的事情,下面我们顺便再看一下workQueue(DistributedQueue)到底是个什么东西?Overseer中要处理的消息都是来自workQueue(DistributedQueue),所以workQueue(DistributedQueue)还是比较关键的。
我们不难发现,workQueue实际上就是对/overseer/queue-word
子节点操作的封装,比如peek()就是读取第一个子节点,pool()就是读取第一个节点并删除。
这样好像就顺了,比如我们想创建一个collection,那么只要客户端向集群中的任意节点发起create collection操作,然后由该节点在/overseer/queue-word
创建子节点,指明该节点的内容为创建
- 客户端选择集群中任一个节点 node_x,提交cretae collection的动作
- node_x在
/overseer/queue-word
下创建子节点,内容为cretae collection - Overseer不断监测是不是有新的operation,即
/overseer/queue-word
下是不是有新的节点进来,有则处理。
注意:Overseer在循环的过程中,也得不断判断自己是不是主。
转载请注明出处:殷亚云的博客