亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解一種用django_cache實(shí)現(xiàn)分布式鎖的方式

 更新時(shí)間:2019年09月01日 09:22:02   作者:知魚君  
這篇文章主要介紹了詳解一種用django_cache實(shí)現(xiàn)分布式鎖的方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

問題背景

在項(xiàng)目開發(fā)過程中,我遇到一個(gè)需求:對(duì)于某條記錄,一個(gè)用戶對(duì)它進(jìn)行操作時(shí)會(huì)持續(xù)比較久,希望在一個(gè)用戶的操作期間,不允許有另一個(gè)用戶操作它,否容易會(huì)出現(xiàn)混亂。

在與同事們討論后,想通過加鎖的方式,起初想用redis鎖,但這樣會(huì)為項(xiàng)目增加別的依賴,因此轉(zhuǎn)而使用django-cache的緩存數(shù)據(jù)庫,來實(shí)現(xiàn)該功能。

資料查找

基于緩存實(shí)現(xiàn)分布式鎖,在網(wǎng)絡(luò)上查找了實(shí)現(xiàn)方式,大概可以總結(jié)為以下3種:

第一種鎖命令I(lǐng)NCR

這種加鎖的思路是, key 不存在,那么 key 的值會(huì)先被初始化為 0 ,然后再執(zhí)行 INCR 操作進(jìn)行加一。 然后其它用戶在執(zhí)行 INCR 操作進(jìn)行加一時(shí),如果返回的數(shù)大于 1 ,說明這個(gè)鎖正在被使用當(dāng)中。

第二種鎖命令SETNX

這種加鎖的思路是,如果 key 不存在,將 key 設(shè)置為 value 如果 key 已存在,則 SETNX 不做任何動(dòng)作

第三種鎖命令SET

上面兩種方法都有一個(gè)問題,會(huì)發(fā)現(xiàn),都需要設(shè)置 key 過期。那么為什么要設(shè)置key過期呢?如果請(qǐng)求執(zhí)行因?yàn)槟承┰蛞馔馔顺隽?,?dǎo)致創(chuàng)建了鎖但是沒有刪除鎖,那么這個(gè)鎖將一直存在,以至于以后緩存再也得不到更新。于是乎我們需要給鎖加一個(gè)過期時(shí)間以防不測(cè)。

在實(shí)際編寫中,我綜合了第二種和第三種方式,即用鍵名來設(shè)置鎖,同時(shí)設(shè)置了過期時(shí)間,以防長(zhǎng)時(shí)間占用。

另外,關(guān)于如何使用django-cache去使用數(shù)據(jù)庫緩存,相關(guān)的API整理如下:

from django.core.cache import caches
# 設(shè)置鎖和超時(shí)時(shí)間
cache.set('my_key', 'Initial value', 60)
# 獲取鎖
cache.get('my_key')
# 更新鎖
cache.add('add_key', 'New value')

代碼編寫

在經(jīng)過多次的迭代,并且對(duì)比了網(wǎng)上的各路寫法后,我結(jié)合django-cache的特性,最終總結(jié)了一套較為簡(jiǎn)潔的寫法。

首先是一個(gè)CacheLock的類,初始化方法里可以傳執(zhí)行超時(shí)時(shí)間,和拿鎖等待的時(shí)間。CacheLock類的主要方法有兩個(gè),一個(gè)是拿鎖的方法,一個(gè)是釋放鎖的方法。

拿鎖的方法中,鍵名根據(jù)操作的具體對(duì)象來定,鍵值為uuid值,超時(shí)時(shí)間默認(rèn)為60s。一旦發(fā)現(xiàn)能拿到鎖,則返回uuid值。

釋放鎖的方法中,首先比較鍵值和uuid值是否一致,一致則釋放,避免因超時(shí)情況導(dǎo)致把其他的正在操作的鎖給釋放掉。

class CacheLock(object):
 def __init__(self, expires=60, wait_timeout=0):
 self.cache = cache
 self.expires = expires # 函數(shù)執(zhí)行超時(shí)時(shí)間
 self.wait_timeout = wait_timeout # 拿鎖等待超時(shí)時(shí)間

 def get_lock(self, lock_key):
 # 獲取cache鎖
 wait_timeout = self.wait_timeout
 identifier = uuid.uuid4()
 while wait_timeout >= 0:
  if self.cache.add(lock_key, identifier, self.expires):
  return identifier
  wait_timeout -= 1
  time.sleep(1)
 raise LockTimeout({'msg': '當(dāng)前有其他用戶正在編輯該采集配置,請(qǐng)稍后重試'})

 def release_lock(self, lock_key, identifier):
 # 釋放cache鎖
 lock_value = self.cache.get(lock_key)
 if lock_value == identifier:
  self.cache.delete(lock_key)

