zookeeper 典型应用场景-队列管理

队列管理

Zookeeper 可以处理两种类型的队列:

  1. 当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达,这种是同步队列。
  2. 队列按照 FIFO 方式进行入队和出队操作,例如实现生产者和消费者模型。

同步队列用 Zookeeper 实现的实现思路如下:

创建一个父目录 /synchronizing,每个成员都监控标志(Set Watch)位目录 /synchronizing/start 是否存在,然后每个成员都加入这个队列,加入队列的方式就是创建 /synchronizing/member_i 的临时目录节点,然后每个成员获取 / synchronizing 目录的所有目录节点,也就是 member_i。判断 i 的值是否已经是成员的个数,如果小于成员个数等待 /synchronizing/start 的出现,如果已经相等就创建 /synchronizing/start。

同步队列流程图
图 5. 同步队列流程图

队列同步代码:

   
   
   
   
  1. void addQueue() throws KeeperException, InterruptedException{
  2. zk.exists(root + "/start",true);
  3. zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
  4. CreateMode.EPHEMERAL_SEQUENTIAL);
  5. synchronized (mutex) {
  6. List<String> list = zk.getChildren(root, false);
  7. if (list.size() < size) {
  8. mutex.wait();
  9. } else {
  10. zk.create(root + "/start", new byte[0], Ids.OPEN_ACL_UNSAFE,
  11. CreateMode.PERSISTENT);
  12. }
  13. }
  14. }
当队列没满是进入 wait(),然后会一直等待 Watch 的通知,Watch 的代码如下:
    
    
    
    
  1. public void process(WatchedEvent event) {
  2. if(event.getPath().equals(root + "/start") &&
  3. event.getType() == Event.EventType.NodeCreated){
  4. System.out.println("得到通知");
  5. super.process(event);
  6. doAction();
  7. }
  8. }

FIFO 队列用 Zookeeper 实现思路如下:

实现的思路也非常简单,就是在特定的目录下创建 SEQUENTIAL 类型的子目录 /queue_i,这样就能保证所有成员加入队列时都是有编号的,出队列时通过 getChildren( ) 方法可以返回当前所有的队列中的元素,然后消费其中最小的一个,这样就能保证 FIFO。

生产者代码:

     
     
     
     
  1. boolean produce(int i) throws KeeperException, InterruptedException{
  2. ByteBuffer b = ByteBuffer.allocate(4);
  3. byte[] value;
  4. b.putInt(i);
  5. value = b.array();
  6. zk.create(root + "/element", value, ZooDefs.Ids.OPEN_ACL_UNSAFE,
  7. CreateMode.PERSISTENT_SEQUENTIAL);
  8. return true;
  9. }
消费者代码:
      
      
      
      
  1. int consume() throws KeeperException, InterruptedException{
  2. int retvalue = -1;
  3. Stat stat = null;
  4. while (true) {
  5. synchronized (mutex) {
  6. List<String> list = zk.getChildren(root, true);
  7. if (list.size() == 0) {
  8. mutex.wait();
  9. } else {
  10. Integer min = new Integer(list.get(0).substring(7));
  11. for(String s : list){
  12. Integer tempValue = new Integer(s.substring(7));
  13. if(tempValue < min) min = tempValue;
  14. }
  15. byte[] b = zk.getData(root + "/element" + min,false, stat);
  16. zk.delete(root + "/element" + min, 0);
  17. ByteBuffer buffer = ByteBuffer.wrap(b);
  18. retvalue = buffer.getInt();
  19. return retvalue;
  20. }
  21. }
  22. }



来自为知笔记(Wiz)


你可能感兴趣的:(zookeeper 典型应用场景-队列管理)