Redis のロックの簡単な分析、Redlock (Redis 分散ロック) について話しましょう
この記事では、Redis のロックについて説明し、ロックが使用される理由を紹介します。Redlock (Redis 分散ロック) は本当に必要ですか? 皆様のお役に立てれば幸いです。
ロックを使用する理由
私が働いていた幼稚園から高校までの教育会社では、次のようなビジネスがありました。シナリオはこんな感じ。企業側は学生の授業を手配する必要があるため、明らかに授業時間は足りているのに授業時間が足りない、ページを更新すると授業時間が足りていないことが判明するという声が時々寄せられます。さらに恐ろしいのは、場合によっては学生の授業時間がマイナスに差し引かれることです(会社の授業時間が無料で使われることになります)。 [関連する推奨事項: Redis ビデオ チュートリアル ]
別の例は次の例です
上記の 2 つの質問は、発生した問題に対して送信されます。私たちのビジネスから。この問題に対する中心的な解決策は、これらの機密 (重要) データの読み取りと書き込みを同時に許可できるリクエストは 1 つだけであるということです。したがって、現時点では分散ロックを使用してプログラムの同時実行を制限する必要があります。
setnx の問題点は何ですか
まず、誰もがよく知っている Redis を使用して分散ロックを実装する方法を見てみましょう。 。たとえば、記事の冒頭で述べた学生クラスのスケジュールの問題については、次のようにロックできます。
これは、setnx を日常的に使用してロックを実装する方法です。
ここで、そのようなシナリオがあると仮定します。 A にロックの取得を要求すると、学生のクラスをスケジュールするときにプログラムがステップ 2 でハングアップし、ロックが解放されませんでした。その後、ロックはデッドロックになり、同じ学生を操作する次のリクエストはロックを取得できず、学生をスケジュールすることはできません。このとき、手動でロックを解除する必要があります。
デッドロックの問題を解決するために、ロックに有効期限を追加します。
有効期限を追加した後、リクエスト A がロックをアクティブに解放しない場合、ロックの有効期限が切れた後にロックがアクティブに解放されるため、リクエスト B もロックを取得できるようになります。ビジネスロジックを処理します。ただし、有効期限を追加すると、ステップ 1 と 2 の間でプログラムがクラッシュします。その場合、依然としてデッドロックの問題が発生します。この問題の根本は、setnx と Expire の 2 つの命令がアトミック命令ではないことです。したがって、setnx と Expire がそれらをすべて実行するか、まったく実行できないかのいずれかにできれば便利です。
このため、この問題を解決するために、Redis2.8 が登場する前にコミュニティで多数の拡張パッケージが登場しました。この混乱を制御するために、公式はバージョン 2.8 で set 命令の拡張パラメータを追加し、setnx 命令と Expire 命令を一緒に実行できるようにしました。そのため、今後はこのような分散ロックを使用する必要があります
これは完璧に見えます。「setnx と Expir がそれらをすべて実行するか、まったく実行しないことができれば素晴らしいでしょう」という私たちの期待を達成しました。次のシナリオがあると仮定します。
リクエストがロックを取得し、ロックのタイムアウトが 5 秒に設定されています。手順2ではビジネスロジックが実行されますが、何らかの理由で5秒経過してもビジネスロジックが完了せず、タイムアウトによりロックが自動的に解除されます。このときリクエストBも来ており、ロックを取得した後、ビジネスロジックの実行が開始されました。この時点で、A のリクエストのビジネス ロジックが実行され、3 番目のステップが開始され、ロックが解除されます。このとき、B の要求によりロックが取得されましたが、A の要求によりロックが解除されました。その後、C リクエストはロックを取得できます。このとき、リクエスト B とリクエスト C では同時実行の問題が発生します。したがって、この例からわかるように、分散ロックの有効期限の設定は非常に重要であり、設定時間がこのインターフェイスの応答時間よりも短い場合でも、同時実行の問題が発生します。したがって、インターフェイスの応答時間の監視を参照して、ロックの有効期限を設定できます。
Redlock
上記のソリューションはすべて、シングルポイント Redis 実装に基づいています。分散ロックのシングルポイント Redis 実装は、基本的にビジネス シナリオの 95% を満たすことができます。残りの 5% は、データの整合性とロック損失に対するゼロトレランスに関する非常に厳しい要件を伴うビジネス シナリオです。現時点では、Redlock を考慮する必要があります。シングルポイントRedisの場合、sentinelによる高可用性を確保していても、何らかの理由でマスターノードがマスター/スレーブを切り替え、マスターとスレーブのデータ同期が間に合わないとデータ損失やロック損失が発生します。 。
複数の Redis インスタンスがあると仮定します。これらのノードは完全に独立しており、データを調整するためにレプリケーションやシステムを使用する必要はありません。5 つの Redis マスター ノードがあると仮定します。クライアントがロックの場合、手順は次のようになります:
現在のサーバー時刻をミリ秒単位で取得します
同じキーとランダムな値を使用してロックを取得してみます。クライアントは、各マシンでロックを取得するときにタイムアウト期間を設ける必要があります。たとえば、ロックの有効期限が 10 秒の場合、単一ノードのロックを取得します。タイムアウト時間は約 5 ~ 50 ミリ秒にする必要があります。この目的は、クライアントが障害が発生したマシンへの接続に余分な時間を費やさないようにすることです。タイムアウト期間内にデータが取得されない場合、ノードは破棄され、次の Redis ノードが取得されます。
取得が完了したら、クライアントが半分以上 (ここでは 3 ノード) からロックを取得した場合に限り、現在の時刻からステップ 1 で取得した時刻を引いた時刻を取得します。 Redis ノードとロックを取得する時間がロック タイムアウトよりも短い場合は、ロックが有効であることが証明されます。
ロックが取得された場合、キーの実際の有効時間は、有効時間からロックの取得に使用された時間を引いたものになります (手順 3 で計算された結果)。
ロックを取得したマシンの半数以上が満たされていない場合、または計算後のロック タイムアウトが負の場合、またはその他の異常な操作がある場合、システムはすべてのインスタンスのロックを解除しようとします。一部の Redis インスタンスがまったくロックされていない場合でも、ロックが成功しない場合、一部のノードがロックを取得できなくなりますが、クライアントは応答を取得せず、一定期間ロックを再取得できません
これで、実際にレッドロックが確認できます。シングルポイント Redis よりも信頼性が高いと思われるロックです。
あなたが私のような Node.js プログラマーの場合は、直接使用できるサードパーティ ライブラリ redlock があります。
レッドロックは本当に必要ですか?
実は、レッドロックについては別の声もあります。Martin Kleppmann (ケンブリッジ大学の研究者、データベースに従事、分散システムと情報セキュリティが交わる TRVE DATA プロジェクトは、記事 blog を執筆し、レッドロックに関するいくつかの見解を表明しました。 Redis の作者 Salvatore も、この記事の質問に対していくつかの 回答 を行っていますが、これは非常に興味深いものです。著者のブログの要点は次のとおりです。
分散ロックの使用法は 2 つまでです。
- 効率: ロックを使用すると、同じ作業を 2 回行う必要がなくなります (高価な計算など)。ロックが失敗し、両方のノードが同じジョブを実行することになった場合、結果としてコストがわずかに増加するか (そうでない場合よりも AWS に 5 セント多く支払うことになります)、または多少の不便が生じます (たとえば、ユーザーは同じメールを受信することになります)通知)。
- 正確性: ロックを使用すると、同時プロセスが相互に干渉してシステム状態を破壊するのを防ぎます。ロックが失敗し、2 つのノードが同じデータを同時に処理すると、その結果、ファイルの破損、データの損失、永続的な不一致、患者に投与された薬剤の誤った用量、またはその他の非常に深刻な問題が発生します。
効率性を重視するのであれば、Redlock のコストと複雑さを負担する必要はありません。ロックの損失によりさらに数回メールを送信するコストや、5 台の Redis サーバーを実行するコストと比較すると、単一の Redis サンプルのみを使用することをお勧めします。単一の Redis インスタンスを使用していて、Redis ノードが突然電源を失ったり、クラッシュしたり、その他の問題が発生した場合、当然、この時点でロックが失われます。ただし、効率の最適化としてロックを使用しているだけで、このクラッシュが頻繁に発生しない場合は、大した問題ではありません。この「大したことはない」シナリオは、まさに Redis が優れている点です。少なくとも、単一の Redis インスタンスに依存している場合は、システムを見ている全員が問題をより簡単に特定できるようになります。
厳密に言えば、redlock には強整合性の厳密性はまったくありません。いくつかの例を示します。
タイミングとシステム クロックは危険な仮定を立てており、各サーバーのクロックに大きく依存しています。システムには GC が存在するため、GC 中にサーバー全体が負荷をかけられ、時間が停滞するため、クロックに強く依存することはできません。
- #トークンがありません。サーバーは、クライアントがロックを取得するたびにトークンを発行するわけではなく、ロックの操作を困難にするために、各操作中にクライアントのトークンがサーバーの現在のトークンと一致することを確認する必要があります。
プログラミング入門をご覧ください。 !
以上がRedis のロックの簡単な分析、Redlock (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)

