分散ロックの見解
6313 ワード
分散ロックを実装するには、共通コンポーネントRedisを使用します. redisのsetnx 最も簡単なのは、redis上でkeyを取得し、戻り結果に基づいて論理 を処理することである.問題:プログラムの実行時にエラーが発生した場合、ロックが解放されず、デッドロックが発生します. スキーム:finallyでロックを解放し、プログラムの実行エラーがfinally解放ロック に入るこれに基づいて改良され、try,finally を加える.問題:アプリケーションがkillされた場合、finallyリリースロック にはアクセスしません.案:期限が切れた場合、デッドロックはわずかな時間で を受け入れることができる.問題: シーン:期限切れは10 sで、あるリクエストが15秒で完了すると、10 sでRedisサービスがこのキーを解放し、2番目のリクエストが来てからキーを要求し、5秒後、1番目のリクエストはアクティブにキーを解放したが、2番目のリクエストはまだ完了していない可能性があり、3番目のリクエストが来て、リクエストキー、2番目のリクエストはアクティブにキーを解放した.スキーム:設定時にキーは一意であるが、値は現在のスレッドの情報に設定でき、アクティブ解放時に現在のスレッドが持つロックであるか否かを判断する. 不足:タイムアウト時に2つのスレッドが同じロックを持っていることが発生します. 補完不足:setnxに成功した後、ガードスレッドを開き、現在のスレッドにロックがあるかどうかを判断し、ある場合は期限切れ時間を再設定します.そうしないと、プライマリスレッドがロックを解除したことを示します.コードロジックは簡単であるが、実装には様々なバグが発生する可能性があり、redis-pyを使用できるロックの使用方法はロックの方法である:lock=Lock()lock.acquire
: key value key , 1, 0
#
ret = redis.setnx(key,value)
if ret:
stock = redis.get('stock') # 100
if stock > 0:
stock -= 1
else:
return Response(' ')
else:
return Response(' ')
redis.del(key)
try:
ret = redis.setnx(key,value)
if ret:
stock = redis.get('stock') # 100
if stock > 0:
stock -= 1
else:
return Response(' ')
else:
return Response(' ')
finally:
redis.del(key)
try:
ret = redis.set(key, value, ex=10,nx=True) # 10 ,
if ret:
stock = redis.get('stock') # 100
if stock > 0:
stock -= 1
else:
return Response(' ')
else:
return Response(' ')
finally:
redis.del(key)
:後で要求されたredis_keyは前者に解放され、失効を招いた.