解決python-redis-lock分布式鎖的問題
python-redis-lock
問題背景
在使用celery執(zhí)行我們的異步任務時,為了提高效率,celery可以開啟多個進程來啟動對應的worker。
但是會出現(xiàn)這么一種情況:在獲取到數(shù)據(jù)源之后要對數(shù)據(jù)庫進行掃描,根據(jù)UUID來斷定是插入還是更新,兩個worker 同時 (相差0.001S)拿到了UUID但是在其中一個沒插入時,另一個也掃描完了數(shù)據(jù)庫,這時這兩個worker都會認為自己拿到的UUID是在數(shù)據(jù)庫中沒有存在過的,所以都會調(diào)用INSERT方法來進行插入操作。
幾種解決方案
為了解決這個問題,一般有如下解決方案.
分布式鎖家族:
數(shù)據(jù)庫:
- 排它鎖(悲觀鎖)
- 樂觀鎖
Redis
- 自己實現(xiàn)Redis SET SETNX 操作,結(jié)合Lua腳本確保原子操作
- RedLock Redis里分布式鎖實現(xiàn)的算法,爭議比較大,謹慎使用
- python-redis-lock 本文將要介紹的技術(shù)。這個庫提供的分布式鎖很靈活,是否需要超時?是否需要自動刷新?是否要阻塞?都是可選的。沒有最好的算法,只有最合適的算法,開發(fā)人員應該根據(jù)實際需求場景謹慎選擇具體用哪一種技術(shù)去實現(xiàn)。
設(shè)計思路:
Zookeeper
這個應該是功能最強大的,比較專業(yè),穩(wěn)定性好。我還沒使用過,日后玩明白了再寫篇文章總結(jié)一下。
擴展思路
在celery的場景下也可以使用celery_once進行任務去重操作, celery_once底層也是使用redis進行實現(xiàn)的。
可以參考這篇
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.
到此這篇關(guān)于python-redis-lock分布式鎖的文章就介紹到這了,更多相關(guān)python分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python爬蟲之Appium爬取手機App數(shù)據(jù)及模擬用戶手勢
這篇文章主要介紹了python爬蟲怎樣通過Appium爬取手機App數(shù)據(jù)及模擬用戶手勢,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08python 如何用urllib與服務端交互(發(fā)送和接收數(shù)據(jù))
這篇文章主要介紹了python 如何用urllib與服務端交互(發(fā)送和接收數(shù)據(jù)),幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下2021-03-03PyQt5+python3+pycharm開發(fā)環(huán)境配置教程
這篇文章主要介紹了PyQt5+python3+pycharm開發(fā)環(huán)境配置教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03Python操作Mongodb數(shù)據(jù)庫的方法小結(jié)
這篇文章主要介紹了Python操作Mongodb數(shù)據(jù)庫的方法,結(jié)合實例形式總結(jié)分析了Python針對MongoDB數(shù)據(jù)庫的基本模塊導入、連接、增刪改查及排序等相關(guān)操作技巧,需要的朋友可以參考下2019-09-09使用Python求解最大公約數(shù)的實現(xiàn)方法
這篇文章主要介紹了使用Python求解最大公約數(shù)的實現(xiàn)方法,包括用Python表示歐幾里得算法和Stein算法的求解原理,需要的朋友可以參考下2015-08-08TensorFlow使用Graph的基本操作的實現(xiàn)
這篇文章主要介紹了TensorFlow使用Graph的基本操作的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04PyCharm:method may be static問題及解決
這篇文章主要介紹了PyCharm:method may be static問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07python?泛型函數(shù)--singledispatch的使用解讀
這篇文章主要介紹了python?泛型函數(shù)--singledispatch的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09