ChubbyGoのセキュリティデモンストレーションと展望

前書き

この記事では、主にChubbyGoの現在の機能で発生する問題のいくつかと、最適化を継続できると思ういくつかの領域について説明します。

実際、ChubbyGoの実装をもう一度確認したところ、変更可能なバグとGoのRPCフレームワークによって引き起こされる不便を除いて、すべてのセキュリティ問題が時間から発生していることに驚きました。これは不合理です。そして予想外のこと。ランポートの考えの影響を受けて、分散環境では時間が非常に難しい問題であることはわかっていましたが、結局のところ、以前はコードレベルに深く入り込むことはなく、この問題についての理解はまだ表面化しています。ChubbyGoが最初に完了した後、分散サービスにどのくらいの時間が影響するかを確認するために、以前よりも深いレベルで検討することができます。

この記事では、最初にChubbyGoで遭遇した2つの実際の例からセキュリティを示し、次にZooKeeperからいくつかのインスピレーションを与えます。

安全性

タイムアウトパラメータを取得する

ChubbyGoは分散ロックサービスを実装しています。異なるクライアントは異なるマシンから来ています。明らかに、クライアントの動作はサーバーでは制御できません。つまり、より堅牢にするために、ロック操作にはタイムアウトパラメータが必要であり、ロックを保持しているクライアントがダウンした後、他のクライアントがロックを取得できないようにする必要があります。これは理解しやすく、問題の鍵は時間です。どうして?写真を見てみましょう:
ここに画像の説明を挿入

  1. クライアントがリクエストを送信するための参照時間は0Sであると仮定します。
  2. クライアントはロック要求を送信し、要求されたロックタイムアウト期間は2Sです。
  3. リーダーがリクエストを受信した直後にリクエストを処理すると仮定すると、ロックは2秒後に解放されます。つまり、ロック解除時間は2 + xです。
  4. リーダーがデータを受信して​​から、リーダーからクライアントへのデータパケットの遅延(y)にロックを実行するまでの時間を追加します。明らかに、yは0より大きいです。
  5. クライアントがパケットを受信して​​ロックを実行すると、クライアントとリーダーのクロックの間に非同期の度合いが導入されます。これを度と呼び、クライアントがパケットを処理してからロックまでの時間をzと呼びます。
  6. つまり、クライアントがロックを解除してロックを解除する時間は2 + x + y +度+ zです。

クライアントのロック解除時間がサーバーのロック解除時間より遅れていることがはっきりとわかります。この時間の違いは(y +度+ z)ですが、最も深刻な問題の1つは、程度が不確かであるかどうかです。リーダーのクロックが速いか、クライアントのクロックが速い、つまり(y +度+ z)である可能性があるため、正または負を判断できません。つまり、2人のクライアントが同時にいる可能性があります。自分はロックを保持していると考えてください。現在の解決策は、リーダーの実際のスリープ時間がTimeOutの2倍であるため、この問題を最大限に回避できます。もちろん、理論的にはまだ間違っていますが、エンジニアリングの観点からは、実際にはほとんどのスリープ時間を回避しています。問題。

この問題は、タイムアウト期間が経過した後もクライアントがロックを保持しているという問題を実際に説明していることがわかります。上記の状況を引き起こす可能性のある別の状況があります。つまり、クライアントプログラムが長いGCまたはプログラム優先度を通過した可能性があります。レベルは非常に低く、OSスケジューラによって時間どおりにスケジュールされていません。これは、多くのブログで説明されている状況でもあります。ChubbyのようにKeepaliveを使用する代わりに、ついにTokenメカニズムを使用してこの問題を解決しました。興味のある友人は分散ロック:セキュリティとパフォーマンスの選択のセクション2.2の最後にあるトークンメカニズムの簡単な説明を確認できます。

CheckSeqインターフェース

CheckSeqは、トークンメカニズムの導入後に他のサーバーがトークンを検出できるように導入されたインターフェースです。次に、他のサーバーがリクエストを正しく処理する場合、ChubbyGoは安全であると説明します。最初に画像を見てみましょう。
ここに画像の説明を挿入

