基于Redis实现分布式锁
2016-06-26 00:09
691 查看
分布式锁的基本功能:
1.同一时刻只能存在一个锁
2.需要解决意外死锁问题,也就是锁能超时自动释放
3.支持主动释放锁
分布式锁解决什么问题:
多进程并发执行任务时,需要保证任务的有序性或者唯一性
准备:
redis版本>=2.6
redis是主从+sentinel模式(为了高可用)
原理:
redis2.6之后,SET命令支持超时和key存在检查,这是一个原子操作
获取锁并设置超时时间:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
删除锁:
DEL key
EX:单位是秒
PX:单位是毫秒
NX:如果key存在,返回nil(失败),不存在返回ok
XX:如果key存在,返回ok,不存在返回nil(失败)
基本操作如图示:
案例:
有一个系统,需要对用户信息进行增删改查操作,系统是多进程的,要求对用户的操作是有序的串行的
上测试代码,可以多开进程观看效果:
缺陷:
a) 一旦redis发生主从切换,可能会丢失一些锁,
b) 如果对锁的要求很高,可以参考redis官方提供的方案:http://redis.io/topics/distlock
c) 范例代码只能当作原理来理解,实际上有很多需要优化的地方,优化可参考:https://pypi.python.org/pypi/python-redis-lock
End;
1.同一时刻只能存在一个锁
2.需要解决意外死锁问题,也就是锁能超时自动释放
3.支持主动释放锁
分布式锁解决什么问题:
多进程并发执行任务时,需要保证任务的有序性或者唯一性
准备:
redis版本>=2.6
redis是主从+sentinel模式(为了高可用)
原理:
redis2.6之后,SET命令支持超时和key存在检查,这是一个原子操作
获取锁并设置超时时间:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
删除锁:
DEL key
EX:单位是秒
PX:单位是毫秒
NX:如果key存在,返回nil(失败),不存在返回ok
XX:如果key存在,返回ok,不存在返回nil(失败)
基本操作如图示:
案例:
有一个系统,需要对用户信息进行增删改查操作,系统是多进程的,要求对用户的操作是有序的串行的
上测试代码,可以多开进程观看效果:
# -*- coding: utf-8 -*- import time import redis # 获取锁 def get_lock(uid): # 连接redis r = redis.StrictRedis(host='localhost', port=6379, db=0, socket_timeout=1, socket_connect_timeout=3) # 当前时间戳,用于删除锁时check sec = str(time.time()) # 处理超时时间 timeout = 300 # 试图锁住uid while True: res = r.set(uid, sec, ex=timeout, nx=True) if res == True: print "get lock succeed, return" return True, sec else: print "get lock failed, lock exist, wait" time.sleep(0.001) return False, None # 释放锁 def del_lock(uid, sec): # 连接redis r = redis.StrictRedis(host='localhost', port=6379, db=0, socket_timeout=1, socket_connect_timeout=3) # 校验 redis_sec = r.get(uid) if sec != redis_sec: print "check permission failed :%s" % uid return False print "check permission succeed :%s" % uid #删除 res = r.delete(uid) if res: print "del key succeed :%s" % uid return False else: print "del key failed :%s" % uid return True if __name__ == '__main__': uid = "001" while True: status, sec = get_lock(uid) if status: del_lock(uid, sec) time.sleep(0.001)
缺陷:
a) 一旦redis发生主从切换,可能会丢失一些锁,
b) 如果对锁的要求很高,可以参考redis官方提供的方案:http://redis.io/topics/distlock
c) 范例代码只能当作原理来理解,实际上有很多需要优化的地方,优化可参考:https://pypi.python.org/pypi/python-redis-lock
End;
相关文章推荐
- redis安装问题小结
- 分布式版本管理git入门指南使用资料汇总及文章推荐
- 使用 Redis 和 Python 构建一个共享单车的应用程序
- Redis偶发连接失败案例实战记录
- Redis中实现查找某个值的范围
- win 7 安装redis服务【笔记】
- redis的hGetAll函数的性能问题(记Redis那坑人的HGETALL)
- Redis和Memcached的区别详解
- 分割超大Redis数据库例子
- Redis总结笔记(一):安装和常用命令
- Redis sort 排序命令详解
- 用Redis实现微博关注关系
- Redis实现信息已读未读状态提示
- redis中修改配置文件中的端口号 密码方法
- 在Ruby on Rails上使用Redis Store的方法
- Redis和Memcache的区别总结
- C#分布式事务的超时处理实例分析
- 在Node.js应用中使用Redis的方法简介
- Erlang分布式节点中的注册进程使用实例
- Redis服务器的启动过程分析