複数のクライアントにサービスを提供できる場合、このサービスを提供するサーバーがダウンした場合、別のサーバーがその代わりになります。メインサーバーがダウンしたかどうかを検出し、クライアントを新しいサーバー?
一元化されたインターフェイス/ゲートウェイなしで行うことは可能ですか?
言い換えれば、それは、クライアントへの集中管理なしでノード バランサーを設計できるかという質問に少し似ています。
複数のクライアントにサービスを提供できる場合、このサービスを提供するサーバーがダウンした場合、別のサーバーがその代わりになります。メインサーバーがダウンしたかどうかを検出し、クライアントを新しいサーバー?
一元化されたインターフェイス/ゲートウェイなしで行うことは可能ですか?
言い換えれば、それは、クライアントへの集中管理なしでノード バランサーを設計できるかという質問に少し似ています。
ええと、あなたは質問している「サービス」についてあまり情報を提供していないので、一般的な方法で回答します。
私の回答の最初の部分では、IP アドレスを含む「集中型インターフェイス/ゲートウェイ」について話していると仮定します。このために、Wikiから引用された CARP (Common Address Redundancy Protocol) があります。
Common Address Redundancy Protocol (CARP) は、同じローカル ネットワーク上の複数のホストが一連の IP アドレスを共有できるようにするプロトコルです。その主な目的は、特にファイアウォールやルーターで使用する場合に、フェイルオーバーの冗長性を提供することです。一部の構成では、CARP は負荷分散機能も提供できます。Cisco の HSRP に代わる無料の、特許の制約を受けない代替手段です。CARP は、主に BSD オペレーティング システムに実装されています。
netbsd の " Introduction to CARP "を引用します。
CARP は、同じネットワーク セグメント上のホストのグループが IP アドレスを共有できるようにすることで機能します。このホストのグループは「冗長グループ」と呼ばれます。冗長グループには、グループ メンバー間で共有される IP アドレスが割り当てられます。グループ内で、1 つのホストが「マスター」に指定され、残りは「バックアップ」として指定されます。マスター ホストは、共有 IP を現在「保持」しているホストです。それは、それに向けられたすべてのトラフィックまたは ARP 要求に応答します。各ホストは、一度に複数の冗長グループに属することができます。
これにより、単一障害点なしでスレーブにIPアドレスを順番に引き継がせることで、ネットワークレベルで質問が解決される場合があります。
さて、回答の 2 番目の部分 (アプリケーション レベル) では、分散型 erlang を使用すると、フォールト トレランスと冗長性を提供する複数のノード (クラスター) を持つことができます (したがって、ここでは IP アドレスを使用しませんが、「分散型 erlang " -erlang ノードのクラスター- 代わりに)。
Distributed Applciationが開始された状態で多数のノードが配置され、アプリケーション リソース ファイルには、アプリケーションを実行できるノードの (順序付けられた) リストが含まれます。
分散型 erlangはどのノードが「マスター」であるかを制御し、さまざまなノードでアプリケーションを自動的に開始および停止します。
http://www.erlang.org/doc/design_principles/distributed_applications.htmlからの引用 (できるだけ少なく) :
複数のErlangノードを持つ分散システムでは、アプリケーションを分散して制御する必要があるかもしれません。特定のアプリケーションを実行しているノードがダウンした場合、アプリケーションを別のノードで再起動する必要があります。
アプリケーションは、分散構成パラメーターで指定された、稼働中の最初のノードで開始されます。アプリケーションは通常どおり起動されます。
アプリケーション制御の分散が適切に機能するためには、分散アプリケーションが実行される可能性のあるノードが相互に連絡し、アプリケーションを開始する場所をネゴシエートする必要があります。
起動すると、ノードは sync_nodes_mandatory および sync_nodes_optional で指定されたすべてのノードが起動するまで待機します。すべてのノードが起動するか、すべての必須ノードが起動し、sync_nodes_timeout で指定された時間が経過すると、すべてのアプリケーションが開始されます。すべての必須ノードが起動していない場合、ノードは終了します。
アプリケーションが実行されているノードがダウンした場合、アプリケーションは (指定されたタイムアウトの後に) 分散構成パラメーターで指定された最初のノードで再始動されます。これをフェイルオーバーと呼びます
distributed = [{Application, [Timeout,] NodeDesc}]
分散アプリケーションが現在実行されているノードよりも、分散に従って優先度の高いノードが起動されると、アプリケーションは新しいノードで再起動され、古いノードで停止されます。これを乗っ取りといいます。
わかりました、それは長いトピックになる可能性があるため、一般的な概要として意図されていました:)
具体的な詳細については、learnyousomeerlangの分散型 OTP アプリケーションの章を読むことを強くお勧めします(もちろん、前のリンク: http://www.erlang.org/doc/design_principles/distributed_applications.html ) 。
また、「サービス」はデータベースなどの他の外部システムに依存する可能性があるため、耐障害性と冗長性も考慮する必要があります。「サービス」がこのように機能するには、アーキテクチャ全体が耐障害性を備え、分散されている必要があります。
それが役に立てば幸い!
この回答は、ネットワーク化されたアプリケーションの高可用性に関する一般的な概要であり、Erlang に固有のものではありません。私は OTP フレームワークで何が利用できるかについてあまり知りません。私はこの言語を初めて使用するからです。
ここには、いくつかの異なる問題があります。
問題 1 - クライアント接続の移動
これは、さまざまな方法で、ネットワーク アーキテクチャのさまざまなレイヤーで解決できます。最も簡単な方法は、接続が失われたときに別のマシンに再接続するように、クライアントに直接コーディングすることです。
ネットワークの透過性が必要な場合は、いくつかのテクノロジを使用して異なるマシン間で TCP 状態を同期し、すべてのトラフィックを新しいマシンに再ルーティングすることができます。これは、クライアントから完全に見えない可能性があります。これは、最初の提案よりもはるかに困難です。
この2つの間にやるべきことがたくさんあると確信しています。
問題 2 - 状態データ
明らかに、クラッシュしたマシンからバックアップ マシンにセッション状態を転送する必要があります。これを信頼できる方法で行うのは非常に難しく、クラッシュしたマシンがクラッシュ前の最後の状態を送信できない可能性があるため、最後のいくつかのトランザクションが失われる可能性があります。この方法で同期呼び出しを使用して、状態を失わないようにすることができます。
これは、クライアントに何かを確認する前に、バックアップ マシンとその接続 (レイテンシを含む) に依存するため、一部のシナリオではコストがかかる (または少なくとも十分に応答しない) 可能性があります。パフォーマンスを向上させるために、接続時にクライアントが受信したトランザクションをバックアップマシンでチェックし、失われたトランザクションを再送信して、クライアントの責任で作業をキューに入れることができます。
問題 3 - クラッシュの検出
クラッシュは常に明確に定義されているとは限らないため、これは興味深い問題です。何かが本当にクラッシュしましたか?クライアントとサーバー間の接続を閉じるネットワーク プログラムを考えてみましょう。さらに悪いことに、サーバーが気付かないうちにクライアントがサーバーから切断されます。考えるべきいくつかの質問を次に示します。
アイデアを得るには、Googleの論文「Chubbylockserver」(PDF)と「Paxosmadelive」(PDF)を参照してください。
簡単に言うと、このソリューションでは、コンセンサスプロトコルを使用して、すべての要求を処理するサーバーのグループからマスターを選出します。マスターに障害が発生した場合、プロトコルが再度使用されて次のマスターが選出されます。
また、障害の検出とサービスの所有権の譲渡を行うリーダー選出の例については、 gen_leaderを参照してください。