solrcloud有两个公开的队列一个是Overseer Job Queue,另一个是Overseer Collection Queue,这两个队列分别通过两个Overseer进行读取并执行相关的操作。另外还有一个临时存储的队列,是针对OverSeer Job Queue容错的,这里不描述。
- OverSeer Job Queue
主要存储一些对ClusterState节点的JSON进行修改操作的数据,例如添加collection,删除collection,添加删除shard、replica等,要注意的是,这里的操作是仅仅针对与ClusterState在zookeeper里面的数据修改,并不会直接对solr里面的core或者数据进行修改,可以认为是对整个集群状态的一个维护。这个队列里面 - Overseer Collection Queue
这个队列里面存贮的消息才是对collection的一些真实的操作消息,由OverseerCollectionProcessor类进行读取并进行相应的操作,这个队列里面的处理事件,对应着CollectionsHanlder里面的各个请求事件,由于大多数操作是需要同步操作的,所以这个队列里面的请求是都有响应的
关于队里的一些常用操作实现:
- offer(byte[] data)
在zk的某个节点下面创建一个PERSISTENT_SEQUENTIAL的节点,并且设置数据 - offer(byte[] data, long timeout)
在上面offer操作的同时,添加一个带有特殊响应字符前缀的节点,然后设定一个timeout来Watch这个节点,如果有变化,就拿这个节点的数据作为响应数据,并且删除响应节点(这个有个疑惑,下面再说) - take
这个方法比较简单,就是直接拿队列节点下面的子节点,做下顺序排序,然后取第一个节点,并且删除这个节点,如果删除成功就认为拿到了这个节点的数据,否则就认为其他人拿走了,往后面去下面的节点继续操作,直到没有更多的节点了。这个方法会一直堵塞一个默认的超时时间,直到拿到队列里面的一条数据 - element
这个方法是直接拿队列里面的第一个节点的数据,但是不删除这个节点,并且没有数据的话就立即返回,拿数据的方法和take类似 - peek(long wait)
这个方法和element类似,只是可以等待一段时间看是否有数据可以拿 - remove()
remove和take其实差不多,但是有点细微区别,take在没有数据的时候是等待,而remove没有数据则直接抛出NoSuchElementException了 - remove(QueueEvent event)
最后这个方法是提供删除某个节点,并且设置这个节点的响应数据,方法比较简单,直接根据event的path删除节点,并且拼出response path设置响应数据,但是这里在offer(byte[] data, long timeout)拿响应的时候有个疑问,就是offer是先创建队列节点,再创建响应response path节点,而这里remove在没有response path的实际,响应就直接忽略了,设想某种场景下,A client比较卡,设置了数据节点,但是还没来得及设置response节点的时候,数据已经被较快的B client读取完了并且返回数据也直接抛弃了,那么take就只有一直wait到timeout也拿不到响应的数据,因为数据已经丢失了
时间: 2024-10-14 08:17:53