記憶喪失の断片化について最近尋ねた質問の解決策に続いて、私にはまだ多くの課題があります. 次のシナリオを考えてみましょう (私が尋ねている質問は、以下の内容に基づいています)。
企業内で高可用性が必要なデータ駆動型のエンタープライズ アプリケーションがあります
。何らかの理由で内部情報ソースがダウンした場合、エンタープライズ アプリケーションはオフサイト (リモート)のリカバリ センター
からデータを取得するように切り替える必要があります。
企業内の 2 つのノード( DB サイド AおよびDB サイド Bと呼ばれる)にデータベースを複製することにしました。これら 2 つは別々の
ハードウェアで実行されていますが、ファスト イーサネットまたは光ファイバー リンクなどでリンクされています。論理的には、これら2 つの Mnesia DB
間に何らかのトンネルまたは安全な通信を作成します。
2 つ (A と B) には同じデータのレプリカがあり、
常に同期している必要があります。一方、攻撃やハードウェア障害
によってローカル データ アクセスが切断された場合に備えて、リカバリ センターにも同じデータのコピーがあり、常に同期されている必要があります。したがって、同じデータベース スキーマを 3 つのサイト ( A側、B 側、および復旧センター
)に複製する必要があります。
現在、企業内では、アプリケーション ミドルウェアがデータベース サイト間でデータ要求を切り替えることができます。A がダウンしている場合、アプリケーションがそれを認識することなく、リクエストはデータベース B に再ルーティングされます。ミドルウェア レイヤーは、ロード バランシング (要求の多重化) を行うように構成したり、フェイルオーバー技術を使用して柔軟になるように構成したりできます。
さらなる分析:
データベース/スキーマの作成時に、関連するすべてのノードが稼働し、
Mnesia が実行されている必要があります。これを実現するには、 「db_side_A@domain.com」、
「db_side_B@domain.com」、最後に「db_recovery_center@domain.com」を作成します。
ここで、テーブルの作成時に、mnesia テーブルを断片化する必要があります。したがって、次のパラメータを決定します。
n_disc_only_copies =:= プールに含まれるノードの数 =:= 3 理由:このパラメーターはすべてのテーブルは、次の配置に基づいて作成されます
、各フラグメントが持つべき disk_only_copies レプリカの数を規制するというドキュメントに従っています。
したがって、各テーブルには、各 mnesia ノードにそれぞれのフラグメントが必要です。
node_pool =:= 関連するすべてのノード =:= ['db_side_A@domain.com',
'db_side_B@domain.com',
'db_recovery_center@domain.com']
ノード = [ 'db_side_A@domain.com', 'db_side_B@domain.com', 「db_recovery_center@domain.com」 ]、 No_of_fragments = 16、 {atomic,ok} = mnesia:create_table( TABLE_NAME ,[ {frag_properties,[ {node_pool,ノード}, {n_fragments,No_of_fragments}, {n_disc_only_copies,length(ノード)}] }、 {索引、[]}、 {attributes,record_info(fields, RECORD_NAME_HERE )}] )、注: 上記の構文で
RECORD_NAME_HERE
は、レコードは Erlang でのコンパイル時に認識されている必要があるため、実際には変数にすることはできません。インストールから、各テーブルについて、すべてのフラグメント (たとえば、table_name_frag2
) がすべてのノードのファイル システムに表示されることがわかります。
課題と発生する質問:
上記の内容に従った後、mnesia がすべてのノードで実行されているため、最初のデータベースの起動は問題ありません。アプリケーションが実行されると、いくつかの課題が現れ始め、以下にリストされています。
すべての書き込みが最初に試行され
DB Side A
、その瞬間にサイド A が利用できない場合、呼び出しが再試行されDB Side B
、recovery center
3 つのデータベース ノードすべてで呼び出しが返されなかった場合、アプリケーション ネットワークミドルウェアレイヤーは、データベースサーバーがすべて利用できないことを報告します (この決定は、アプリケーションが mnesia レプリカにランダムに書き込むようにすると、mnesia ノードが失われた場合に一貫性のないデータベースエラーが表示される可能性が非常に高いという事実に影響された可能性があります)相互にネットワーク接続されていますが、異なる Erlang アプリケーションによってそれぞれに書き込みがコミットされています. を使用することmaster_nodes
にした場合、データを失う危険性があります) したがって、行動によって、あなたは強制していますDB Side A
マスターになる。これにより、他のデータベース ノードが稼働している間は常にアイドル状態になり、DB Side A
サイド A にヒットするリクエストと同じ数のリクエストがダウンすることはありません。サイド B とリカバリ センターにリクエストがヒットすることはありません。通常、Mnesia は開始時に、関連するすべてのノードが実行されていることを確認する必要があります (関連するすべてのノードで mnesia が実行されている必要があります)。これにより、ネゴシエーションと一貫性チェックを行うことができます。これは、mnesia がすべてのノードでダウンした場合、完全に初期化してテーブルをロードする前に、すべてのノードで mnesia を開始する必要があることを意味します。Erlang VM がリモート サイトで Mnesia と一緒に停止すると、さらに悪化します。まあ、あちこちでいくつかの微調整とスクリプトを実行すると、VM 全体と目的のアプリケーションがダウンした場合に再起動するのに役立つ可能性があります。
長い話を短くするために、質問に行きましょう。
質問:
inconsistent_database, starting to run database behind a partitioned network
a を設定するmnesia master node
ことが望ましくない状況で (データ損失の恐れがあるため) 、 mnesia が のイベントを生成した場合、データベース管理者はどうしますか?私の申請に関する記憶喪失イベントの結果はどうなり
inconsistent_database, starting to run database behind a partitioned network
ますか? 私がこの出来事に反応せず、物事をそのままにしておくとどうなりますか? データが失われていますか?大規模な mnesia クラスタで、Mnesia がリモート サイトの Erlang VM と一緒にダウンした場合、何ができるでしょうか? この状況を自動的に処理する既知の適切な方法はありますか?
ネットワークの問題や障害が原因で 1 つまたは 2 つのノードに到達できない場合があり、生き残ったノードの mnesia は、特に
indexes
. 実行時に、一部のレプリカがダウンした場合、アプリケーションの動作はどうなるでしょうか? mnesia クラスター内にマスター ノードを配置するようアドバイスしていただけますか?
上記の質問に答える際に、可用性を確保できるかどうかにかかわらず、最初に説明したレイアウトを強調することもできます。実稼働環境で mnesia の断片化および複製されたデータベースを使用した個人的な経験を提供できます。このテキストの冒頭にあるリンクされた (引用された) 質問を参照して、フラグメントの数、オペレーティング システムの依存関係、ノード プールのサイズ、テーブルのコピーの種類など、データベースの作成時に信頼性を高めることができる代替設定を提供してください。など