クロイスター → シンプルな OTP クラスター管理

成功しているほとんどすべてのビジネス アプリケーションは、遅かれ早かれ、水平方向のスケーリングが必要なフェーズに入ります。 多くの場合、新しいインスタンスを開始するだけで負荷平均を減らすことができます。 ただし、異なるノードが互いのことを認識していることを確認し、ワークロードを慎重に分散する必要がある、それほど簡単ではないケースもあります。

クロイスター → シンプルな OTP クラスター管理

それはとても幸運だった アーランは、その快適な構文とそれに関する誇大宣伝のために私たちが選択したもので、最高級の機能を備えています。 分散システムのサポート。 理論的には、これはまったく簡単なことのように思えます。

異なるノード上のプロセス間、およびリンクとモニター間で受け渡されるメッセージは透過的です […]

実際には、すべてがもう少し複雑です。 分散型 アーラン 「コンテナ」が輸送用の大きな鉄の箱を意味し、「港湾労働者」が単に沿岸労働者の同義語であったときに開発されました。 で IP4 多くの空きアドレスがあり、ネットワークの切断は通常、ネズミがケーブルをかじることによって引き起こされ、実稼働システムの平均稼働時間は数十年単位で測定されました。

今では私たちは皆、信じられないほど自給自足し、パッケージ化され、分散して実行されています。 アーラン 動的 IP アドレスが非常にランダムな原理に基づいて配布され、スケジューラの左端の気まぐれにノードが現れたり消えたりする環境では。 分散システムを実行するすべてのプロジェクトで定型コードの山を回避するには アーラン、敵対的な環境と戦うためには、助けが必要です。

注意:あることは承知しております。 libcluster。 本当にクールで、星が XNUMX 個以上あり、作者はコミュニティ内で有名です。 このパッケージが提供するクラスターの作成と保守の方法で十分であれば、幸いです。 残念ながら、さらに多くのことが必要です。 私はクラスター再編の劇場の傍観者ではなく、セットアップを詳細に制御したいと考えています。

必要条件

私が個人的に必要としていたのは、クラスターの管理を引き継ぎ、次のプロパティを持つライブラリでした。

  • ハードコーディングされたノードのリストとサービスを介した動的な検出の両方を使用した透過的な動作 アーラン;
  • すべてのトポロジ変更 (あそこのノード、ここのノード、ネットワークの不安定性、分割) に対する完全に機能するコールバック。
  • のように、長い名前と短い名前でクラスターを起動するための透過的なインターフェイス :nonode@nohost;
  • インフラストラクチャ コードを記述する必要がなく、すぐに使える Docker サポート。

後者は、アプリケーションをローカルでテストした後、 :nonode@nohost、または、を使用して人工的に分散された環境で test_cluster_task、ただ走りたいだけです docker-compose up --scale my_app=3 コードを変更せずに、Docker で XNUMX つのインスタンスをどのように実行するかを確認してください。 次のような依存アプリケーションも必要です mnesia - トポロジが変更されると、アプリケーションからの追加のキックなしで、舞台裏でクラスターがライブで再構築されます。

回廊 は、クラスターのサポートからコーヒーの作成まであらゆる機能を備えたライブラリを意図したものではありませんでした。 これは、考えられるすべてのケースをカバーすることを目的とした特効薬ではなく、また、世界の理論家が考えているような学術的に完全な解決策でもありません。 CS この用語に入れます。 このライブラリは、非常に明確な目的を果たすように設計されていますが、大きすぎない機能を完璧に実行します。 この目標は、ローカル開発環境と、敵対的なコンテナでいっぱいの分散弾性環境との間に完全な透明性を提供することです。

選択されたアプローチ

回廊 はアプリケーションとして実行することを目的としていますが、上級ユーザーは直接実行してクラスターのアセンブリとメンテナンスを手動で行うことができます。 Cloister.Manager ターゲット アプリケーションのスーパーバイザ ツリー内。

