最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+Redis從零打造分布式鎖實戰(zhàn)示例

 更新時間:2024年01月22日 08:51:07   作者:傻子的尷尬 IT智慧谷  
Redis作為一款高性能的內(nèi)存鍵值數(shù)據(jù)庫,憑借其支持原子操作、高并發(fā)和數(shù)據(jù)持久化等特性,非常適合用來實現(xiàn)分布式鎖,本文將詳細探討如何使用Python結(jié)合Redis從簡單到復(fù)雜地實現(xiàn)分布式鎖,并提供相應(yīng)的示例代碼

引言

在分布式系統(tǒng)中,多個節(jié)點可能需要訪問同一共享資源,這就需要一種協(xié)調(diào)機制來保證在同一時刻只有一個節(jié)點進行操作,這就是分布式鎖的作用。

1. 簡單實現(xiàn)(基于SETNX命令)

使用setnx命令(set if not exists)嘗試設(shè)置一個key-value對,如果key不存在,則設(shè)置成功并返回1,表示獲取到了鎖。

import redis
import time
def acquire_lock(redis_client, lock_key):
    identifier = str(time.time()) + str(id(threading.current_thread()))
    acquired = redis_client.setnx(lock_key, identifier)
    return acquired
def release_lock(redis_client, lock_key, identifier):
    pipe = redis_client.pipeline(True)
    while True:
        try:
            pipe.watch(lock_key)
            if pipe.get(lock_key) == identifier:
                pipe.multi()
                pipe.delete(lock_key)
                pipe.execute()
                return True
            pipe.unwatch()
            break
        except redis.exceptions.WatchError:
            pass
    return False
# 使用示例
r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = 'mylock'
if acquire_lock(r, lock_key):
    print("Lock acquired")
    # 執(zhí)行臨界區(qū)代碼...
    release_lock(r, lock_key, identifier)

2. 改進:設(shè)置超時時間(expire命令)

為防止進程崩潰導(dǎo)致鎖無法釋放,可以給鎖設(shè)置一個過期時間。

def acquire_lock_with_timeout(redis_client, lock_key, expire_time):
    identifier = str(time.time()) + str(id(threading.current_thread()))
    while True:
        result = redis_client.set(lock_key, identifier, nx=True, ex=expire_time)
        if result:
            return identifier
        time.sleep(0.1)
# 使用示例不變,但在acquire_lock_with_timeout函數(shù)中增加了expire_time參數(shù)

3. 進一步改進:使用Lua腳本保證原子性

在釋放鎖的時候,需要確保刪除的是自己設(shè)置的鎖,且這個操作是原子的??梢允褂肔ua腳本來實現(xiàn)。

RELEASE_LOCK_SCRIPT = """
if redis.call("get", KEYS[1]) == ARGV[1] then
    return redis.call("del", KEYS[1])
else
    return 0
end
"""
def release_lock LUA(redis_client, lock_key, identifier):
    release_script = redis_client.register_script(RELEASE_LOCK_SCRIPT)
    released = release_script(keys=[lock_key], args=[identifier])
    return bool(released)
# 使用示例不變

4. 更完善的實現(xiàn),Redlock算法

Redlock算法的實現(xiàn)相對復(fù)雜,以下是一個簡化的Python示例,展示了如何在多個Redis實例上嘗試獲取和釋放鎖。請注意,在實際應(yīng)用中,需要確保Redis實例之間的時間同步,并且考慮網(wǎng)絡(luò)延遲等因素。

import redis
import time
class RedLock:
    def __init__(self, masters, ttl):
        self.masters = [redis.Redis(host=host, port=port, db=db) for host, port, db in masters]
        self.quorum = len(self.masters) // 2 + 1
        self.ttl = ttl
    def lock(self, resource_id):
        expiration = time.time() + self.ttl
        while time.time() < expiration:
            acquired_count = 0
            locked_instances = []
            # 嘗試在每個Redis實例上獲取鎖
            for master in self.masters:
                if master.set(resource_id, 'locked', nx=True, px=self.ttl):
                    acquired_count += 1
                    locked_instances.append(master)
            # 如果獲得超過半數(shù)以上的鎖,則認為成功獲取分布式鎖
            if acquired_count > self.quorum:
                return locked_instances
            # 清除已獲取但未達到法定數(shù)量的鎖
            for master in locked_instances:
                master.delete(resource_id)
            # 等待一段時間后重試
            time.sleep(0.1)
        raise Exception("Could not acquire lock")
    def unlock(self, resource_id, masters_with_lock):
        for master in masters_with_lock:
            # 使用Lua腳本保證原子性地刪除鎖(與前面簡單實現(xiàn)中的釋放鎖方法類似)
            RELEASE_LOCK_SCRIPT = """
            if redis.call("get", KEYS[1]) == "locked" then
                return redis.call("del", KEYS[1])
            else
                return 0
            end
            """
            release_script = master.register_script(RELEASE_LOCK_SCRIPT)
            release_script(keys=[resource_id])
# 示例用法:
masters = [('localhost', 6379, 0), ('localhost', 6380, 0)]  # 假設(shè)有兩個Redis實例
redlock = RedLock(masters, 10000)  # 設(shè)置鎖的有效期為10秒
resource_id = 'my_resource'
try:
    masters_with_lock = redlock.lock(resource_id)
    print(f"Acquired Redlock on resource {resource_id}")
    # 執(zhí)行臨界區(qū)代碼...
finally:
    redlock.unlock(resource_id, masters_with_lock)

