面接で必ず聞くべき質問: Redis は分散ロックに適した選択肢ですか?それとも Zookeeper の方が良いのでしょうか?

面接で必ず聞くべき質問: Redis は分散ロックに適した選択肢ですか?それとも Zookeeper の方が良いのでしょうか?

まず、分散ロックの原理は、私たちが普段話しているロックと基本的に同じです。目的は、複数のスレッドが同時に実行されている場合に、1 つのスレッドだけが同時にビジネス、メソッド、または変数を操作するようにすることです。

プロセス、つまり JVM またはアプリケーションでは、制御を処理するのは簡単です。 jdk java.util 並行性パッケージには、これを処理できる synchronized キーワードや Lock ロックなど、ロックを追加するためのメソッドが用意されています。

ただし、現在のアプリケーションが 1 台のサーバーにのみデプロイされている場合、同時実行性は非常に低くなります。一度に数万件ものリクエストがあった場合、サーバーが過負荷になり麻痺してしまう可能性が高くなります。

ダブル11と30日の夜10時にアリペイ紅包などのビジネスシーンを考えてみましょう。当然、これらの業務を同時に処理するには複数のサーバーが必要になります。これらのサービスは、同時に数百台のサーバーによって処理される可能性があります。

でも、よく考えてみてください。紅包配布ビジネスを扱うサーバーが 100 台あり、紅包が 1 億枚あり、1,000 万人がランダムな量で紅包を配布すると仮定すると、このビジネス シナリオでは、これらの 1,000 万人に配布される紅包の合計量が 1 億枚になるようにする必要がありますか?

うまく処理されず、全員が100万ドルを受け取ることになったら、ジャック・マーはおそらく旧正月の初日に破産を宣言しなければならないだろう。

1. 従来のロックを使用するとどうなるでしょうか?

まず最初に、クラスターを構築する必要がある理由についてお話しします。簡単に言えば、需要(同時リクエスト量)が増加し、1 人のワーカーの処理能力が限界に達したため、さらにワーカーを募集して一緒に処理するということです。

1000万件のリクエストが100台のサーバーに均等に分散され、各サーバーが10万件のリクエストを受信すると仮定します(これらの10万件のリクエストは同じ秒ではなく、1時間または2時間以内に到着する可能性があります。10月30日の夜に赤い封筒を開けるようなものと考えることができます。すぐに開ける人もいれば、12時まで待って思い出す人もいます〜)

この場合、1 秒あたりの平均リクエスト数は 1,000 未満であり、通常のサーバーはまだこの負荷に耐えることができます。

最初のリクエストが来たら、ランダムな金額で 1 億の一部を彼に渡す必要がありますか?最初の人が 100 を獲得したとすると、1 億から 100 を引いて、99,999,900 を残す必要がありますか?

2 番目のユーザーがお金を分配しに来ますが、金額はランダムです。今回彼は200元を受け取ります。ということは、残りの 99999900 元から 200 元を差し引いて、99999700 元を残す必要があるということですか?

100,000 人目のユーザーが来て、まだ 1,000,000,000 が残っていることがわかったら、その 1,000,000,000 すべてが彼のものになります。

これは、1 億を各サーバーに分割すること、つまり 10 万人のユーザーが 1 億を共有し、最終的に合計 100 台のサーバーが存在するため、100 億を分割する必要があることに相当します。

もしこれが本当なら、ジャック・マーは破産しないものの(最新の統計によると、ジャック・マーは2,300億人民元を保有している)、ボーナスを受け取る開発プロジェクトチームと製品マネージャーは破産する可能性がある。

簡略化された構造図は次のとおりです。

2. 分散ロックをどのように処理しますか?

したがって、この問題を解決するには、1,000 万人のユーザーが 100 億ではなく 1 億だけを共有できるようにします。このとき、分散ロックが役立ちます。

分散ロックはクラスター全体をアプリケーションとして扱うことができるため、ロックはサービス内ではなく各サービスから独立している必要があります。

