分散ロックを使用する理由は何ですか? この問題について議論する前に、ビジネス シナリオを見てみましょう。 システム A は電子商取引システムであり、現在は 1 台のマシンに導入されています。システムにはユーザーが注文するためのインターフェースがありますが、注文する前に、ユーザーは在庫をチェックして、十分な在庫があるかどうかを確認する必要があります。 システムにはある程度の並行性があるため、商品の在庫は事前に redis に保存され、ユーザーが注文すると redis の在庫が更新されます。 この時点でのシステム アーキテクチャは次のとおりです。 しかし、これによって問題が発生します。ある瞬間に、Redis 内の特定の商品の在庫が 1 の場合、2 つのリクエストが同時に到着し、そのうちの 1 つは上図のステップ 3 まで実行され、データベースの在庫が 0 に更新されますが、ステップ 4 はまだ実行されていません。 他のリクエストはステップ 2 まで実行され、在庫がまだ 1 であることがわかったので、ステップ 3 に進みます。 結果、商品は 2 個売れましたが、在庫は 1 個しかありません。 これは明らかに間違っています!これは典型的な在庫の売られ過ぎの問題です。 この時点で、解決策を考えるのは簡単です。ロックを使用してステップ 2、3、4 をロックし、これらのステップが実行された後に別のスレッドがステップ 2 を実行できるようにします。 上図の通り、ステップ 2 を実行する際に、Java が提供する synchronized または ReentrantLock を使用してロックし、ステップ 4 が完了したらロックを解除します。 このように、ステップ 2、3、および 4 は「ロック」され、複数のスレッド間でのみ連続して実行できるようになります。 しかし、良い時代は長くは続かなかった。システム全体の同時実行性が急上昇し、1 台のマシンでは処理できなくなりました。次に、以下に示すようにマシンを追加する必要があります。 マシンを追加すると、システムは上記のようになります。すごいですね! 2 人のユーザーのリクエストが同時に到着したが、異なるマシンに届いたと仮定すると、これらの 2 つのリクエストを同時に実行できますか? それとも、在庫の過剰販売の問題が発生しますか? なぜ?上図の 2 つの A システムは 2 つの異なる JVM で実行されるため、追加されるロックはそれぞれの JVM 内のスレッドに対してのみ有効であり、他の JVM 内のスレッドに対しては無効です。 したがって、ここでの問題は、Java が提供するネイティブ ロック メカニズムが、複数のマシンの展開シナリオでは機能しないことです。 これは、2 台のマシンによって追加されたロックが同じロックではない (2 つのロックが異なる JVM にある) ためです。 では、2 台のマシンに追加されたロックが同じロックであることを確認すれば、問題は解決するのではないでしょうか。 この時点で、分散ロックが登場する時が来ました。分散ロックの考え方は次のとおりです。 システム全体で、ロックを取得するためのグローバルかつ一意の「もの」が提供され、各システムはロックが必要なときにこの「もの」にロックを要求するため、異なるシステムによって取得されたロックは同じロックであるとみなすことができます。 この「もの」としては、Redis、Zookeeper、またはデータベースが考えられます。 テキストの説明はあまり直感的ではありませんので、次の図を見てみましょう。 上記の分析から、在庫過剰のシナリオでは、分散展開システムで Java のネイティブ ロック メカニズムを使用するとスレッドの安全性が保証されないため、分散ロック ソリューションを使用する必要があることがわかります。 では、分散ロックをどのように実装するのでしょうか?読み続けてください! Redis ベースの分散ロックの実装 上記の分析は、分散ロックが使用される理由を説明しています。ここでは、分散ロックが実装された場合にどのように対処するかについて詳しく説明します。拡張: Redisson は分散ロックをどのように実装しますか? 最も一般的な解決策は、分散ロックにRedisを使用することです。 分散ロックに Redis を使用するアイデアは、おおよそ次のようになります。Redis にロックが追加されたことを示す値を設定し、ロックが解除されたらキーを削除します。 具体的なコードは次のとおりです。
このアプローチにはいくつかの重要なポイントがあります。
そうでない場合は、まず値を設定し、次に有効期限を設定します。これはアトミック操作ではないため、有効期限を設定する前にクラッシュが発生し、デッドロックが発生する可能性があります (キーは永久に存在します)。
これは、ロック解除時にキーを削除する前に、値がロックされた値と一致していることを確認するためです。 これにより、A がロックを取得し、有効期限が 30 秒の場合、35 秒後にロックが自動的に解除されるという状況を回避できます。 A はロックを解除しようとしますが、この時点で B がロックを取得している可能性があります。クライアント A は B のロックを削除できません。 クライアントが分散ロックを実装する方法を考慮するだけでなく、Redis の展開も考慮する必要があります。 Redis には 3 つのデプロイメント方法があります。
分散ロックに Redis を使用することの欠点は、単一マシンのデプロイメント モードを採用した場合、Redis が失敗する限り、単一ポイントの問題が発生することです。ロックしても機能しません。 マスタースレーブモードでは、ロック中に 1 つのノードのみがロックされます。センチネルによって高可用性が実現されていても、マスターノードに障害が発生してマスターとスレーブの切り替えが発生すると、ロックが失われる可能性があります。 上記の考慮に基づいて、redis の作成者もこの問題を考慮しました。彼は次のような意味を持つ RedLock アルゴリズムを提案しました。 Redis のデプロイメント モードが Redis Cluster であり、マスター ノードが合計 5 つあると仮定します。以下の手順に従ってロックを取得します。
ただし、このアルゴリズムはまだ議論の余地があり、多くの問題がある可能性があり、ロック プロセスが正しいという保証はありません。 別の方法:レディソン さらに、RedisクライアントのネイティブAPIに基づいてRedis分散ロックを実装するには、オープンソースフレームワークRedissionを使用することもできます。 Redisson は、分散ロックのサポートも提供するエンタープライズ レベルのオープン ソース Redis クライアントです。私も皆さんにこれを使うことを強くお勧めします。なぜでしょうか? 上で述べたことを思い出してください。 Redis を通じて値を設定する独自のコードを記述する場合は、次のコマンドを通じて設定します。
ここで設定されるタイムアウトは 30 秒です。 30 秒以内にビジネス ロジックを完了しないと、キーの有効期限が切れ、他のスレッドがロックを取得する可能性があります。 この場合、最初のスレッドがビジネス ロジックの実行を完了する前に 2 番目のスレッドが実行される場合、スレッドの安全性の問題が発生します。なので、この有効期限も別途管理する必要があり、面倒ですね〜 redisson がどのように実装されているか見てみましょう。まずはredissionを使う喜びを感じてください:
とても簡単です。分散ロックを完了するには、API のロック機能とロック解除機能を使用するだけです。それは多くの詳細を考慮するのに役立ちます:
redisson にはウォッチドッグ (監視犬) という概念があります。ロックを取得した後、10 秒ごとにキーのタイムアウトを 30 秒に設定できるようになります。 この方法では、ロックが常に保持されていても、キーの有効期限が切れたり、他のスレッドがロックを取得したりといった問題は発生しません。
(マシンがクラッシュするとウォッチドッグはなくなります。このとき、キーの有効期限は延長されません。30秒後に自動的に期限切れになり、他のスレッドがロックを取得できるようになります) 以下にその実装コードの一部を示します。
さらに、redisson は redlock アルゴリズムのサポートも提供します。 使い方も非常に簡単です:
まとめ: このセクションでは、Redisを分散ロックとして使用する具体的な実装計画を分析します。 そしてその限界のいくつか その後、Redis クライアント フレームワーク redisson が導入されました。 これを使用することをお勧めします。 自分でコードを書くよりも、細かいことはあまり気にしなくて済みます。 Zookeeper に基づく分散ロックの実装 一般的な分散ロック実装ソリューションとしては、Redis を使用するほか、Zookeeper を使用して分散ロックを実装することもできます。 Zookeeper が実装する分散ロックの仕組み (以下、ZK と呼びます) を紹介する前に、ZK とは何かを簡単に紹介しましょう。 Zookeeper は、構成管理、分散コラボレーション、命名機能を提供する集中型サービスです。 zk モデルは次のとおりです: zk には、ファイル システムと同様に、znode と呼ばれる一連のノードが含まれており、各 znode はディレクトリを表し、znode にはいくつかの特性があります。
Zookeeper はオプションの順序付け機能を提供します。たとえば、子ノード「/lock/node-」を作成し、順序を指定できます。その後、Zookeeper は子ノードを生成するときに、現在の子ノードの数に基づいて整数のシーケンス番号を自動的に追加します。 つまり、最初に作成された子ノードの場合、生成される子ノードは /lock/node-0000000000、次のノードは /lock/node-0000000001 というようになります。
ZK の上記の特性に基づいて、ZK を使用して分散ロックを実装するためのソリューションを簡単に考え出すことができます。
ロックが解除されると、次のシーケンス番号を持つノードが起動され、ステップ 3 が再実行され、自身のノード シーケンス番号が最小であるかどうかが判断されます。 例えば、/lock/001 が解放され、/lock/002 が時間を検出すると、ノードセットは [/lock/002,/lock/003] となるため、シーケンス番号が最も小さいノードである /lock/002 がロックを取得します。 全体のプロセスは次のとおりです。 これが具体的な実装アイデアです。コードの書き方については、比較的複雑なのでここでは掲載しません。 キュレーターの紹介 Curator は Zookeeper のオープンソース クライアントであり、分散ロックの実装も提供します。 使い方も比較的簡単です。
分散ロックを実装するためのコア ソース コードは次のとおりです。
実際、キュレーターの分散ロック実装の基本原理は、上記の分析と似ています。ここでは、図を使ってその原理を詳しく説明します。 まとめ: このセクションでは、分散ロックを実装するための zookeeperr のソリューションと zk のオープンソース クライアントの基本的な使用方法を紹介し、その実装原則を簡単に紹介します。関連資料として、「例を使って ZooKeeper で分散ロックを実装してみましょう!」を参照してください。 2つのソリューションの長所と短所の比較 このセクションでは、2 つの分散ロック実装について学習した後、redis と zk の実装の利点と欠点について説明します。 Redis 分散ロックの場合、次のような欠点があります。
しかし一方で、Redisを使用して分散ロックを実装することは多くの企業で非常に一般的であり、ほとんどの場合、いわゆる「非常に複雑なシナリオ」に遭遇することはありません。 したがって、分散ロックとして Redis を使用することも良い解決策です。最も重要な点は、Redis はパフォーマンスが高く、高並行性のロック取得および解放操作をサポートできることです。 zk 分散ロックの場合:
ただし、ZK にも欠点があります。ロックを頻繁に申請したり解除したりするクライアントが多い場合、ZK クラスターにかかる負荷が比較的高くなります。 まとめ: まとめると、redis と zookeeper にはそれぞれ長所と短所があります。これらの問題は、テクノロジーを選択する際の参考要素として使用できます。 提案 これまでの分析から、分散ロックを実装するための一般的なソリューションは Redis と Zookeeper の 2 つであり、それぞれに利点があることがわかりました。どのように選択すればよいでしょうか? 個人的には、zk によって実装されたロックの方が好みです。 Redis には隠れた危険があり、不正確なデータを引き起こす可能性があるからです。ただし、どのように選択するかは、企業内の具体的なシナリオによって異なります。 企業が ZK クラスターの条件を満たしている場合は、ZK の実装が推奨されます。ただし、会社に Redis クラスターしかなく、ZK クラスターを構築する条件がない場合。 実際、redis を使用して実装することも可能です。さらに、システム設計者は、システムにすでに Redis があるが、外部依存関係を再度導入したくないと考えているため、Redis を使用することができます。 これには、システム設計者がアーキテクチャを考慮する必要があります。 |
<<: Hongmeng HarmonyOS 分散ソフトバス: 低遅延、高帯域幅のマルチデバイス仮想ネットワークの構築
>>: Huawei AppGallery Connect 研究グループが西安を訪れ、サーバーレスの新しいトレンドについて議論しました。
現在、総合コミュニティフォーラムは数多くありますが、19階コミュニティ、武漢ローカルフォーラムなどに...
私はこれまでYahoo検索にあまり注意を払っていませんでしたが、最近、いくつかのサイトのランキングを...
外部リンクの掲載形式や掲載場所は、業界によって異なります。外部リンク担当者は、外部リンクを構築すると...
[編集者注] 2013 年以降、電子商取引の状況は目まぐるしいほど変化しました。変化のスピードが速す...
@陈子木 以前、ビジュアルデザイナーと一緒にWebアプリケーションを開発したことがあります。彼が提出...
2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています私はウェブ...
オンライン マーケティング モデルの人気が高まり、オンライン プロモーションには従来のマーケティング...
コミュニティ ウェブサイトは、その名前が示すように、インターネット上の小さなコミュニティです。例えば...
justhost は、ロステレコム データセンター内に 2 つのデータセンターを持っています。1 つ...
編集者注: この記事は、Sinovation Ventures のパートナーである Wang Hua...
Racknerd は、米国建国記念日 (7 月 4 日、独立記念日) に合わせて、年間 11.38 ...
ライトブログは、ブログとマイクロブログの中間のネットワークサービスです。ブログは表現力に富む傾向があ...
Hadoop と Spark をどのように比較しても、Spark エコシステムがどれほど成熟し完成し...
「近年、当院の外来業務へのプレッシャーが爆発的に増大し、関連する医療業務システムは24時間365日、...
A5ウェブマスターネットワークによると、数ヶ月間激化していた電子商取引の価格戦争は本日午前9時に最高...