1. 分散ロックが必要なのはなぜですか?分散ロックについて話す前に、なぜ分散ロックが必要なのかを簡単に説明する必要があります。 分散ロックに対応するのが「単一マシンロック」です。マルチスレッド プログラムを作成する場合、共有変数を同時に操作することで発生するデータの問題を回避するために、通常は「相互排他」ロックを使用して共有変数の正確性を確保します。使用範囲は「同一プロセス内」となります。 複数のプロセスが同時に共有リソースを操作する必要がある場合、どのようにして相互に排他的にすることができますか? たとえば、現在のビジネス アプリケーションは通常、マイクロサービス アーキテクチャであり、1 つのアプリケーションで複数のプロセスが展開されます。これらの複数のプロセスが MySQL 内の同じレコード行を変更する必要がある場合、無秩序な操作によって発生するデータ エラーを回避するために、「分散ロック」を導入してこの問題を解決する必要があります。 分散ロックを実装するには、外部システムを使用する必要があり、すべてのプロセスがこのシステムで「ロック」を申請する必要があります。 この外部システムは「相互排他」機能を実装する必要があります。つまり、2 つの要求が同時に到着した場合、1 つのプロセスのみが成功を返し、もう 1 つのプロセスは失敗 (または待機) を返します。 この外部システムとしては、MySQL、Redis、Zookeeper などがあります。しかし、より良いパフォーマンスを追求するために、通常は Redis または Zookeeper を使用することを選択します。 次に、Redis をメインラインとして、浅いところから深いところまで、分散ロックのさまざまな「セキュリティ」の問題を詳細に分析し、分散ロックを徹底的に理解できるようにします。 2. 分散ロックを実装するにはどうすればいいですか?一番簡単なものから始めましょう。 分散ロックを実装するには、Redis に「相互に排他する」機能が必要です。 SETNX コマンドを使用できます。これは、SET if Not eXists を意味します。つまり、キーが存在しない場合はその値が設定され、存在する場合は何も実行されません。 2 つのクライアント プロセスがこのコマンドを実行して相互排他を実現し、分散ロックを実装できます。 クライアント 1 がロックを申請し、ロックが成功します。
クライアント 2 はロックを申請しますが、後から到着したため失敗します。
この時点で、リソースを正常にロックしたクライアントは、「共有リソース」を操作できます。たとえば、MySQL のデータ行を変更したり、API リクエストを呼び出したりできます。 操作が完了したら、後から参加したユーザーが共有リソースを操作する機会を与えるために、ロックを時間内に解除する必要があります。ロックを解除するにはどうすればいいですか? これも非常に簡単で、DEL コマンドを使用してこのキーを削除するだけです。
ロジックは非常にシンプルで、全体的な流れは次のようになります。 しかし、大きな問題があります。クライアント 1 がロックを取得するときに、次のシナリオが発生すると、「デッドロック」が発生します。 プログラムはビジネスロジック例外を処理し、時間内にロックを解除できません。 プロセスがハングし、ロックを解除する機会がない この時点で、このクライアントは常にこのロックを占有し、他のクライアントは「決して」このロックを取得できなくなります。 この問題を解決するにはどうすればいいでしょうか? 3. デッドロックを回避するにはどうすればよいでしょうか?簡単に考えられる解決策としては、ロックを申請する際に「リース期間」を設定することです。 Redis に実装する場合、このキーに「有効期限」を設定します。ここでは、共有リソースの操作時間が 10 秒を超えないと想定しているため、ロックするときにキーが 10 秒で期限切れになるように設定します。
こうすることで、クライアントが異常かどうかに関わらず、10秒後にロックを「自動的に解除」することができ、他のクライアントは引き続きロックを取得できるようになります。 疑問の顔ですが、本当にこれでいいのでしょうか? まだ問題が残っています。 現在の操作は、ロックと有効期限の設定を 2 つのコマンドとして実行します。最初のコマンドだけが実行され、2 番目のコマンドが時間内に実行されない可能性はありますか?例えば:
つまり、これら 2 つのコマンドがアトミック操作 (一緒に成功する) であることは保証されず、有効期限の設定が失敗し、「デッドロック」問題が依然として発生する潜在的なリスクがあります。 それで何をすればいいのでしょうか? Redis 2.6.12 より前では、SETNX と EXPIRE のアトミック実行を保証する方法を考え、さまざまな異常な状況に対処する方法も考慮する必要がありました。 しかし、Redis 2.6.12 以降では、Redis は SET コマンドのパラメータを拡張し、次のコマンドを使用できるようになりました。
これによりデッドロックの問題が解決され、比較的簡単になります。 |
<<: 25年以上のIT経験を持つクラウドコンピューティング技術の専門家が、クラウドファースト戦略の鍵について詳しく説明します。
>>: ファーウェイクラウドと51Home、インテリジェント住宅生活サービスに関する戦略的協力協定を締結
最近、中国のウェブマスターフォーラムを閲覧していたところ、多くの初心者ウェブマスターが解決が難しい問...
注:この記事は非常に退屈です。特別な必要がない限り、スキップしたり無視したりすることができます。昨日...
Baidu のホームページでキーワード検索を入力すると、検索結果ページにジャンプし、ブラウザの UR...
管理者は、データの使用状況を効果的に分析し、データをより経済的なディスクに手動で移行する必要がありま...
ウェブサイトを過度に最適化すると、ウェブサイトのランクが下がる可能性があります。このトピックは、一部...
現代社会は自己実現の社会です。誰もが自分を見せたり共有したりすることに喜びを感じており、若者はさまざ...
企業サイトや個人ブログはそれぞれ異なるユーザー(つまり、異なるオーディエンス)に直面しています。ユー...
ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeibo はセルフメデ...
[[347022]] Redis 分散ロック分散ロックはなぜ必要なのでしょうか? JDK はロックす...
IT業界は低年齢層向けの業界だと多くの人が考えています。白髪の老人は「プログラマー」という言葉に縁が...
Discuz! の愛好家たちは 4 月 10 日に、インターネット時代は注目経済の時代であると報告し...
実際、クラウド ネイティブ テクノロジーがほとんどの IT システムが目指すべき目標となっていること...
私は外部リンクの掲載にかなりの経験があります。外部リンクはウェブサイトの最適化に非常に良い効果をもた...
王維「ウェアラブルデバイス」や「インターネットハードウェア」がメディアや資本によってトレンドとみなさ...
2013 年以前は外部リンクが王様でしたが、2013 年以降はユーザーが王様です。実際、検索エンジン...