ホームページ  >  記事  >  データベース  >  Redis が分散ロックを実装する方法

Redis が分散ロックを実装する方法

(*-*)浩
(*-*)浩オリジナル
2019-11-27 10:33:044147ブラウズ

Redis が分散ロックを実装する方法

分散ロックが解決する必要がある問題

相互排他性: いつでも 1 つのクライアントのみがロックを所有できます。一度に複数のクライアントは所有できません。同時にクライアントの取得

#セキュリティ: ロックを削除できるのはロックを保持しているユーザーのみであり、他のユーザーは削除できません (推奨学習:

Redis ビデオ チュートリアル)# # デッドロック: ロックを取得したクライアントが何らかの理由でクラッシュし、ロックの解放に失敗しました。他のクライアントはロックを取得できません。この種の問題を回避するにはメカニズムが必要です。

フォールト トレランス:ノードはダウンしていますが、クライアントは引き続きロックを取得または解放できます

Redis を介して分散ロックを実装する方法: (完全ではない方法)

SETNX キーの値 :

キーが存在しない場合は、値を作成して割り当てます時間計算量:0(1)

戻り値:設定が成功した場合は 1 が返されます。 ; 設定に失敗した場合は0が返されます。

しかし、今回取得したキーは長期間有効なので、長期有効性の問題をどのように解決すればよいでしょうか?

EXPIRE key 秒数

キーの生存時間を設定します。キーの有効期限が切れると (生存時間が 0 になると)、キーは自動的に削除されます

欠点: 原子性が満たされていない

以下は疑似コードです

//该程序存在危险,如果执行到第二行就崩溃了,则此时key会被一直占用而无法被释放
RedisService redisService = SpringUtils.getBean(Redi sService.class); 
long status = redisService.setnx(key, "1");
if(status == 1) {
	redisService.expire(key, expire);
	//执行独占资源逻辑
	doOcuppiedWork();
}

Redis を介して分散ロックを実装する方法: (正しい方法)

SET key value [EX seconds] [PX milliseconds] [NX|XX]
EX 秒: キーの有効期限を秒に設定します。

PX ミリ秒: キーの有効期限をミリ秒ミリ秒に設定します。

NX: 次の場合のみキーが存在しません。キーがすでに存在する場合にのみキーを設定します。

XX: キーがすでに存在する場合にのみキーを設定します。

SET 操作が正常に完了した場合は、OK を返します。それ以外の場合は、OK を返します。 return nil

以下は疑似コードです

RedisService redisService = SpringUtils.getBean(RedisService.class); .
String result = redisService.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
if ("OK".equals(result)) {
	//执行独占资源逻辑
	doOcuppiedWork();
}

多数のキーの同時有効期限切れに関する注意事項

集中有効期限切れ多数のキーのクリアには時間がかかるため、短期的なラグが発生します。

解放計画: キーの有効期限を設定するときに、各キーにランダムな値を追加します

Redis 関連の技術記事の詳細については、

Redis Introduction Tutorial

列を参照して学習してください。

以上がRedis が分散ロックを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。