redis锁处理并发 php,使用Redis锁处理并发问题的方法

064e75fb251bd30911efc08de4360300.png

使用Redis锁处理并发问题,保证多进程仅有一个实例在运行,当运行中的实例down了后其它实例中的一个能顶上来,保证有且仅有一个实例在运行。import redis

r = redis.Redis(...)

last_heart = 0# 记录上一次得到的锁心跳

free_lock_try = 6# 锁无心跳的最大次数

while not r.setnx('mylock', 1):

now_heart = r.get('mylock')

print(f"没获取到锁,now_heart={now_heart},last_heart={last_heart},free_lock_try={free_lock_try}")

if now_heart == last_heart:

free_lock_try = free_lock_try - 1

if free_lock_try == 0:# 锁已经1分钟没有心跳了

old_heart = r.getset('mylock', 1)# 将lock重置为1,并返回set之前的心跳值

if old_heart < now_heart:

time.sleep(10)

continue

else:

break# 成功获取到锁,退出循环

else:

free_lock_try = 6# 锁有心跳,重置free_lock_try值

last_heart = now_heart

time.sleep(10)

def producer_exit():

"""程序正常退出时候自动清理锁"""

r.delete('mylock')

import atexit

atexit.register(producer_exit)

# 业务代码

while True:

r.incr('mylock')# 让锁心跳加一

...

我们来看看这段程序都解决了并发锁中的哪些问题:

1、高并发下,多个进程无法同时获取到锁。这里使用的是redis.setnx,如果锁已经存在,其他进程是无法重置锁并获取到锁的。另外当多个进程同时发现有锁已经没有心跳了,使用的是redis.getset将心跳重置为1,都能set成功,但是get出来的值多个进程是不一样的,只有真正获取到锁的进程返回的是之前进程的心跳,而其他进程获取到的都是1。

2、有锁进程正常退出,可以使用atexit注册进程退出函数删除锁,这里也可以不要,不过下次启动得等新的进程等待几次心跳

3、有锁进程意外退出,退出后心跳不再增加,超过free_lock_try次数后,其他进程会重新设置并获取锁

4、所有进程全都意外退出,这个问题不是锁来关心的,可以使用supervisor进行守护进程。

更多redis知识请关注redis入门教程栏目。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值