1. ホーム
  2. データベース
  3. レディス

redis分散ロック最適化の実装

2022-01-15 19:55:57

スタンドアロンアプリケーションでは、synchronizedキーワードやLockツールクラスを使って直接ロックを行うことができますが、分散アプリケーションでは、ロックを実装するためのツールが必要です。

ロック処理を平易に説明すると、次のようになります。
        1.ピットを占拠する
        2. ロジックを実行する
        3. 穴埋め

この穴埋め作業をredisで行うことができます。

ロックの基本バージョン

//Get the lock by taking the pit
boolean lock = redis.setIfAbsent(key, value);
if (lock) {
//business logic

//fill the hole
redis.delete(lock)
}



ロックを取得した後にアプリケーションがダウンし、ロックが解除されないとデッドロックが発生する

ロックを取得する際に、ロックに有効期限を追加する必要があります。

redis.setIfAbsent(key, value);
redis.expire(key, value);


また、誤ってロックを取得した際に有効期限をうまく設定しないとデッドロックが発生することがあります

setとexpireの操作をluaスクリプトでアトミック操作にまとめ、有効期限を正常に設定できるようにする。

ロックが期限切れになっても、現在のタスクが終了していなければ、他のアプリケーションによってロックが取得される可能性があり、ロックのキーが更新され、現在のタスクがロックを解放し終わると、他の人のロックが解放されることになります

ロックを解除する。

  • 現在のロックの値と自身のロックの値が一致するかどうかを判断する。
  • 一致しない場合は解放しない。
  • 値が一致した場合、ロックを解除するキーを削除する。

ロックを解放する際、キーの値が一致したと判断しても、その後キーの有効期限が切れてロックが他の人に取得された場合、キーを削除すると、他の人のロックを解放することになります
クエリ、判定、削除のロジックがアトミックな操作になるように、luaスクリプトを使用します。

ロック再連続性を保証する方法

再帰的なメソッドやその他の呼び出しにロックロジックがある場合、そのロジックは

lock.lock();
//logic
lock.lock();
//logic
lock.unLock();
lock.unLock();


リエントラントロックを実装するには、ロックの値を操作し、その値にリエントラントの数を記録し、ゼロになるまでリエントラントごとに1加算、アンロックごとに1減算し、キーを削除してロックを解除すればよいでしょう。

key:
{
    "value":1
}


ビジネスロジックに時間がかかりすぎて、ロックが早く切れ、解除された場合はどうするか?

  • 有効期限を長く設定する
  • ロックに更新機能を追加する必要がある。

長い有効期限を設定することの欠点は、アプリケーションが停止した後、ロックが他の誰かによってアクセスされる前に長い時間を経験する必要がある場合、ビジネスに影響を与えるということです。

ロックがダウンした場合、より短い有効期限でロックもスワイプされる更新機能があれば、よりエレガントな解決策になります。

Redissionでロックを取得した場合、watchDogスレッドが起動し、現在のスレッドがまだロックを保持しているかどうかを監視し、保持している場合は更新される

10秒ごとにロックが保持されているかどうかを確認し、解除されていない場合はロックの有効期限をリセットして更新します。

アプリケーションがredisのマスターノードでロック取得に成功した場合、マスターノードがダウンしてスレーブノードにロックデータがまだ同期されておらず、マスター・スレーブ切り替え後に他のアプリケーションが分散ロック取得の機会を狙っている場合

レッドロック

マスター・スレーブ構造では問題があるのでは? redlockでは、マスター・スレーブ関係のない複数のredisMasterノードを使って、同時にダウンしないように、できれば合計数が奇数であるように切り替えます。
redLockは、複数のノードのロックを同時に取得し、半分以上のノードがロック取得に成功した場合のみ成功し、それ以外は失敗し、すべてのノードからロックを削除するためにロールバックすることで動作します。

参考資料

つまり、大きなRedisの分散ロックはこのように設計されているのです。

Redis分散ロックの仕組みと更新方法

Redis分散ロック最適化に関する記事は以上です。redis分散ロック最適化については、Scripting Houseの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。