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在循环的过程中,也得不断判断自己是不是主。

转载请注明出处:殷亚云的博客