背景
if(userId == 123){do something}
いくつかの簡単な学習プロジェクトを行うのごく初期には、このようなデータベース接続プールのサイズ、ユーザーのブラックリストなど、物事を設定するいくつかの必要性に遭遇するでしょう、これらのことは、死者の内部のコードに書かれているような、プロジェクト内のこのコードはどこでも見ることができます。その後、私は仕事に参加し、この書き込み方法は、構成の良い統一管理されていないことがわかった、どこでも場所の構成は、オンラインとオフラインなどのコード環境に応じて調整することはできませんが、唯一の同じ構成で使用することができますが、もし、他の方法が、これは非常に面倒なので、xml、yamlの使用に関する作業では、他の方法は、内部のファイルを構成するために、異なるオペレーティング環境では、異なる設定ファイルを読み込むことができます。異なるオペレーティング環境では、異なる設定を読み取るために。このアプローチは、基本的に後のほとんどのニーズを満たす動的にこれらの設定を変更する必要が発生した場合、ファイルを介しての方法は、唯一のファイルを変更し、サービスを再起動することができます、非常に面倒なので、設定センターの誕生です。
ここで、コンフィギュレーションセンターを実現したい場合、どのような機能が必要かを考えてみましょう。いくつか挙げてみます:
- コンフィギュレーションを動的に変更できます。
- コンフィギュレーションセンターは、コンフィギュレーションに影響を与えることなくハングします。
- 複数のサービスでコンフィグレーションを共有できます。
- 権限管理をサポートし、権限を与えられた人だけがコンフィギュレーションを閲覧・変更できます。
- 設定をロールバックすることができます , 構成の問題が発生したときに設定をロールバックするサービスのようにロールバックすることができます .
- グレースケールリリースは、最初にいくつかのマシンは、完全な量で、問題がない場合は、設定を使用できるようにすることができます。
- コンフィギュレーションセンターQPSは、それが会社の基本的なサービスを確保するために必要な場合は、十分に保証することができます。
実際、オープンソースのプロジェクトでは、春の雲の設定、アポロなどのオープンソースの設定センターがかなり多く、アポロはCtripオープンソースの設定センターは、業界でも非常に有名ですが、この記事では、主にNacosの設定センターを紹介し、もちろん、興味のある学生は、他の登録センターの紹介に関連する参照してくださいダウンすることができます。
基本コンセプト
同様に、まず第一に、我々はまた、いくつかの基本的な用語やレジストリに関連する概念を紹介します:
- 名前空間:レジストリと同様に、名前空間はNacosのトップレベル構造に属し、テナントレベルの分離に使用されます。最も一般的には、テスト環境やオンライン環境などの異なる環境を分離するために使用されます。
- コンフィギュレーション管理:編集、保存、配布、変更管理、履歴バージョン管理、変更監査、その他コンフィギュレーションに関連するすべての活動。
- 設定項目:特定の設定可能なパラメータとその値フィールドで、通常はparam-key=param-valueの形式。例えば、頻繁に構成されるシステムのログ出力レベルは構成項目です。
- 設定セット:関連または無関係の設定項目の集合を設定セットと呼びます。システムにおいて、設定ファイルは通常、システム設定のすべての側面を含む設定セットです。例えば、構成セットには、データソース、スレッドプール、ログレベルなどの構成項目が含まれます。
- コンフィギュレーションセットID : NacosにおけるコンフィギュレーションセットのID。コンフィギュレーションセットIDは、組織がコンフィギュレーションを分割する次元の一つ。
- コンフィギュレーション・グルーピング(Configuration Grouping) : Nacosにおけるコンフィギュレーション・セットの集合。
- コンフィギュレーション・スナップショット:NacosクライアントSDKは、コンフィギュレーションのスナップショットをローカルに生成します。クライアントがNacosサーバーに接続できない場合、コンフィギュレーションスナップショットを使用してシステム全体の災害耐性を表示することができます。設定スナップショットはGitのローカルコミットに似ており、適切なタイミングで更新されるキャッシュにも似ていますが、キャッシュの有効期限という概念はありません。
設定センターのアーキテクチャを以下に示します:
- ユーザはバックエンドのインターフェイスでコンフィギュレーションを追加・変更できます。
- 変更されたデータはすべて、まずLeaderで筏を通して変更され、その後他のレプリカに同期されます。
- ユーザが設定を購読したい場合は、ロングポーリングによって購読することができます。
一貫性のあるストレージ
構成センターは、最も重要なストレージの良い仕事をする方法ですが、2つの方法で、一般的なストレージは、いずれかのフルメモリストレージは、非常に高いパフォーマンスを確保することができますが、異なるマシンのメモリの複雑さの一貫性を維持することは比較的高いですが、もう一つは、データベースを使用することです、メモリは、任意の状態を維持しない、各マシンは、操作に書き込むことができます、複雑さは比較的低い、問題の一貫性を考慮する必要はありませんが、原因です。すべての読み取りと書き込みは、データベースに行くので、パフォーマンスが保証されていません。Nacosではこれらの2つの方法で、ストレージ内のいくつかの改善を行うには、パフォーマンスと複雑さの両方を達成するために一貫性を確保するために。
Nacos1.3では、mysqlとraft + derbyの2つのストレージ方式を提供した後、次の導入では、これらの2つのストレージ方式を1つずつ紹介します。
mysql + 非同期完全通知
Nacosが提供し始めたのはmysql方式で、すべてのマシンが読み書きでき、マスターとバックアップはなく、次の図のようになります:
あなただけのmysqlを使用する場合は、一部の学生は、唯一のデータベースのパフォーマンスがボトルネックになることはありませんどのように確保するためにmysqlを使用して、質問をするでしょうか?最も簡単な方法は、Mysqlの高い構成を使用することです、私にお金が干上がるように、それは、これは非常に信頼性の高いものではないことは明らかである、唯一のtycoonプレーヤーに適用されます。次に、どのようにこの最適化を行うには?一般的なビジネス学生は通常、そのようなredis、memcachedなどのMysqlの前にキャッシュの層を置きます。
Nacosでも、データベースへの負担を軽減するために、同じコンセプトのキャッシュが使われています。ConfigServiceの中にHashMapがあり、コンフィグ用のメタデータをすべてキャッシュしています。
しかし、ストレージの特定の値については、メモリに直接配置されませんが、ローカルディスクに格納され、そうすることの利点は、コンフィグの設定値が彼のサイズを保証することはできませんので、各コンフィグの値が非常に大きい場合は、メモリが必然的に不足することになり、この時間Nacosとアポロ2つのオープンソースのミドルウェアは、2つのソリューションを提供します:
- Apolloのアプローチは、guavaCacheを使用することです、消去ポリシーを使用すると、消去のために使用される頻度が低くなります。
- Nacosのアプローチは、メタデータの完全な量をキャッシュすることです、特定の値は、ストレージの分離を使用して、ディスクスペースに格納され、nacosは、このアプローチを使用して、メタデータへのアクセスだけであれば、メモリの完全な量をすることができます、アポロのようになることはありませんデータベースにアクセスする理由の除去に遭遇する可能性があります。
Dump
Nacosは、メモリへのキャッシュメタデータの完全な量を使用して、特定の値は、ディスク領域に格納されていますが、マシンのデータが変更されると、どのように他のマシンのメモリを変更するには、問題が発生しますか?これは、データの各変更で、完全な非同期通知が必要ですConfigDataChageイベントを送信し、ローカルマシンが受け入れ、処理し、他のすべてのマシンにこの変更メッセージを送信します。
他のマシンは、この変更通知を受信すると、ダンプ操作を実行します。
最初にメタデータのMD5を照会します。MD5は実際にコンフィギュレーションの値に基づいて計算されるので、いつ値が変更されたかを素早く判断することができ、変更されていればその値がディスクに保存されます。
マシンが新しいスタートである場合、実際には、この時間は、任意のキャッシュだけでなく、ダンプファイルが存在しないことになり、DumpServiceは、データベース内のすべてのデータ、使用するためにマシンにキャッシュされているすべての完全な量を横断します。
raft + derby
1.3.0以降のNacosでは、データの一貫性を保証するためにraftプロトコルを使用し、組み込みデータストレージにapache derbyを使用するという新しいストレージモデルを提供しています。このアプローチを提供する目的は、ユーザーがmysqlデータベースクラスタを維持するためのコストを削減し、クラスタ展開のコストを簡素化することです。
sofa-jraftの使用中のNacosは、これは高性能のいかだの実装の蟻のオープンソースのJavaバージョンですが、いかだの学生に精通していないいかだの学生はいかだを理解するために、論文の次のいかだを読むことができますいかだは非常に多くのリーダーの概念を強化していることを知っている必要があります:
- リーダーだけがクライアントからの要求を受け入れることができます。
- リーダーは、すべてのフォロワーと積極的にコミュニケーションをとり、すべてのフォロワーに「提案」を送り、大多数のフォロワーからの回答を集める責任があります。
- リーダーはまた、リーダーシップを維持するために、すべてのフォロワーにハートビートを送信します。
すべてがリーダーに関係するため、性能はリーダーに限定されなければならないことがわかりました。そこでNacosでは、ドラフト自体の最適化が多いsofa-jraftを選択し、sofa-jraftで以下の最適化を行いました:
バッチ処理: バッチ処理は多くのシステムの最適化戦略です。jraftでもdisruptorのバッチ消費モデルMPSCにより、以下のバッチ処理の一部をバッチ処理で実現し、性能を大幅に向上させています:
- 一括投稿 task
- バッチネットワーク送信
- ローカル IO バッチライト
- ステートマシンへのバッチアプリケーション
パイプラインレプリケーション:パイプラインは、もはや古い要求応答モデルと同じように助けるためにパイプライン技術であり、彼はパイプラインに要求を入れて続けることができる、プロセスは、要求を返信するために待機する必要はありませんし、結果の最後に一緒に読み取ることができます。パイプラインのパフォーマンスが30%向上します。
並列化: リーダーはログを永続化し、並列にフォロワーに送信し、異なるフォロワーに並列に送信します。
リニアリード:ラフトプロトコルでは、リードリクエストはログに従って処理され、ログの複製とステートマシンの実行を経てリード結果を取得し、その結果をクライアントに返します。このアプローチの欠点は、ログの保存、複製が必要なことで、スワイプオーバーヘッド、ストレージオーバーヘッド、ネットワークオーバーヘッドが発生します。SofajratのReadIndexでは、すべての読み取りをローカルで実行できるように、読み取りを最適化し、これは特に大きなパフォーマンスの向上です。
Apache Derbyはまた、Javaで書かれた軽量データベースですが、この設計を通じてNacosは、実際に軽量分散データベースを構築している、各マシンでデータを保存するデータベースを持っているし、すべてのマシン間のデータの一貫性を確保するためにいかだプロトコルを介して 。
組み込みデータベースは、パフォーマンスの面でMysqlの方法よりも優れていないキャッシュの多くは、コンテンツがディスクに保存されているため、基本的なライブラリは、Mysqlの方法が実際に優れているので、行くことはありませんが、運用と方法の展開のメンテナンスで埋め込まれたデータベースの方法は非常に有利です。ここではどのようにトレードオフにユーザー自身のための選択を行う必要があります!
クライアントサブスクリプションの変更
前節では、Nacosレジストリのサブスクリプションは、udpブロードキャスト+時限訓練を通じて取得され、一方、設定センターでは、サブスクリプションの変更は、ロングローテーションの方法で行われると述べましたが、なぜサブスクリプションのこれらの2つの実装は、それを達成するために異なる方法で実装されるのでしょうか?登録センターに格納されているデータは、ノードのIp、ポートおよびその他の情報のような小さなデータですが、設定センターでは、設定のサイズを制御することはできません、このような100の設定にサブスクライブサービスとして、1Mのデータサイズの各構成は、もし定時訓練の練習は、毎回100Mのデータを引っ張るだろう、それは明らかに信頼できないので、ここで訓練のアプローチの長い回転の使用は、訓練の特定の長い回転の方法は次のとおりです。方法は次のとおりです:
- Step1:クライアントが長いトレーニング要求を発行し、タイムアウト時間のデフォルトは30秒です。要求は、すべてのサブスクリプション構成のコンテンツのMD5に発行され、コンテンツ全体が要求として発行されません、そうでない場合は、データの多くは、上記のように毎回発行されます。
- ステップ2:サーバーは、Servlet3.0の機能を使用して、この要求を受信し、非同期のAsyncContextを開きます。
- ステップ3:このAsyncContextのサーバー側のストレージは、設定の変更を待って、データの変更は、DataChangeEventイベントによってトリガされ、要求のmd5と新しい更新されたmd5が同じであるかどうかを判断し、同じ場合は、AsyncContextの応答に変更情報を書き込むように変更されます。
- ステップ4:タイムアウトがまだ来ていない場合は、今回更新する設定がないことを意味し、再びステップ1に戻ります。
こうすることで、毎回のリクエスト量は非常に少なくなり、本当にデータが更新されたときだけ、本当のデータが返されるようになります。
設定のグレーイング
あるコンフィギュレーションが業務に影響を与えるかどうかを検証する必要がある場合があります。 通常はコンフィギュレーションセンターを直接変更し、全マシンのフルボリュームを更新し、このコンフィギュレーションに問題があればフルボリュームがダウンします。Nacosにはグレースケール機能があり、一部のマシンにのみ特定のコンフィグレーションを与えることで、小規模なトラフィック検証を行うことができます。
Nacosのグレーリリースは、下図のようにベータリリースとも呼ばれています:
nacosでの具体的な実装は、ベータ関連の情報を保存するために別のテーブルを使用することです:
β_ipsフィールドでグレーアウトが必要なマシンを保存し、クライアントがロングローテーションを購読する際に、それがグレーアウトされたマシンかどうかをフィルタリングし、もしそうであれば、そのマシンだけが更新されます:
履歴のロールバック
Nacosでは、コミットIDさえあれば対応するバージョンにロールバックできる、gitのコミットに似た履歴バージョンも提供しています。
まとめ
Nacosには他にも権限管理など多くの機能がありますが、ここでは紹介しません。最も巧妙に設計されたNacosの設定センターでは、ストレージとサブスクリプションですが、ストレージNacosは2つのモードを提供し、1つはMysql +キャッシュ+このディスクの方法ですが、もう一つは、ドラフト+ダービーの方法を介している、独自の長所と短所を持っています。サブスクリプションの言葉Nacosは、トレーニングの長いラウンドを介して、完全に異なる方法を使用し、レジストリは、更新のリアルタイム通知のための良いソリューションであり、リソースの要求数が多い必要はありません。あなたがNacosに興味があるなら、我々はNacosのコードを読むことをお勧めします。