解决python-redis-lock分布式锁的问题
作者:Loganer 发布时间:2023-05-23 18:57:49
python-redis-lock
官方文档
不错的博文可参考
问题背景
在使用celery执行我们的异步任务时,为了提高效率,celery可以开启多个进程来启动对应的worker。
但是会出现这么一种情况:在获取到数据源之后要对数据库进行扫描,根据UUID来断定是插入还是更新,两个worker 同时 (相差0.001S)拿到了UUID但是在其中一个没插入时,另一个也扫描完了数据库,这时这两个worker都会认为自己拿到的UUID是在数据库中没有存在过的,所以都会调用INSERT方法来进行插入操作。
几种解决方案
为了解决这个问题,一般有如下解决方案.
分布式锁家族:
数据库:
排它锁(悲观锁)
乐观锁
Redis
自己实现Redis SET SETNX 操作,结合Lua脚本确保原子操作
RedLock Redis里分布式锁实现的算法,争议比较大,谨慎使用
python-redis-lock 本文将要介绍的技术。这个库提供的分布式锁很灵活,是否需要超时?是否需要自动刷新?是否要阻塞?都是可选的。没有最好的算法,只有最合适的算法,开发人员应该根据实际需求场景谨慎选择具体用哪一种技术去实现。
设计思路:
Zookeeper
这个应该是功能最强大的,比较专业,稳定性好。我还没使用过,日后玩明白了再写篇文章总结一下。
扩展思路
在celery的场景下也可以使用celery_once进行任务去重操作, celery_once底层也是使用redis进行实现的。
可以参考这篇
Talk is cheap, show me your code!
一个简单的demo
import random
import time
import threading
import redis_lock
import redis
HOST = 'YOUR IP LOCATE'
PORT = '6379'
PASSWORD = 'password'
def get_redis():
pool = redis.ConnectionPool(host=HOST, port=PORT, password=PASSWORD, decode_responses=True, db=2)
r = redis.Redis(connection_pool=pool)
return r
def ask_lock(uuid):
lock = redis_lock.Lock(get_redis(), uuid)
if lock.acquire(blocking=False):
print(" %s Got the lock." % uuid)
time.sleep(5)
lock.release()
print(" %s Release the lock." % uuid)
else:
print(" %s Someone else has the lock." % uuid)
def simulate():
for i in range(10):
id = random.randint(0, 5)
t = threading.Thread(target=ask_lock, args=(str(id)))
t.start()
simulate()
Output:
4 Got the lock.
5 Got the lock.
3 Got the lock.
5 Someone else has the lock.
5 Someone else has the lock.
2 Got the lock.
5 Someone else has the lock.
4 Someone else has the lock.
3 Someone else has the lock.
3 Someone else has the lock.
2 Release the lock.
5 Release the lock.
4 Release the lock.
3 Release the lock.
来源:https://blog.csdn.net/wyh1618/article/details/120973410


猜你喜欢
- pygame.mixer是一个用来处理声音的模块,其含义为“混音器”。游戏中对声音的处理一般包括制造声音和播放声音两部分,这里仅学习了播放声
- 问题是:输入一个数字,按照指定要求逆序输出该数字,很简单,下面是实现:#!usr/bin/env python#encoding:utf-8
- 当感觉mysql性能出现问题时,通常会先看下当前mysql的执行状态,使用 show processlist 来查看,例如:其中state状
- explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句.使用方法:在sel
- 以下内容来自CHATGPT,其中PGADMIN经实验,有效1、在MYSQL中使用:可以使用GROUP_CONCAT函数来实现相同名称的多行字
- 前言今天我们一起来聊聊DataFrame中的索引。上一篇文章当中我们介绍了DataFrame数据结构当中一些常用的索引的使用方法,比如ilo
- 前言无论是单机锁还是分布式锁,原理都是基于共享的数据,判断当前操作的行为。对于单机则是共享RAM内存,对于集群则可以借助Redis,ZK,D
- js中变量的特征js的变量是松散类型的。变量可以用于保存任何类型的数据。所以js也被称为弱类型语言。变量的定义与访问简单说下作用域什么是作用
- 01.简介当我们使用的鱼眼镜头视角大于160°时,OpenCV中用于校准镜头“经典”方法的效果可能就不是和理想了。即使我们仔细遵循OpenC
- eg:如在后台的标签列表中,实现上移、下移、置顶功能主要实现思路是节点操作,比如说:上移,直接把点击项移动到前一个节点,以此类推,当然实际代
- 很多应用多需要处理文件,而处理文件有一个固定的模式:打开文件,读入一些数据,处理这些数据,打印到屏幕上或写入另一个文件。那么,如果我们想修改
- 本文实例讲述了python任务调度实现方法。分享给大家供大家参考。具体如下:方法1:import sched, timeimport oss
- 在做NLP(自然语言处理)相关任务时,经常会遇到需要识别并提取省、城市、行政区的需求。虽然我们自己通过关键词表一个个查找也能实现提取目的,但
- 可视性的问题几乎在每次不同产品的用户测试中都会出现:用户总是对页面的某些元素、功能视若无睹,或根本无视。基于此,对这个问题进行了一番小小的研
- 大家平时见到google的广告太多了,但有没有兴趣知道一下它的运行过程呢?下面我们一起来看看这个广告代码的执行过程,以及其中的一些精彩内容。
- PySnooper 是一个非常方便的调试器。如果您正在试图弄清楚为什么您的Python代码没有按照您的预期去做,您会希望使用具有断点和监视功
- 本文介绍FCKeditor在Java环境下的使用方法。一、简介 功能:所见即所得,支持图片和Flash,工具栏可自由配置,使用简单兼容性:I
- 注意:localtime获取的年份是相对于1900的偏移,需要加上1900,而localtime获取的month范围是0-11,需要加1。#
- 多数情况下,mysql在刚刚安装时是不支持中文的,这是由于编码的问题我们可以通过修改配置文件,永久实现mysql对中文的识别首先我们要先将文
- Oracle LogMiner 是Oracle公司从产品8i以后提供的一个实际非常有用的分析工具,使用该工具可以轻松获得Oracle 重作日