ホームページ Java &#&チュートリアル Redis を使用して分散ロックを実装する方法

Redis を使用して分散ロックを実装する方法

Aug 31, 2024 pm 06:31 PM

私は愚かです

そうですね、ローカル システムで作業するときは常に、すべてがバターのように機能します。それが、私たちが 「127.0.0.1 に勝る場所はない」 と呼ぶ理由ですが、現実に目覚めてください

How to implement a Distributed Lock using Redis

まあ、本番環境では必ずしも期待どおりに動作するとは限りません。主に、アプリケーションの複数のインスタンスを実行している場合です。

How to implement a Distributed Lock using Redis

?ご覧のとおり、アプリケーションの複数のインスタンスが実行されており、クライアントが DB 内でユーザーを有料ユーザーとしてマークするリクエストを行ったとします。

  • クライアントはサーバーをリクエストします
  • リクエストはロードバランサーに到達します
  • インスタンスの 1 つがリクエストを取得し、DB に書き込みクエリを作成します

大丈夫そうですよね?今のところ問題ありません。

そうですね、今のところは問題ありません。しかし、次のようなビジネス ロジックを書きたい場合はどうなるでしょうか:-

  • DB からユーザーを取得します
  • ユーザーが無料ユーザーであるか、すでに有料ユーザーであるかを確認します
  • 無料の場合は、有料としてマークし、データベースに保存します
  • 支払われた場合は、応答で「支払い済み」を送信します。

⚡️ ご存知のとおり (ここでは MySQL を使用していると仮定します)、MySQL DB は ACID に準拠しており、これはすべてのクエリがアトミックで分離されることを意味します。これは、MySQL クエリがアトミックな方法で実行され、成功するか失敗するかを意味します。ただし、途中で終了することはありません。

?しかし、ここで問題が 1 つあります。考えて、考えて....

  • ステップ 1: ユーザーを取得しています (アトミック トランザクション)
  • ステップ 2: コードでビジネス ロジックを実行する
  • ステップ 3: ユーザーが支払いを行っていない場合に MySQL レコードを更新する (アトミック トランザクション)

ステップ 2 で支払いをキャンセルするリクエストがもう 1 つあり、そのクエリが最初に実行されてユーザーが無料としてマークされ、次にステップ 3 が実行されてユーザーが有料としてマークされた場合はどうなりますか。

??万歳、ユーザーは料金を支払うことなく当社の製品にアクセスできるようになりました。

ロック

✅ 救世主、ロックスの登場
How to implement a Distributed Lock using Redis

?ロックは、一度に 1 つのスレッドのみがクリティカル セクション (複数のワーカー、つまりスレッドによってアクセスされるべきではないコードのブロック) に入ることができる構造です

したがって、操作の完了前にロックを取得し、完了後に解放します。-

  • ステップ 0: try-acquire() ロック
  • ステップ 1: 取得した場合は、ユーザーを取得します (アトミック トランザクション)
  • ステップ 2: コードでビジネス ロジックを実行する
  • ステップ 3: ユーザーが支払いを行っていない場合に MySQL レコードを更新する (アトミック トランザクション)
  • ステップ 4: ロックを解放()します

?問題

ここで問題が発生します。それは、メモリ ロック データ構造またはメモリ ベースのロックを使用する場合、それがアプリケーションの 1 つのインスタンスに適格になるということです。同じコードを実行し、DB 内で更新している他のインスタンスはどうなりますか?

分散ロックの概念が登場します

?分散ロック

How to implement a Distributed Lock using Redis

ここでのロックは集中サービスとして機能し、サービスの 1 つのインスタンスがロックを取得すると、他のインスタンスは同じキーを使用できなくなります。

支払いサービスではどのようなキーがここにある可能性がありますか?

?ユーザーが支払いを行う場合、キーは = "PAYMENT_" + user_id + amount

の組み合わせになります。

これはユーザーごとに一意になります。そして、このキーは、ユーザーが支払いを行ったり、支払いをキャンセルしたりしても同じままになります。したがって、どちらかのアクションが同じキーを取得しようとするため、一方のアクションが発生しているときは、他のアクションを続行できません。

?一体何だ キー、ロックの取得、ロックの解除。そして最も重要なのは、Redis がどのように使用されているのかということです。


? Redis を使用して分散ロックを実装する

Redis の単一インスタンスの使用:-

How to implement a Distributed Lock using Redis

しかし、単一の Redis インスタンスにはいくつかの問題があります:-

  • 単一のインスタンスが失敗し、取得したロックが解放されない可能性があります
  • 1 つのクライアントが 1 つのインスタンスのロックを取得するときに 2 つのインスタンスが使用される場合 (マスター-レプリカ)
  • マスターは同期するためにレプリカと同様に通信する必要があります。この通信自体は非同期通信です

?つまり、マスターでロックが取得され、レプリカとの通信中にマスターがレプリカと同期する前にダウンした場合です。レプリカはマスターになり、以前にマスターで取得したものと同じキーのロックを取得できるようになります。

サービスの 2 つのインスタンスは、2 つのインスタンス (マスター レプリカ) がある場合でも、Redis 上のロックを取得できます。

Redlock アルゴリズムの使用:-

ロックの取得:- ロックの有効期限を指定して複数の Redis インスタンスのロックを取得しようとします
ロックの検証:- 主要な Redis インスタンスがクライアントに対してロックを取得した場合、ロックは取得されたものとみなされます
ロックの解放:- ロックを解放すると、すべてのインスタンスがロックを解放します

How to implement a Distributed Lock using 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 サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

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

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

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

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

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

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

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

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

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

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

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

eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? Apr 19, 2025 pm 11:27 PM

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

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

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

See all articles