Alibaba第2回インタビュー:Redis分散ロックの有効期限が切れたが、業務が完了していない場合はどうすればよいですか?

Alibaba第2回インタビュー:Redis分散ロックの有効期限が切れたが、業務が完了していない場合はどうすればよいですか?

[[420487]]

インタビュアー: あなたのシステムでは分散ロックをどのように実装していますか?

:Redis 分散ロックを使用しました。具体的なアプローチとしては、バックエンドがリクエストを受信した後、分散ロックを追加します。ロックが成功すると、ビジネスが実行されます。ロックが失敗した場合は、ロックを待機するか、要求を拒否します。業務実行が完了するとロックが解除されます。

インタビュアー:具体的にどのようなコマンドが使われているのか教えていただけますか?

: SETNX コマンドは次のように使用します。

  1. SETNX キー名値

設定が成功した場合は 1 が返されます。それ以外の場合は 0 が返されます。次の図に示すように、クライアント 1 はロックを正常にロックしましたが、クライアント 2 はロックを取得できませんでした。

インタビュアー:この設定に問題はありますか?正常にロックされたクライアントがクラッシュした場合はどうなりますか?

:例えば、上の図のクライアント 1 がクラッシュした場合、ロックを解除することはできません。有効期限を設定できます。コマンドは次のとおりです。

  1. セット キー値 [EX 秒] [PX ミリ秒] NX

インタビュアー:有効期限を設定した場合、業務が完了していないのにRedisロックの有効期限が切れてしまった場合はどうすればいいでしょうか?

:鍵を交換しなければなりません。

インタビュアー:どのように機能するのか教えていただけますか?

: ロックの設定に成功したら、ウォッチドッグを起動して、一定時間 (たとえば 10 秒) ごとに現在の分散ロックを更新します。つまり、現在のキーのタイムアウトを 10 秒ごとにリセットします。コマンドは次のとおりです。

  1. EXPIRE <キー> <秒数>

全体のプロセスは次のとおりです。

インタビュアー: ウォッチドッグを実装するにはどうすればいいですか?

: クライアントが正常にロックされると、スケジュールされたタスクが開始され、10 秒ごとに (できれば構成サポートを使用して) ビジネスが処理されたかどうかを確認できます。検出の基礎は、分散ロックのキーがまだ存在するかどうかを判断することです。そうであれば更新されます。

インタビュアー: 現在のスレッドが処理されている場合、このキーは別のクライアントによって書き込まれますか?

: クライアントごとに clientID を指定し、VALUE に clientID プレフィックスを追加できます。このように、ロックを更新するときに、現在の分散ロックの値のプレフィックスを判断して、それが現在のクライアントに属しているかどうかを判断できます。一致する場合はロックを更新し、そうでない場合は何もしません。

インタビュアー:再ロック機能はご自身で実装されたのですか?

:私たちはredissonの分散ロックソリューションを使用しています。 redisson を使用して分散ロックを取得するのは非常に簡単です。コードは次のとおりです。

  1. RLock ロック = redisson.getLock( "クライアントロック" );
  2. ロック。ロック();
  3. 試す {
  4. //加工事業
  5. } キャッチ (例外 e) {
  6. //例外を処理する
  7. ついに
  8. ロックを解除します。
  9. }

具体的な原則は次のとおりです。クライアント 1 が正常にロックした場合、この分散ロックのデフォルトのタイムアウトは 30 秒です (Config.lockWatchdogTimeout を通じて変更できます)。ロックが正常に追加されると、ウォッチドッグが開始されます。ウォッチドッグは、クライアント 1 がまだロック キーを保持しているかどうかを 10 秒ごとにチェックするバックグラウンド スレッドです。そうであれば、ロックキーの寿命が延長されます。拡張操作は、ロック キーのタイムアウトを再度 30 秒に設定することです。

インタビュアー:redisson ではタイマーはどのように実装されていますか?

: redisson タイマーは、netty-common パッケージの HashedWheelTime を使用して実装されています。

インタビュアー: クライアント1がクラッシュした場合、分散ロックは更新できますか?

:分散ロックの更新はクライアント上で実行されるため、クライアント1がダウンすると更新スレッドが動作できなくなり、ロックを更新できなくなります。この時点で、分散ロックは削除され、他のクライアントが取得できるようにする必要があります。

インタビュアー: クライアント 1 がクラッシュした場合、他のクライアントはロックを取得するのに 30 秒待たなければなりません。ロックをすぐに削除する方法はありますか?

: client1 がダウンしているため、タイムアウト期間後にロックが自動的に削除されるまで待つことしかできません。すぐに削除したい場合は、センチネルがすべての Redis クライアントのリストを維持できるようにセンチネル メカニズムを追加するなどの追加作業を行う必要があります。センチネルはクライアントがダウンしているかどうかを定期的に監視します。ダウンタイムが検出されると、クライアントのロックは直ちに削除されます。以下のように表示されます。

ここでのセンチネルは、Redis のセンチネルではなく、クライアントの障害を検出するためにビジネス システム自体によって作成されたセンチネルです。

インタビュアー:redisson を使用しない場合、分散ロック継続をどのように実装しますか?たとえば、springboot2.0 で使用されるデフォルトの Redis クライアントは Lettuce です。

:Lettuce は redisson のようなウォッチドッグ メカニズムを提供していないため、ロックの更新はビジネス システム自体で実装する必要があります。これは次の手順で実現できます。

