标签:
solrcloud有两个公开的队列一个是Overseer Job Queue,另一个是Overseer Collection Queue,这两个队列分别通过两个Overseer进行读取并执行相关的操作。另外还有一个临时存储的队列,是针对OverSeer Job Queue容错的,这里不描述。
这个队列里面存贮的消息才是对collection的一些真实的操作消息,由OverseerCollectionProcessor类进行读取并进行相应的操作,这个队列里面的处理事件,对应着CollectionsHanlder里面的各个请求事件,由于大多数操作是需要同步操作的,所以这个队列里面的请求是都有响应的
关于队里的一些常用操作实现:
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也拿不到响应的数据,因为数据已经丢失了
标签:
原文地址:http://my.oschina.net/zengjie/blog/516580