另外,將緩存鎖寫成一個(gè)裝飾器,對(duì)需要加鎖的地方,添加上該裝飾器,則可以很輕松地實(shí)現(xiàn)鎖功能。

def lock(cache_lock):
 def my_decorator(func):
 def wrapper(*args, **kwargs):
  lock_key = 'bk_monitor:lock:xxx' # 具體的lock_key要根據(jù)調(diào)用時(shí)傳的參數(shù)而定
  identifier = cache_lock.get_lock(lock_key)
  try:
  return func(*args, **kwargs)
  finally:
  cache_lock.release_lock(lock_key, identifier)
 return wrapper
 return my_decorator

再舉一個(gè)實(shí)際調(diào)用中的例子:

@lock(CacheLock())
def f():
 pass

另外,我在設(shè)置緩存的key名的時(shí)候,會(huì)根據(jù)函數(shù)的具體操作對(duì)象,從而給裝飾器傳遞相應(yīng)的參數(shù),這里就不再舉例了。

優(yōu)化改進(jìn)

當(dāng)然,實(shí)現(xiàn)以上功能需求一定還有別的更好的方式,關(guān)于鎖的實(shí)現(xiàn),網(wǎng)絡(luò)上有很多別的方式,比如基于zookeeper實(shí)現(xiàn)分布式鎖、基于數(shù)據(jù)庫實(shí)現(xiàn)分布式鎖等等,它們?cè)诳煽啃曰蛐阅芊矫娑几饔虚L(zhǎng)短,要根據(jù)具體場(chǎng)景進(jìn)行取舍,所以還有非常多值得研究的地方。

我這里也只是拋磚引玉,歡迎拍磚~

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 基于Python實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng)

    基于Python實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了基于Python實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • python interpret庫訓(xùn)練模型助力機(jī)器學(xué)習(xí)

    python interpret庫訓(xùn)練模型助力機(jī)器學(xué)習(xí)

    這篇文章主要為大家介紹了python interpret庫訓(xùn)練模型功能特性,為你的機(jī)器學(xué)習(xí)提供便捷的路徑,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Python中的異常處理簡(jiǎn)明介紹

    Python中的異常處理簡(jiǎn)明介紹

    這篇文章主要介紹了Python中的異常處理簡(jiǎn)明介紹,本文講解了try-except檢測(cè)異常、上下文管理器(with…as…語句)、raise引發(fā)異常、斷言等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • python將txt文檔每行內(nèi)容循環(huán)插入數(shù)據(jù)庫的方法

    python將txt文檔每行內(nèi)容循環(huán)插入數(shù)據(jù)庫的方法

    今天小編就為大家分享一篇python將txt文檔每行內(nèi)容循環(huán)插入數(shù)據(jù)庫的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python?print無法打印\r的問題及解決

    python?print無法打印\r的問題及解決

    這篇文章主要介紹了python?print無法打印\r的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • python3.4爬蟲demo

    python3.4爬蟲demo

    今天小編就為大家分享一篇關(guān)于python3.4爬蟲demo,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Python unittest模塊用法實(shí)例分析

    Python unittest模塊用法實(shí)例分析

    這篇文章主要介紹了Python unittest模塊用法,結(jié)合實(shí)例形式分析了unittest模塊功能及相關(guān)函數(shù)使用技巧,需要的朋友可以參考下
    2018-05-05
  • django model object序列化實(shí)例

    django model object序列化實(shí)例

    這篇文章主要介紹了django model object序列化實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • python字典序問題實(shí)例

    python字典序問題實(shí)例

    這篇文章主要介紹了python字典序問題,是字符串操作一個(gè)比較典型的應(yīng)用,需要的朋友可以參考下
    2014-09-09
  • Python數(shù)據(jù)擬合實(shí)現(xiàn)最小二乘法示例解析

    Python數(shù)據(jù)擬合實(shí)現(xiàn)最小二乘法示例解析

    這篇文章主要為大家介紹了Python數(shù)據(jù)擬合實(shí)現(xiàn)最小二乘法的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10

最新評(píng)論