zookeeper实现的一个锁

要求: 分布在不同机器上的进程,同时扫描某个ftp目录,得到文件目录,下载文件,但是要保证每个文件都只被一个进程获取

 
思路:
1.  文件以RW方式打开,比较暴力 ,另FTP支持RW方式打开吗。。。没了解过
2.  实现一个分布式锁,
  2.1  redis:   
         redis单机的事务能否实现?   应该可以,保证一个list,然后不断poll即可。
         redis集群的一致性能否实现?  从表面上看,最终一致性不能保证。。。。。 ------------- 待测试验证
 
 2.2 zookeeper
 zookeeper状态信息:  http://coolxing.iteye.com/blog/1871328 
 
  
实现时候的zookeeper内文件结构:
 [zk: localhost:2181(CONNECTED) 79] ls /na/lock/ftp/2014/12/01/test6/0.log
 [x-309002431815222022-0000000001, x-164887243784979208-0000000000, x-381060026091242234-0000000002]
 /na/lock/ftp/2014/12/01/test6/0.log 是 目标文件
x-309002431815222022-0000000001, x-164887243784979208-0000000000, x-381060026091242234-0000000002 是3个客户端创建的子文件
子文件结构  x- [sessionid] - [zk内部sequence]   309002431815222022 是sessionid  0000000001 是 seq
3个客户端提交的create请求将在zk内部通过类似cas(或者就是cas)来竞争达到排序的目的,然后大家看谁的seq最靠前谁就获得锁。
 
   apache提供的lock需要改进的地方:
       1. path自适应,parent不存在的时候能够自动创建parent
       2. 两个进程中的线程同时create一个文件的时候会有keeperexception,需要catch下,判定有exception的没有获取到锁
       3. znodename做sortmap的时候,拿prefix在内做了compare,容易出问题,需要改成直接拿sequence比较。
           int answer = this.prefix.compareTo(that.prefix);    // --  line79
=》
         // int answer = this.prefix.compareTo(that.prefix); 注释掉
       4. create子节点的时候,line186,用了临时的SEQUENTIAL文件类别,原意是控制单个文件的并发写入,这个文件是可以重入的,在锁占用进程关闭zkclient之后,另外的进程是可以进入的。但是在本案例中,文件下载下来就不能再处理了,所以要改成PERSISTENT_SEQUENTIAL
   code如下 :
           id = zookeeper.create(dir + "/" + prefix, data, getAcl(), CreateMode.EPHEMERAL_SEQUENTIAL);
=>
           id = zookeeper.create(dir + "/" + prefix, data, getAcl(), CreateMode.PERSISTENT_SEQUENTIAL);
posted @ 2014-12-03 16:49  njuzhoubing  阅读(335)  评论(0编辑  收藏  举报