1.問題:
??最近客服有報無法上報運動記錄,通過日志查看是分布式鎖等待超時所致,
??redis出現一個分布式鎖的TTL為-1,正常情況都會設定超時時間的,
??
2.分析:
通過k8s發現sport服務在50幾天內重啟了40幾次,機器上記憶體比較緊缺,暫時只能重啟,占用記憶體高的問題也先不解決,
看下之前加鎖的代碼:
acquire_lock
def acquire_lock(redis_client, lock_key, lock_value, expire=10, timeout=5):
"""
獲取鎖
:param redis_client: redis;連接
:param lock_key: lock key
:param lock_value: lock value
:param expire: lock key過期時間
:param timeout: 等待超時
:return:
"""
assert isinstance(redis_client, RedisClient), [type(RedisClient), RedisClient]
wait_time = 0
sleep_time = 0.05
with redis_client.ctx_conn as conn:
while True:
stime = time.time()
if conn.execute('SETNX', lock_key, lock_value):
conn.execute('EXPIRE', lock_key, expire)
return True
elif not conn.execute('TTL', lock_key):
conn.execute('EXPIRE', lock_key, expire)
logger.info("acquire_lock :%s" % lock_key)
gevent.sleep(sleep_time)
etime = time.time()
wait_time += etime - stime
if wait_time >= timeout:
break
assert 0, [conn, lock_key, lock_value, expire, timeout]
從現狀來分析,應該是SETNX之后沒有執行EXPIRE,正常執行肯定沒有問題;
我估計是因為行程剛好執行到SETNX的時候被k8s殺了,導致EXPIRE沒有去執行
3.解決方案:
- set需要同時兼容NX EX的原子功能
??研究了一下redis的set命令,果然有這個功能
??SET', lock_key, lock_value, NX, EX, expire
- 兼容沒有設定超時的時候設定一下超時
??判斷TTL 是-1的時候:
??ttl當 key 不存在時,回傳 -2 , 當 key 存在但沒有設定剩余生存時間時,回傳 -1 , 否則,以秒為單位,回傳 key 的剩余生存時間
??
原子操作set
def acquire_lock(redis_client, lock_key, lock_value, expire=10, timeout=5):
"""
獲取鎖
:param redis_client: redis;連接
:param lock_key: lock key
:param lock_value: lock value
:param expire: lock key過期時間
:param timeout: 等待超時
:return:
"""
assert isinstance(redis_client, RedisClient), [type(RedisClient), RedisClient]
wait_time = 0
sleep_time = 0.05
logger.info("acquire_lock lock_key:%s lock_value:%s" % (lock_key, lock_value))
with redis_client.ctx_conn as conn:
while True:
stime = time.time()
if conn.execute('SET', lock_key, lock_value, "NX", "EX", expire):
return True
elif conn.execute('TTL', lock_key) == -1:
conn.execute('EXPIRE', lock_key, expire)
gevent.sleep(sleep_time)
etime = time.time()
wait_time += etime - stime
if wait_time >= timeout:
break
assert 0, [conn, lock_key, lock_value, expire, timeout]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/545254.html
標籤:NoSQL
上一篇:Mysql 自定義目錄安裝
