日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
redis并發(fā)鎖incr
Redis的INCR命令將key中存儲(chǔ)的數(shù)字值遞增。如果key不存在,那么key的值會(huì)先被初始化為0,然后在執(zhí)行INCR操作。如果值包含錯(cuò)誤的類(lèi)型,或字符串類(lèi)型的值不能表示為數(shù)字,那么返回一個(gè)錯(cuò)誤。本操作的值限制在64位(bit)有符號(hào)數(shù)字表示之內(nèi)。 ,,如果您需要使用Redis實(shí)現(xiàn)分布式鎖,可以使用Redis的SETNX命令。SETNX命令可以將指定的鍵名和值存儲(chǔ)到Redis中,但是僅當(dāng)該鍵名不存在時(shí)才會(huì)執(zhí)行此操作。如果該鍵名已經(jīng)存在,則該命令不會(huì)執(zhí)行任何操作。

Redis并發(fā)鎖時(shí)間怎么設(shè)置

在分布式系統(tǒng)中,為了保證數(shù)據(jù)的一致性和完整性,常常需要使用鎖來(lái)控制對(duì)共享資源的訪問(wèn),Redis作為一款高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),也可以用來(lái)實(shí)現(xiàn)分布式鎖,本文將介紹如何設(shè)置Redis并發(fā)鎖的時(shí)間。

Redis并發(fā)鎖的基本原理

Redis的并發(fā)鎖是通過(guò)使用SET命令和NX(Not eXists)和PX(Precision-Key)選項(xiàng)來(lái)實(shí)現(xiàn)的,當(dāng)一個(gè)客戶端嘗試獲取鎖時(shí),它會(huì)發(fā)送一個(gè)SET命令,同時(shí)指定一個(gè)唯一的key和一個(gè)過(guò)期時(shí)間,如果這個(gè)key不存在,那么客戶端將成功獲取鎖;如果這個(gè)key已經(jīng)存在,那么客戶端將無(wú)法獲取鎖,通過(guò)設(shè)置過(guò)期時(shí)間,可以確保鎖在一定時(shí)間內(nèi)有效。

設(shè)置Redis并發(fā)鎖的方法

1、使用SET命令和NX選項(xiàng)

import redis
def acquire_lock(conn, lock_name, acquire_timeout=10, lock_timeout=10):
    identifier = str(uuid.uuid4())
    lock_timeout = int(math.ceil(lock_timeout))
    
    end = time.time() + acquire_timeout
    while time.time() < end:
        if conn.set(lock_name, identifier, ex=lock_timeout, nx=True):
            return identifier
        elif not conn.ttl(lock_name):
            conn.expire(lock_name, lock_timeout)
    
    return False

2、使用Lua腳本

import redis
import time
import uuid
def acquire_lock(conn, lock_name, acquire_timeout=10, lock_timeout=10):
    identifier = str(uuid.uuid4())
    lock_timeout = int(math.ceil(lock_timeout))
    lua = """
    local key = KEYS[1]
    local timeout = tonumber(ARGV[1])
    local identifier = tostring(ARGV[2])
    
    local current_time = tonumber(redis.call('TIME'))
    while current_time < math.min(timeout, tonumber(ARGV[3])) do
        if redis.call('GET', key) == false then
            redis.call('SET', key, identifier, 'PX', timeout)
            return identifier
        elseif tonumber(redis.call('TTL', key)) > 0 then
            redis.call('EXPIRE', key, timeout)
            return identifier
        end
        
        table.insert(KEYS, key) -將當(dāng)前key添加到等待隊(duì)列中
        table.remove(KEYS, KEYS[1]) -從等待隊(duì)列中移除當(dāng)前key
        redis.call('WAIT', math.min(timeout * 1000, tonumber(ARGV[3]))) -等待一段時(shí)間后再次嘗試獲取鎖
        redis.call('REMOVE', KEYS[KEYS + 1]) -從等待隊(duì)列中移除剛剛插入的key
        redis.call('MULTI') -開(kāi)啟事務(wù)模式
        redis.call('SET', key, identifier) -將當(dāng)前key的值設(shè)置為identifier
        redis.call('PEXPIRE', key, timeout) -為當(dāng)前key設(shè)置過(guò)期時(shí)間
        redis.call('EXEC') -執(zhí)行事務(wù)中的命令
        return identifier -如果成功獲取鎖,返回identifier作為解鎖標(biāo)識(shí)符
        end
        redis.call('UNWATCH') -如果當(dāng)前key已經(jīng)被其他客戶端鎖定,取消監(jiān)視該key的操作
        redis.call('SLEEP', (timeout * 1000) % (10 * 1000)) -讓當(dāng)前客戶端等待一段時(shí)間后再次嘗試獲取鎖
        redis.call('REDISCALL', 'EVAL', KEYS[1], "if (redis.call('EXISTS', KEYS[1]) == 'nil') then return nil else return me end") -如果當(dāng)前key已經(jīng)被刪除,返回nil表示無(wú)法獲取鎖
        redis.call('MULTI') -開(kāi)啟事務(wù)模式
        redis.call('UNSET', key) -將當(dāng)前key的值設(shè)置為nil
        redis.call('PEXPIRE', key, '-inf') -為當(dāng)前key設(shè)置一個(gè)非常小的過(guò)期時(shí)間,使其立即過(guò)期
        redis.call('EXEC') -執(zhí)行事務(wù)中的命令
        return nil -如果無(wú)法獲取鎖,返回nil表示解鎖標(biāo)識(shí)符無(wú)效
    end"""
    lua_script = conn.register_script(lua)
    lua_result = lua_script(lock_name, lock_timeout * 1000, str(uuid.uuid4()), str(lock_timeout * 1000), str(acquire_timeout * 1000))
    
    if isinstance(lua_result, list) and len(lua_result) == 2:
        return str(lua_result[0]) == str(identifier) or str(lua_result[1]) == 'nil' and acquire_lock(conn, lock_name, acquire_timeout, lock_timeout) is not None
    
    return None if not isinstance(lua_result, list) or len(lua_result) != 2 or not (str(lua_result[0]) == str(identifier) or str(lua_result[1]) == 'nil') else acquire_lock(conn, lock_name, acquire_timeout, lock_timeout) is not None

本文題目:redis并發(fā)鎖incr
網(wǎng)站網(wǎng)址:http://www.dlmjj.cn/article/ccseeoi.html