最初のサーバーがユーザー 1 からのリクエストを受信した後、この時点では、独自のアプリケーションで配布可能な金額を決定するだけでは不十分で、1 億枚の紅包の管理を特に担当する人物 (サービス) に外部リクエストを送信して、「100 元欲しいので、100 元ください」と依頼する必要があります。

紅包(サービス)を担当する女の子は、まだ1億元あるのを見て、「わかりました。100元あげます。99,999,900元残ります」と言いました。

2番目のリクエストが到着した後、サーバー2で受信され、赤い封筒を管理する女の子に、10元を分けたいと引き続き尋ねます。紅包を管理する女の子が最初に確認し、まだ99999900枚あることがわかったので、「わかりました。10元あげます」と言いました。残りは99999890元です。

1000元のリクエストが到着すると、サーバー100がリクエストを受け取り、赤い封筒を管理している女の子に「100元欲しいですか?」と尋ね続けます。女の子は目を丸くして「あと1元しかありません。受け取るか受け取らないかはあなた次第です」と言います。現時点では、1元しかお渡しできません(1元もお金です。辛い一口麺を買うには十分です)。

これらのリクエスト番号 1 と 2 は実行順序を表すものではありません。正式なシナリオでは、100 台のサーバーがあり、各サーバーは、赤い封筒の管理を担当する女の子 (サービス) にアクセスするための要求を保持します。すると、紅包担当の女の子は同時に100件の依頼を受けることになります。このとき、赤い封筒を担当する女の子(ボールを投げる)にロックを追加するだけです。 100 人のサーバーのうちロックを獲得した (ボールを掴んだ) 人は誰でも入って来て私に話しかけることができます。私はあなたにポイントを与えます、そして他の人はただ待っていてください。

上記の分散ロック処理の後、ジャック・マーはようやく安心し、紅封筒チームのメンバー全員に鶏の脚を与えることにしました。

簡略化された構造図は次のとおりです。

3. 分散ロックの実装は何ですか?

分散ロックの実装に関しては、データベース メソッド、Redis 分散ロック、Zookeeper 分散ロックなど、まだ数多くあります。

分散ロックとして redis を使用する場合、上の図の「赤い封筒を担当する女の子 (サービス)」は redis に置き換えることができます。想像力を働かせてください。

3.1、Redis が分散ロックを実装できるのはなぜですか?

まず、Redis はシングルスレッドです。ここでのシングルスレッドとは、ネットワーク要求モジュールが 1 つのスレッドを使用する (したがって、同時実行の安全性を考慮する必要がない)、つまり、1 つのスレッドがすべてのネットワーク要求を処理し、他のモジュールは引き続き複数のスレッドを使用することを意味します。

実際の操作では、プロセスはおおよそ次のようになります。

サーバー 1 は、赤い封筒を送った少女、つまり Redis にアクセスしたいので、「setnx key value」操作を通じて Redis にキーを設定します。値が何であるかは問題ではありません。重要なのはキー、つまりマークを持つことであり、すべてのサーバーが同じキーを設定している限り、このキーを好きなように呼ぶことができます。

以下のように設定するとします。

すると、成功を意味する 1 が返されることがわかります。

次のように、同じキーを設定するための別のリクエストが届いた場合:

このとき、失敗を意味する 0 が返されます。

次に、この操作を使用して、現時点でロックを取得できるかどうか、または「赤い封筒を送る責任がある女の子」を訪問できるかどうかを判断できます。 1 が返された場合は、後続のロジックの実行を開始します。 0 が返された場合は、すでに誰かに占有されていることを意味するので、待機を継続する必要があります。

サーバー 1 はロックを取得した後、ビジネス処理を実行し、完了したら次の図に示すようにロックを解除する必要があります。

削除が成功すると 1 が返され、他のサーバーは上記の手順を繰り返してこのキーを設定し、ロックを取得する目的を達成できます。