此示例僅為了說明Redlock算法的核心思想,并未涵蓋所有邊界條件和異常處理,如Redis實例宕機、網(wǎng)絡(luò)延遲導(dǎo)致時間不一致等情況,請在生產(chǎn)環(huán)境中使用時結(jié)合實際情況進行優(yōu)化和完善。

總結(jié)

通過以上介紹和示例代碼,我們了解了如何基于Python與Redis實現(xiàn)不同層次復(fù)雜度的分布式鎖。從簡單的SETNX命令獲取鎖,到設(shè)置鎖的超時時間以防止進程崩潰導(dǎo)致死鎖,再到利用Lua腳本保證釋放鎖操作的原子性,以及針對大規(guī)模分布式環(huán)境考慮采用Redlock算法提高系統(tǒng)的容錯性和安全性。這些方法可以根據(jù)實際業(yè)務(wù)場景選擇合適的方式來實現(xiàn)分布式鎖,從而有效解決多節(jié)點環(huán)境下對共享資源的競爭問題。隨著技術(shù)的發(fā)展和需求的變化,分布式鎖的實現(xiàn)方式也將持續(xù)演進和完善,為構(gòu)建更穩(wěn)定、高效的分布式系統(tǒng)提供有力支撐。

以上就是Python+Redis從零打造分布式鎖實戰(zhàn)示例的詳細內(nèi)容,更多關(guān)于Python Redis分布式鎖的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 9個提高?Python?編程的小技巧

    9個提高?Python?編程的小技巧

    這篇文章主要介紹了9個提高?Python?編程的小技巧,下文分享python編程技巧,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-05-05
  • python實現(xiàn)簡單銀行管理系統(tǒng)

    python實現(xiàn)簡單銀行管理系統(tǒng)

    這篇文章主要為大家詳細介紹了python實現(xiàn)簡單銀行管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 教你用Django將前端的數(shù)據(jù)存入Mysql數(shù)據(jù)庫

    教你用Django將前端的數(shù)據(jù)存入Mysql數(shù)據(jù)庫

    這篇文章主要給大家介紹了關(guān)于如何用Django將前端的數(shù)據(jù)存入Mysql數(shù)據(jù)庫的相關(guān)資料,文中通過圖文以及示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Django具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2021-11-11
  • python?plotly設(shè)置go.Scatter為實線實例

    python?plotly設(shè)置go.Scatter為實線實例

    這篇文章主要為大家介紹了python?plotly設(shè)置go.Scatter為實線線條的樣式實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Python深度學(xué)習(xí)pytorch神經(jīng)網(wǎng)絡(luò)Dropout應(yīng)用詳解解

    Python深度學(xué)習(xí)pytorch神經(jīng)網(wǎng)絡(luò)Dropout應(yīng)用詳解解

    這篇文章主要為大家介紹了Python深度學(xué)習(xí)中關(guān)于pytorch神經(jīng)網(wǎng)絡(luò)Dropout的應(yīng)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • Python打包編譯工具Pyinstaller與Nuitka特性超詳細對比

    Python打包編譯工具Pyinstaller與Nuitka特性超詳細對比

    應(yīng)用程序開發(fā)完畢,一般都需要對程序進行打包后發(fā)布,除開源項目外,很少有發(fā)布源碼的,這篇文章主要介紹了Python打包編譯工具Pyinstaller與Nuitka特性對比的相關(guān)資料,需要的朋友可以參考下
    2026-03-03
  • Django之第三方平臺QQ授權(quán)登錄的實現(xiàn)

    Django之第三方平臺QQ授權(quán)登錄的實現(xiàn)

    本文主要介紹了Django之第三方平臺QQ授權(quán)登錄的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Python安裝selenium包詳細過程

    Python安裝selenium包詳細過程

    在本篇文章里小編給大家整理了關(guān)于Python安裝selenium包詳細過程,需要的朋友們可以學(xué)習(xí)下。
    2019-07-07
  • Python中asyncio的多種用法舉例(異步同步)

    Python中asyncio的多種用法舉例(異步同步)

    這篇文章主要給大家介紹了關(guān)于Python中asyncio的多種用法,包括順序執(zhí)行非異步任務(wù)、順序執(zhí)行異步任務(wù)、并行執(zhí)行異步任務(wù)以及并行執(zhí)行非異步任務(wù),通過使用asyncio模塊,可以有效地提高程序的執(zhí)行效率,尤其是在處理I/O密集型任務(wù)時,需要的朋友可以參考下
    2024-11-11
  • Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解

    Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解

    這篇文章主要介紹了Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解,Pandas是一個用于數(shù)據(jù)分析和處理的Python庫,它提供了高效的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具,使得數(shù)據(jù)的清洗、轉(zhuǎn)換、分析和可視化變得更加容易和靈活,需要的朋友可以參考下
    2023-08-08

最新評論

库尔勒市| 镇康县| 崇州市| 朝阳县| 绥滨县| 蛟河市| 黄龙县| 多伦县| 林芝县| 新建县| 岗巴县| 社会| 应城市| 昭觉县| 阿拉善左旗| 东乡县| 若尔盖县| 吕梁市| 伊春市| 敖汉旗| 保靖县| 洛川县| 正蓝旗| 游戏| 三都| 望都县| 什邡市| 兴山县| 英德市| 翁牛特旗| 股票| 云南省| 稷山县| 襄城县| 商河县| 天镇县| 始兴县| 社会| 德惠市| 新龙县| 哈巴河县|