Leaderがサーバー、次のOtherServerがトークンを検出する必要のあるリソースサーバー、残りの2つが異なるクライアントであると想定します。ステップバイステップで見ていきましょう。

  1. ClientAがロックを要求し、Tokenの値は2です。
  2. ClientAは、このトークンを使用してリソースを要求します。
  3. このリクエストを受信した後、OtherServerはCheckTokenリクエストをChubbyGo Leaderに送信します。パラメーターはClientAから受信したトークンであり、値は2です。
  4. リーダーは、CheckSeqを受信したときにトークンが現在最新であることを確認し、OtherServerにOKを返します。ただし、ClientAが保持するロックは、データパケットが途中で実行されるとタイムアウトします。ChubbyGoとクライアントが保持するロックは、同時に(少なくともサーバーの有効期限が切れた後)期限切れになると想定しています。これは、実際には、前のセクション。つまり、OtherServerがOKを受信すると、Token3を使用したClientBの要求が到着した可能性がありますが、ClientAはロックを保持していないことをすでに知っているため、OtherServerはOKを受信しますが、ClientAにリソースを割り当てます。 ClientA。
  5. ClientBのリクエストが到着しました。このとき、OtherServerは上記のプロセスを続行します。もちろん、上記の極端な条件が発生しなければ、リソースのリクエストは成功します。

もちろん、リソースがChubbyGoに存在する場合、これらのことは起こりません。各リクエストのトークンを直接チェックすることは問題ありません。

見通し

FIFOクライアントの順序与逐次一貫性

ChubbyGoは、Chubbyのような線形の一貫性を提供します。つまり、すべての顧客に対して、Get操作の前に発生したすべての操作を確認できます。つまり、グローバルイベントは線形として理解でき、リーダー以外のすべてのサービスは次の役割のみを果たします。データの冗長性:明らかに、これは比較的大きなリソースの浪費です。少なくともN / 2フォロワーサーバーとリーダーが同じログを持っているためです(基盤となる整合性プロトコルはRaftによって実装されています)が、それらは機能していません。

現時点では、実際に質問を検討する必要があります。つまり、顧客はこれほど強力な一貫性を必要としているのでしょうか。ChubbyGoのロックサービスが提供する仮想ファイルツリーを例にとると、顧客は自分のロック以外のファイルのデータをほとんど気にしないことは明らかです。このように、クライアントは自身のパースペクティブの一貫性のみを気にする必要があるため、FIFOは本当に非常に適切な一貫性です。ZooKeeperはzxidを使用してFIFOを実装します。もちろん、これにも問題があります。現時点では、Zookeeperはグローバルな整合性を実現できないようです。実際、Syncの役割であるZookeeperアーキテクチャを実現することは難しくありません。もちろん、私にとっては、ZooKeeperが取得する可能性があるのは、特別な書き込み操作としてよりエレガントだと思います。

そのため、ChubbyGoは後の段階でFIFOクライアントの順序の一貫性を導入することができます。これを実現するのは難しくありません。各操作にzxidを導入するだけで問題ありません。少なくとも今のところはこのように見えます。おそらく、サポートすることもできます。将来的にフォロワーからデータを読み取る。

改善の詳細については、Chubbyのドキュメントに記載しています。セクション3.3を参照してください。

総括する

ChubbyGoはアーキテクチャの点で際立っていないため、これらの考えの後で結論を出すのは実際にはイライラします。逆に、ZooKeeperのアーキテクチャはより簡潔で効率的であり、ユーザーにより多くの可能性を提供します。ただし、Redisと比較すると、ChubbyGoにはまだいくつかの利点があります。たとえば、ChubbyGoには、Redisが複数のクライアントにロックを保持させるための分散ロックとして使用するデータ損失がなく、より多くの機能があります。

おすすめ

転載: blog.csdn.net/weixin_43705457/article/details/109458119