您好,登錄后才能下訂單哦!
前言
上周“被”上線了一個緊急項目,周五下班接到需求,周一開始思考解決方案,周三開發完成,周四走流程上線,也算是面向領導編程了。之前的項目里面由于是自運維,然后大多數又都趕時間,所以在處理定時任務上面基本都是自己在服務器上添加crontab,而不是讓多個實例自己去處理定時任務的并發鎖,并且Laravel 5.5開始自帶并發鎖,我們也快升級了。但是這次項目是Python項目,無奈只能自己實現一下,以下這個方案實現起來非常簡單且易于理解。
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') # 讓鎖心跳加一 ...
我們來看看這段程序都解決了并發鎖中的哪些問題
導致Redis并發原因解釋
正所謂只有知其然才能知其所以然,只有弄明白問題出現的原因所在,才能對癥下藥,尋找解決問題的良方。眾所周知,Redis程序采用單線程模式進行運行,作為單線程程序,Redis客戶端的命令是逐條執行,也叫做One by One執行。既然是逐條命令執行,從表面上來看Redis似乎不存在高并發的問題,這一觀點論也有道理,原子性的Redis命令本身也確實不存在高并發問題,這與多線程下的程序勃然不同。但是我們項目工作搭建Redis環境之后,通常都會是一組命令集合執行程序,一個請求中就包含了N個Redis執行命令,再加上多個客戶端請求,命令就更多了,導致連接超時、數據混亂或錯誤、請求阻塞等多種問題。
即總結為,產生Redis并發誘因是程序中的業務復雜度導致。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。