もちろん、上記の操作は Redis クライアント上で直接実行されます。プログラムを通じて呼び出す場合、このように記述することは絶対にできません。たとえば、JavaはJedisを介して呼び出す必要がありますが、処理ロジック全体は基本的に同じです。

上記の方法により、分散ロックの問題は解決したようですが、他に何か問題があるか考えてみましょう。 ?

はい、まだ問題が残っています。デッドロックが発生する可能性があります。たとえば、サーバー 1 がセットアップされ、ロックを取得した後、突然クラッシュします。

その後のキー削除操作は実行できません。キーは常に Redis に存在します。他のサーバーがそれをチェックするたびに、0 が返されます。誰かがロックを使用していると判断され、待機する必要があります。

このデッドロック問題を解決するには、キーの有効期間を設定する必要があります。

設定方法は2通りあります

1. 最初の方法は、キーを設定した後に、キーの有効期間「有効期限切れキータイムアウト」を直接設定することです。キーのタイムアウトを秒単位で設定します。この時間が経過すると、デッドロックを回避するためにロックは自動的に解除されます。

この方法は、ロックの有効期間を制御のために Redis に渡すことと同じです。時間が経過してもキーを削除していない場合、Redis が直接キーを削除し、他のサーバーは引き続き setnx を使用してロックを取得できます。

2. 2 番目の方法は、他のサーバーにキーを削除する権限を与えることです。この場合、値が必要になります。

たとえば、サーバー 1 は値、つまりタイムアウトを現在の時刻 + 1 秒に設定します。この時点で、サーバー 2 は get を通じて、時刻が現在のシステム時刻を超えていることを検出します。これは、サーバー 1 がロックを解除していないことを意味し、サーバー 1 に問題がある可能性があります。

サーバー 2 は、delete キー操作の実行を開始し、setnx 操作の実行を継続します。

しかし、ここで問題があります。つまり、サーバー 2 がサーバー 1 のタイムアウトを検出するだけでなく、サーバー 3 でも検出される可能性があるということです。偶然、サーバー 2 の setnx 操作が完了し、次にサーバー 3 が削除された場合、サーバー 3 も正常に setnx できますか?

つまり、サーバー 2 とサーバー 3 の両方がロックを取得したことになりますが、これは大きな問題です。こういう時どうすればいいでしょうか?

このとき、「GETSET キー値」コマンドを使用する必要があります。このコマンドの意味は、現在のキーの値を取得し、新しい値を設定することです。

サーバー 2 がキーの有効期限が切れていることを検出し、getset コマンドの呼び出しを開始し、取得した時間を使用してキーの有効期限が切れているかどうかを判断します。取得した時間がまだ期限切れになっている場合は、ロックが取得されたことを意味します。

そうでない場合は、サービス 2 が getset を実行する前に、サーバー 3 もロックの有効期限が切れていることを検出し、サーバー 2 より前に getset 操作を実行して有効期限をリセットすることになります。

その後、サーバー 2 は後続の操作を中止し、サーバー 3 がロックを解除するか、キーの有効期間が経過したかどうかを監視し続ける必要があります。

実はここには小さな問題があります。サーバー 3 は有効期間を変更しました。ロックを取得した後、サーバー 2 も有効期間を変更しましたが、ロックを取得できませんでした。ただし、有効期間はサーバー 3 に基づいて延長されていますが、この影響は実際には非常に小さく、ほとんど無視できます。

3.2、Zookeeper が分散ロックを実装できるのはなぜですか?

Baidu Encyclopedia では次のように紹介しています: ZooKeeper は、分散型のオープンソース分散アプリケーション調整サービスです。これは、Google の Chubby のオープンソース実装であり、Hadoop と Hbase の重要なコンポーネントです。

ZooKeeper を初めて使う人にとっては、ZooKeeper がコンピュータのファイル システムのようなものだということがお分かりいただけると思います。ドライブ D にフォルダー a を作成し、フォルダー a にフォルダー a1 と a2 を続けて作成できます。