1. ロック コマンドについては、Spring パッケージ内の分散ロック コードを参照します。ロックが存在し、現在のクライアントによって追加された場合は、ロックを更新します。ロックが存在しない場合は、ロックを追加します。コードは次のとおりです。

  1. プライベート静的最終文字列 OBTAIN_LOCK_SCRIPT =
  2. "ローカル lockClientId = redis.call('GET', KEYS[1])\n" +
  3. "lockClientId == ARGV[1] の場合\n" +
  4. " redis.call('PEXPIRE', KEYS[1], ARGV[2])\n" +
  5. " true を返す\n" +
  6. "そうでなければ lockClientId ではない\n" +
  7. " redis.call('SET', KEYS[1], ARGV[1], 'PX', ARGV[2])\n" +
  8. " true を返す\n" +
  9. "終了\n" +
  10. "falseを返す" ;

2. ロックを HashMap などのデータ構造に保存します。スケジュールされたタスクは定期的にマップをスキャンし、各ロックを更新します。コードは次のとおりです。

  1. プライベート最終 Map<String, RedisLock> locks = new ConcurrentHashMap<>();

3. 再ロックコマンド

  1. プライベート静的最終文字列 RENEW_LOCK_SCRIPT =
  2. "ローカル lockClientId = redis.call('GET', KEYS[1])\n" +
  3. "lockClientId == ARGV[1] の場合\n" +
  4. " redis.call('PEXPIRE', KEYS[1], ARGV[2])\n" +
  5. " true を返す\n" +
  6. "終了\n" +
  7. "falseを返す" ;

4. 現在のクライアントによってロックが追加された場合はロックを更新し、そうでない場合は失敗します。

ロック継続コードを定期的に実行するスケジュールされたタスクを記述します。

  1. redisTemplate.execute ( renewLockScript
  2. Collections.singletonList(lockKey)、クライアントID、
  3. 文字列.valueOf(expireAfter));

インタビュアー:この質問はここまでにしましょう。次の質問に移りましょう...

<<:  Kafka の運用とメンテナンス |データ移行を本当に理解していますか?

>>:  HarmonyOSJS 分散機能 - 学習ノート

推薦する

anynode-3.75ドル/KVM/Win互換/256MBメモリ/30GBハードディスク/500GBトラフィック

今日は、Anynode の 2 つの特別な VPS、openvz と最小メモリの KVM を紹介しま...

クラウドに移行する前に検討すべき 3 つの質問

過去 10 年間でクラウド コンピューティングの導入が拡大しており、より洗練されたハイブリッド クラ...

VPS 初心者向けチュートリアル: 海外の VPS を購入するには?

友人の中には、若くて語彙が足りない人や、面倒で「説明できない」翻訳ソフトウェアを使いたくない人がいる...

NDRCの罰則は厳しいが、対策はほとんど取られていない。業界は電子商取引のミスのコストは低いと言っている。

電子商取引の価格戦争は続く。最近、クバのCEOディン・ドンホア氏が悲痛な涙を流すプロモーション広告が...

macloud: ロシアのクラウドサーバー、日払い、最低1元/日、AMD EPYC/Intel Gold +NVMe+64Tトラフィック/月、カスタムアップロードISO

ロシアのサーバー業者であるMacloudは、ロシアのモスクワにあるDataproデータセンターで主に...

racknerd: クリスマスセール、特別な高トラフィック VPS、年間 12 ドルから、ハイブリッド サーバーの 50% オフ プロモーション

今年はクリスマス、外国商人によるプロモーションの最後の波です。 Racknerd は、クリスマス向け...

Wang Tong: SEO 実践者はどのようにアップグレードすべきでしょうか?

ここ数か月、Baidu は中国の SEO 実践者全員を大いに苦しめてきました。多くの人が「SEO は...

公安機関がオンライン犯罪を取り締まり、3,500以上の違法ウェブサイトを是正

ウェブマスターネットワークが10月15日に報じたところによると、今年8月に公安部が全国に公安機関を派...

お知らせ: BURSTNET® エンタープライズ クラウド VPS

Burstnet は、エンタープライズ レベルのクラウド VPS に参加したことを知らせるメールを送...

2022 年に避けるべきクラウド コスト最適化の 6 つの間違いとその修正方法

翻訳者 |李睿校正 |孫淑娟 梁策企業や組織は毎年末に、事業規模の拡大やクラウドコストの削減など、翌...

電子商取引ウェブサイト向けオンライン顧客サービスソリューション

1. 開発状況インターネットの急速な発展により、中国のインターネットユーザー数は5億6000万人を超...

ウィトキー産業の「不十分な」発展を4つの視点から分析する

中国のインターネットユーザー数が5億人に達したため、中国のインターネットの発展は新たなレベルに達しま...

ウェブサイトを構築するときにできることは検索エンジンのランキングだけというのは本当ですか?

今日、私はウェブマスターのウェブサイトで「SEOの発展:どこに向かっているのか?」というタイトルの記...

中国聯通とテンセントの戦略的協力の強化は実体経済のデジタル変革に貢献する

12月20日、中国聯通とテンセントは「2022年中国聯通パートナー会議」で新たな戦略協力協定に署名し...

HostingSource - 8 USD/1 GB RAM/30 GB HDD/5 TB フロー/10 GB ポート (Windows+2 USD)

Hostingsource.com は、ホスティング事業で約 20 年の経験があります。現在、ニュー...