Redis を使用して分散ロックを実装する方法
私は愚かです
そうですね、ローカル システムで作業するときは常に、すべてがバターのように機能します。それが、私たちが 「127.0.0.1 に勝る場所はない」 と呼ぶ理由ですが、現実に目覚めてください
まあ、本番環境では必ずしも期待どおりに動作するとは限りません。主に、アプリケーションの複数のインスタンスを実行している場合です。
?ご覧のとおり、アプリケーションの複数のインスタンスが実行されており、クライアントが DB 内でユーザーを有料ユーザーとしてマークするリクエストを行ったとします。
- クライアントはサーバーをリクエストします
- リクエストはロードバランサーに到達します
- インスタンスの 1 つがリクエストを取得し、DB に書き込みクエリを作成します
大丈夫そうですよね?今のところ問題ありません。
そうですね、今のところは問題ありません。しかし、次のようなビジネス ロジックを書きたい場合はどうなるでしょうか:-
- DB からユーザーを取得します
- ユーザーが無料ユーザーであるか、すでに有料ユーザーであるかを確認します
- 無料の場合は、有料としてマークし、データベースに保存します
- 支払われた場合は、応答で「支払い済み」を送信します。
⚡️ ご存知のとおり (ここでは MySQL を使用していると仮定します)、MySQL DB は ACID に準拠しており、これはすべてのクエリがアトミックで分離されることを意味します。これは、MySQL クエリがアトミックな方法で実行され、成功するか失敗するかを意味します。ただし、途中で終了することはありません。
?しかし、ここで問題が 1 つあります。考えて、考えて....
- ステップ 1: ユーザーを取得しています (アトミック トランザクション)
- ステップ 2: コードでビジネス ロジックを実行する
- ステップ 3: ユーザーが支払いを行っていない場合に MySQL レコードを更新する (アトミック トランザクション)
ステップ 2 で支払いをキャンセルするリクエストがもう 1 つあり、そのクエリが最初に実行されてユーザーが無料としてマークされ、次にステップ 3 が実行されてユーザーが有料としてマークされた場合はどうなりますか。
??万歳、ユーザーは料金を支払うことなく当社の製品にアクセスできるようになりました。
ロック
✅ 救世主、ロックスの登場
?ロックは、一度に 1 つのスレッドのみがクリティカル セクション (複数のワーカー、つまりスレッドによってアクセスされるべきではないコードのブロック) に入ることができる構造です
したがって、操作の完了前にロックを取得し、完了後に解放します。-
- ステップ 0: try-acquire() ロック
- ステップ 1: 取得した場合は、ユーザーを取得します (アトミック トランザクション)
- ステップ 2: コードでビジネス ロジックを実行する
- ステップ 3: ユーザーが支払いを行っていない場合に MySQL レコードを更新する (アトミック トランザクション)
- ステップ 4: ロックを解放()します
?問題
ここで問題が発生します。それは、メモリ ロック データ構造またはメモリ ベースのロックを使用する場合、それがアプリケーションの 1 つのインスタンスに適格になるということです。同じコードを実行し、DB 内で更新している他のインスタンスはどうなりますか?
分散ロックの概念が登場します
?分散ロック
ここでのロックは集中サービスとして機能し、サービスの 1 つのインスタンスがロックを取得すると、他のインスタンスは同じキーを使用できなくなります。
支払いサービスではどのようなキーがここにある可能性がありますか?
?ユーザーが支払いを行う場合、キーは = "PAYMENT_" + user_id + amount
の組み合わせになります。これはユーザーごとに一意になります。そして、このキーは、ユーザーが支払いを行ったり、支払いをキャンセルしたりしても同じままになります。したがって、どちらかのアクションが同じキーを取得しようとするため、一方のアクションが発生しているときは、他のアクションを続行できません。
?一体何だ キー、ロックの取得、ロックの解除。そして最も重要なのは、Redis がどのように使用されているのかということです。
? Redis を使用して分散ロックを実装する
Redis の単一インスタンスの使用:-
しかし、単一の Redis インスタンスにはいくつかの問題があります:-
- 単一のインスタンスが失敗し、取得したロックが解放されない可能性があります
- 1 つのクライアントが 1 つのインスタンスのロックを取得するときに 2 つのインスタンスが使用される場合 (マスター-レプリカ)
- マスターは同期するためにレプリカと同様に通信する必要があります。この通信自体は非同期通信です
?つまり、マスターでロックが取得され、レプリカとの通信中にマスターがレプリカと同期する前にダウンした場合です。レプリカはマスターになり、以前にマスターで取得したものと同じキーのロックを取得できるようになります。
サービスの 2 つのインスタンスは、2 つのインスタンス (マスター レプリカ) がある場合でも、Redis 上のロックを取得できます。
Redlock アルゴリズムの使用:-
ロックの取得:- ロックの有効期限を指定して複数の Redis インスタンスのロックを取得しようとします
ロックの検証:- 主要な Redis インスタンスがクライアントに対してロックを取得した場合、ロックは取得されたものとみなされます
ロックの解放:- ロックを解放すると、すべてのインスタンスがロックを解放します
はい、それだけです。
❤️ お読みいただきありがとうございます。このような記事をさらにご覧いただくためにニュースレターを購読してください:- https://www.serversidedigest.com/
詳細情報:-
- Java の Jedis:- https://redis.io/docs/latest/develop/connect/clients/java/jedis/
- Golang の Redis クライアント:- https://github.com/redis/go-redis
以上がRedis を使用して分散ロックを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。