アプリケーションとして実行する場合、ライブラリは以下に依存します。 config、そこから次の基本的な値を読み取ります。

config :cloister,
  otp_app: :my_app,
  sentry: :"cloister.local", # or ~w|n1@foo n2@bar|a
  consensus: 3,              # number of nodes to consider
                             #    the cluster is up
  listener: MyApp.Listener   # listener to be called when
                             #    the ring has changed

上記のパラメータは文字通り次のことを意味します。 回廊 OTPアプリケーションに使用されます :my_app、使用します アーランサービスの検出 ノードを少なくとも XNUMX つ接続し、 MyApp.Listener モジュール(実装 @behaviour Cloister.Listener) は、トポロジの変更に関する通知を受信するように構成されています。 完全な構成の詳細な説明は、次の場所にあります。 ドキュメンテーション.

この構成では、アプリケーションは 回廊 意志 段階的に起動する、コンセンサスに達するまでメイン アプリケーションの起動プロセスを遅らせます (上記の例のように、XNUMX つのノードが接続されて接続されています)。これにより、メイン アプリケーションは、起動時にクラスターがすでに使用可能であると想定する機会が得られます。 トポロジが変更されるたびに (ノードは完全に同期して開始しないため、変更の回数は多くなります)、ハンドラーが呼び出されます。 MyApp.Listener.on_state_change/2。 ほとんどの場合、ステータス メッセージを受信したときにアクションを実行します。 %Cloister.Monitor{status: :up}これは、「こんにちは、クラスターが組み立てられました。」を意味します。

ほとんどの場合、インストールは consensus: 3 より多くのノードが接続されることが予想される場合でも、コールバックは通過するため、最適です。 status: :rehashingstatus: :up 新しく追加または削除されたノード上で。

開発モードで開始する場合は、次のように設定するだけです。 consensus: 1 и 回廊 クラスタの組み立てを待つ必要はありません。 :nonode@nohostまたは :node@hostまたは :[email protected] - ノードの構成方法に応じて (:none | :shortnames | :longnames).

分散アプリケーション管理

単独ではない分散アプリケーションには通常、次のような分散依存関係が含まれます。 mnesia。 同じコールバックから再構成を処理するのは簡単です on_state_change/2。 たとえば、再構成方法の詳細な説明は次のとおりです。 mnesia その場で ドキュメンテーション 回廊.

使用する主な利点 回廊 トポロジの変更後にクラスターを再構築するために必要なすべての操作を実行するということです。 フードの下。 アプリケーションは、IP アドレス、つまりノード名が事前にわかっているか、動的に割り当て/変更されているかに関係なく、すべてのノードが接続された、すでに準備された分散環境で実行されます。 これには特別な Docker 構成設定はまったく必要なく、アプリケーション開発者の観点からは、分散環境での実行とローカル環境での実行に違いはありません。 :nonode@nohost。 これについて詳しくは、 ドキュメンテーション.

トポロジ変更の複雑な処理はカスタム実装を通じて可能ですが、 MyApp.Listener、これらのライブラリの制限と構成のバイアスが実装の基礎となる特殊なケースが常に存在する可能性があります。 大丈夫です、上記を理解してください libclusterこれはより汎用的なものであり、低レベルのクラスターを自分で処理することもできます。 このコード ライブラリの目標は、考えられるすべてのシナリオをカバーすることではなく、最も一般的なシナリオを不必要な労力や面倒なコピー&ペーストなしで使用できるようにすることです。

注意: オリジナルではこの時点で「クラスタリングを成功させてください!」というフレーズがありましたが、私が翻訳に使用した Yandex は (辞書を自分で調べる必要はありません)、「クラスタリングを成功させてください!」というオプションを提供してくれました。 特に現在の地政学的状況を考慮すると、これ以上に優れた翻訳を想像することはおそらく不可能でしょう。

出所: habr.com

コメントを追加します