人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

python3使用python-redis-lock解決并發(fā)計(jì)算問題

發(fā)布日期:2021-12-17 16:17 | 文章來源:腳本之家

需求

我在最近的一個(gè)任務(wù)中,存在一個(gè)redis高并發(fā)計(jì)算多個(gè)客戶端接收預(yù)警信息的時(shí)長問題。

模型是首先模擬多個(gè)客戶端連接預(yù)警服務(wù)器集群,然后向預(yù)警服務(wù)集群發(fā)送告警信息。隨后預(yù)警服務(wù)集群將會(huì)向客戶端推送告警信息。

此時(shí),我記錄了發(fā)送告警至預(yù)警集群的時(shí)間,并且在客戶端還會(huì)記錄接收到告警的時(shí)間。

我將這個(gè)時(shí)間都會(huì)記錄到redis中,那么此時(shí)就會(huì)有一個(gè)問題,當(dāng)多個(gè)客戶端搶占式往redis 讀取數(shù)據(jù),計(jì)算,設(shè)置數(shù)據(jù),這個(gè)過程是會(huì)被相互覆蓋的。

可以從上面的截圖來看,多個(gè)不同的客戶端讀取redis的數(shù)據(jù),大部分讀取到了同一個(gè)數(shù)據(jù),導(dǎo)致計(jì)算錯(cuò)誤。

導(dǎo)致問題的示意圖如下:

為了解決這個(gè)問題,則可以編寫一個(gè)redis的鎖,用來控制數(shù)據(jù)的并發(fā)讀取以及寫入。
在python redis庫默認(rèn)只有樂觀鎖的一種寫法,在這里我再推薦使用一個(gè)庫python-redis-lock,使用這個(gè)庫對redis多個(gè)客戶端并發(fā)的情況加鎖,真的很方便。
下面來看看怎么使用。

python-redis-lock

https://pypi.org/project/python-redis-lock/

在使用這個(gè)庫之前,需要安裝如下:

pip install python-redis-lock

使用鎖的示例:

lock = redis_lock.Lock(conn, "name-of-the-lock")
if lock.acquire(blocking=False):
 print("Got the lock.")
 lock.release()
else:
 print("Someone else has the lock.")

上面是單獨(dú)設(shè)置鎖的方式,還可以單獨(dú)設(shè)置所有redis的操作加入鎖。

# On application start/restart
import redis_lock
redis_lock.reset_all(redis_client)

修改業(yè)務(wù)代碼,增加lock操作

1. 首先導(dǎo)入redis_lock

import redis_lock

2.將redis連接的客戶端傳入lock中,并設(shè)置lock的名稱

# 設(shè)置redis連接
self.conn = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True, db=3)
 
# 設(shè)置redis鎖
self.lock = redis_lock.Lock(self.conn, "redis-lock")

3.將業(yè)務(wù)讀取、設(shè)置redis的部分加入鎖

while True:
 # 設(shè)置redis鎖,操作redis
 if self.lock.acquire(blocking=False):
  print("Got the lock.")
  # 獲取lock,執(zhí)行業(yè)務(wù)處理
  # 獲取當(dāng)前redis鐘記錄的客戶端接收到告警的總時(shí)長
  recv_time_sum_count_clients = self.conn.get(recv_time_sum_count_clients_key)
  if recv_time_sum_count_clients is None:
recv_time_sum_count_clients = "0:0"
 
  # 獲取當(dāng)前的統(tǒng)計(jì)數(shù)據(jù)
  recv_time_sum, count_clients = recv_time_sum_count_clients.split(":")
 
  # 計(jì)算告警接收總時(shí)長
  recv_time_sum = float(recv_time_sum) + recv_time
  # 計(jì)算收到預(yù)警的客戶端數(shù)量
  count_clients = int(count_clients) + 1
 
  # 寫入redis中
  recv_time_sum_count_clients = "%s:%s" % (str(recv_time_sum), str(count_clients))
  self.conn.set(recv_time_sum_count_clients_key, recv_time_sum_count_clients)
 
  print("user_id = %s, 計(jì)算平均時(shí)間成功, "
  "recv_time_sum = %s, count_clients = %s \n" %
  (self.user_id, recv_time_sum, count_clients))
 
  # 釋放lock
  self.lock.release()
 
  # 退出循環(huán)
  break
 else:
  print("Someone else has the lock.")

在客戶端的代碼中設(shè)置了鎖之后,再來執(zhí)行一下,看看有無搶占讀取redis數(shù)據(jù)的情況,如下:

設(shè)置了鎖之后,客戶端由于并發(fā)導(dǎo)致redis數(shù)據(jù)讀取、設(shè)置錯(cuò)誤的情況就可以避免了。

并且這個(gè)庫還可以使用到Django框架中,更多細(xì)節(jié)讀者可以到該庫Github中細(xì)細(xì)查閱,本篇章就不介紹了,哈哈。

到此這篇關(guān)于python3使用python-redis-lock解決并發(fā)計(jì)算問題的文章就介紹到這了,更多相關(guān)python-redis-lock 并發(fā)內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開通

自選配置、實(shí)時(shí)開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部