では、私たちのファイルシステムの特徴は何でしょうか? ?つまり、同じディレクトリ内でファイル名を繰り返すことはできません。これは ZooKeeper の場合も同様です。

ZooKeeper 内のすべてのノード、つまりフォルダーは Znode と呼ばれ、この Znode ノードにデータを保存できます。

「create /zkjjj nice」でノードを作成できます。このコマンドは、ルート ディレクトリに nice という値を持つ zkjjj ノードを作成することを意味します。ここでの値は、先ほど説明した redis の値と同じです。意味はありませんので、好きなものをあげてください。

さらに、ZooKeeper は次の 4 種類のノードを作成できます。

1. 永続ノード

2. 永続的なシーケンシャルノード

3. 一時ノード

4. 一時的な連続ノード

まず、永続ノードと一時ノードの違いについて説明します。永続ノードとは、このノードを作成すると、ZooKeeper クライアントが切断されているかどうかに関係なく、ZooKeeper サーバーがこのノードを記録することを意味します。

一時ノードの場合はその逆になります。 ZooKeeper クライアントが切断されると、ZooKeeper サーバーはノードを保存しなくなります。

シーケンシャルノードについてお話しましょう。連続ノードとは、ノードを作成するときに、ZooKeeper がノードに 0000001、0000002 などの番号を自動的に付けることを意味します。

最後に、Zookeeper には監視メカニズムがあります。クライアントは、関心のあるディレクトリ ノードを監視するために登録します。ディレクトリ ノードが変更されると (データの変更、削除、サブディレクトリ ノードの追加または削除)、Zookeeper はクライアントに通知します。

次に、上記の配当分配シナリオに基づいて、Zookeeper をロックインする方法について説明します。

サーバー 1 がノード /zkjjj を正常に作成し、サーバー 1 がロックを取得したとします。サーバー 2 が同じロックを再度作成しようとすると、失敗します。現時点では、このノードの変更のみを監視できます。

サーバー 1 が業務を処理してノードを削除した後、通知を受け取り、同じノードを作成し、ロックを取得して業務を処理し、ノードを削除します。後続の 100 台のサーバーも同様です。

ここで、100 台のサーバーは上記のノード作成操作を 1 つずつ実行するのではなく、同時に実行することに注意してください。サーバー 1 が正常に作成されると、残りの 99 台がこのノードをリッスンするように登録し、通知を待機するなどします。

しかし、ここでまだ問題があり、行き詰まりが続くことにお気づきでしょうか?

サーバー 1 がノードの作成後にクラッシュし、削除に失敗すると、他の 99 台のサーバーは通知を待機し続け、それで終わりになります。 。 。

このとき、一時ノードを使用する必要があります。前に述べたように、一時ノードの特性は、クライアントが切断されると、つまりサーバー 1 がノードを作成してハングアップすると、一時ノードが失われることです。

その後、このノードは自動的に削除され、後続のサーバーが引き続きノードを作成し、ロックを取得できるようになります。

しかし、ショック効果という点にも注意を払う必要があるかもしれません。非常に単純な例を挙げると、ハトの群れに食べ物を投げると、最終的に食べ物をつかむのは 1 羽のハトだけであっても、すべてのハトが驚いて食べ物を奪い合い、つかみ損ねたハトは...

つまり、サーバー 1 ノードに変更があった場合、残りの 99 台のサーバーに通知されますが、最終的に正常に作成されるのは 1 台のサーバーのみなので、98 台はまだ監視を待つ必要があります。この状況に対処するには、一時的なシーケンシャル ノードが必要です。

一般的な意味は、以前は 99 台のサーバーすべてが 1 つのノードをリッスンしていましたが、現在は各サーバーがその前にあるノードをリッスンするということです。