ホットトピック











Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redisのキューを読むには、キュー名を取得し、LPOPコマンドを使用して要素を読み、空のキューを処理する必要があります。特定の手順は次のとおりです。キュー名を取得します:「キュー:キュー」などの「キュー:」のプレフィックスで名前を付けます。 LPOPコマンドを使用します。キューのヘッドから要素を排出し、LPOP Queue:My-Queueなどの値を返します。空のキューの処理:キューが空の場合、LPOPはnilを返し、要素を読む前にキューが存在するかどうかを確認できます。

Redisデータをクリアする方法:Flushallコマンドを使用して、すべての重要な値をクリアします。 FlushDBコマンドを使用して、現在選択されているデータベースのキー値をクリアします。 [選択]を使用してデータベースを切り替え、FlushDBを使用して複数のデータベースをクリアします。 DELコマンドを使用して、特定のキーを削除します。 Redis-CLIツールを使用してデータをクリアします。

Centosシステムでは、Redis構成ファイルを変更するか、Redisコマンドを使用して悪意のあるスクリプトがあまりにも多くのリソースを消費しないようにすることにより、LUAスクリプトの実行時間を制限できます。方法1:Redis構成ファイルを変更し、Redis構成ファイルを見つけます:Redis構成ファイルは通常/etc/redis/redis.confにあります。構成ファイルの編集:テキストエディター(VIやNANOなど)を使用して構成ファイルを開きます:sudovi/etc/redis/redis.conf luaスクリプト実行時間制限を設定します。

