有些分布式场景会有分布式锁的需求,可以为了原子操作,也可能为了性能的原因,不管是分布式锁市面是有不少解决方法的,比如etcd、consul、zookeeper… 初次之外redis这样的nosql也是可以实现分布式锁的。  python党喜欢用redis、etcd、consul来搞。   java这帮人更喜欢用zookeeper来实现分布式锁,zookeeper做分布式锁有临时节点(Ephemeral Node)的效果,也就是说当客户端出问题时,watch在zookeeper的服务会监听到的,  另外由这个客户端建立的键值也会被干掉…  


该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新http://xiaorui.cc/?p=3028

如果我们用redis来实现分布式锁,是怎么实现? (真想直接贴代码,不废话…)

首先借助于redis的setnx命令来操作,setnx本身针对key赋值的时候会判断redis中是否存在这个key,如果有返回-1,  如果没有的化,他会直接set键值。那他跟直接set键值有啥区别?  setnx是原子操作,而set不能保证原子性。


为了防止锁被长久锁定,或者防止客户端崩掉了没有删掉锁,可以用expire加入过期时间。 但这过期时间也不解决那种客户端异常退出,又没删除锁的情况。  我在使用etcd做服务发现注册时候,用了一个笨办法,把过期时间调的很细,可以开一个线程不停的去设置锁及过期时间.  这样能缓解一般的过期情况.

代码是基于https://github.com/everalbum/redislock/blob/master/redislock.go 修改的,这老外写的代码太高调了。 另外我在这基础上加入了增加过期时间的方法,及自定义prefix key和token,超时时间。

代码我已经整理到 https://github.com/rfyiamcool/go_redis_lock  ,暂不能构建一个可直接用来使用包,没想过要构建一个库包.   下面是实现的代码及test实例…   


这段golang代码运行后的正常结果是:


如果同时起多个进程去测试,会遇到这么一个结果:

END.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!

golang随机time.sleep的Duration问题

碰到一个Golang time.Sleep()的问题,这golang的time.sleep的功能貌似要比python ruby都要精细些,python的等待只是time.sleep()而已,而golang可以time.Sl...

阅读全文

golang使用yaml格式解析构建配置文件

还是那个golang监控agent那些事情,现在功能差不多了,唯独缺少信号处理及daemon服务化。 程序写的差不多了,但是这配置文件咋整? 难道把这些常亮要写在.g...

阅读全文

Golang使用pprof监控性能及GC调优

这两天用golang在写一个监控的agent,发现长时间运行后会有内存泄露的情况,着实让人郁闷半天… 要解决golang泄露的问题,要理解goalng gc那是事情,...

阅读全文