100 台のサーバーが同時にリクエストを送信すると仮定すると、/zkjjj ノードの下に、/zkjjj/000000001、/zkjjj/000000002、そして /zkjjj/000000100 までの 100 個の一時的な連続ノードが作成されます。この数値は、ロックを取得する順序を設定することと同じです。

ノード 001 が処理されて削除されると、002 は通知を受け取り、ロックを取得して実行を開始し、実行が完了したらノードを削除して 003 に通知する、というように動作します。

<<:  ガートナーは、分散クラウドを含むインフラストラクチャと運用に影響を与える6つのトレンドを明らかにしました。

>>:  ハイブリッドクラウドの総コストを計算する方法

推薦する

初心者でも2か月で武漢SEOをトップページに送ることができる

なぜ私は初心者だと言うのでしょうか? 2 か月以上前は、SEO が何なのかさえ知りませんでした。しか...

YYミュージックの収益モデルは論争を巻き起こし、音楽著作権を侵害している疑いで問われた。

昨年の立ち上げ直後には5000万元以上の利益を上げ、今年上半期の売上高は1億元近くに達した。YY M...

LoveBucks 中小規模のウェブサイト所有者は、ユーザーの人気度に応じて収益を得ることができます

オンライン コンテンツで収益を上げるのは簡単なことではありません。特に、ユーザー数が少ない出版社やブ...

簡単な分析: 店舗デザインにおけるビジュアルマーケティング戦略

インターネットでは、顧客は主にストアページの表示と自身の想像力によって商品や店舗を理解し、最終的に注...

P2P 破産の波: 半数が危機に瀕しており、今年中に 100 社が破産する可能性あり

4月28日、百度は800以上のP2Pプラットフォームを閉鎖した。アナリストらは、P2P業界は初期段階...

無料のウェブサイト構築システム、オープンソース化されたばかりのCMSをお勧めします!

10年以上の歴史を持ち、広く知られているこのCMSシステムは、最近、オープンソース化を発表し、新しい...

ニュースウェブサイトのトラフィックを増やすにはどうすればいいですか?インタラクションを試す

はじめに:ニュースはもはや伝統的なニュースメディアやポータルサイトによって支配されていません。ネット...

金融グレードのプロフェッショナル クラウド サービスである Ping An Cloud は、保険業界が安心してクラウドに移行できるよう支援します。

【平安クラウド金融業界ソリューション】 [51CTO.comからのオリジナル記事] 保険業界は伝統的...

Ceph の運用とメンテナンスで分散ストレージの「落とし穴」を知る

過去 2 年間、私の主な仕事は Hadoop テクノロジー スタックでしたが、最近 Ceph に触れ...

クラウド移行時に企業が注意すべき問題は何ですか?

インターネット技術の継続的な発展に伴い、クラウド コンピューティングやその他の関連技術を導入する企業...

完全に自律かつ制御可能!国内初のフルリンクOS OpenCloudOSリリースソースコミュニティプロジェクト

6月22日、2022 OpenCloudOSコミュニティオープンデーで、国産オープンソースオペレーテ...

#干货# vpckr: 韓国の広帯域 VPS、中国への直接接続、高速、無制限のトラフィック

新興企業のvpckrは、主に韓国のVPS(SK\KT\LGデータセンター)を運営しており、帯域幅が大...

BandwagonHost: 新しいドバイ VPS、1Gbps 帯域幅、月額 19.99 ドルから、12 のデータセンター間の転送無料

Bandwagonhostは、デフォルトのアクセス帯域幅が1Gbpsである「DUBAI-ECOMME...

Baidu の外部リンク取り締まり方針に対応して質の高い外部リンクを作成する方法

最近、百度は外部リンクの取り締まりを強めており、筆者も危機感を抱いている。どうすれば、Baiduの外...

4か月間降格されたサイトの記事を通常の状態に戻す方法

今日は木曜日、寝る前に、多くのウェブマスターと同じようにウェブサイトの状態を確認しました! 私のウェ...