Redisデータの有効期間戦略には2つのタイプがあります。周期削除:期限切れのキーを削除する定期的なスキャン。これは、期限切れの時間帯-remove-countおよび期限切れの時間帯-remove-delayパラメーターを介して設定できます。怠zyな削除:キーが読み取られたり書かれたりした場合にのみ、削除の有効期限が切れたキーを確認してください。それらは、レイジーフリーレイジーエビクション、レイジーフリーレイジーエクスピア、レイジーフリーラジーユーザーのパラメーターを介して設定できます。

Redisコマンドラインツール(Redis-Cli)を使用して、次の手順を使用してRedisを管理および操作します。サーバーに接続し、アドレスとポートを指定します。コマンド名とパラメーターを使用して、コマンドをサーバーに送信します。ヘルプコマンドを使用して、特定のコマンドのヘルプ情報を表示します。 QUITコマンドを使用して、コマンドラインツールを終了します。

Redisカウンターは、Redisキー価値ペアストレージを使用して、カウンターキーの作成、カウントの増加、カウントの減少、カウントのリセット、およびカウントの取得など、カウント操作を実装するメカニズムです。 Redisカウンターの利点には、高速速度、高い並行性、耐久性、シンプルさと使いやすさが含まれます。ユーザーアクセスカウント、リアルタイムメトリック追跡、ゲームのスコアとランキング、注文処理などのシナリオで使用できます。

Debian Systemsでは、Directoryコンテンツを読み取るためにReadDirシステム呼び出しが使用されます。パフォーマンスが良くない場合は、次の最適化戦略を試してください。ディレクトリファイルの数を簡素化します。大きなディレクトリをできる限り複数の小さなディレクトリに分割し、Readdirコールごとに処理されたアイテムの数を減らします。ディレクトリコンテンツのキャッシュを有効にする:キャッシュメカニズムを構築し、定期的にキャッシュを更新するか、ディレクトリコンテンツが変更されたときに、頻繁な呼び出しをreaddirに削減します。メモリキャッシュ(memcachedやredisなど)またはローカルキャッシュ(ファイルやデータベースなど)を考慮することができます。効率的なデータ構造を採用する:ディレクトリトラバーサルを自分で実装する場合、より効率的なデータ構造(線形検索の代わりにハッシュテーブルなど)を選択してディレクトリ情報を保存およびアクセスする
