3

この質問は、2 つのデータベースを 2 つの異なるサーバーで同期させる場合の冗長性の実装に関するものです。まず、問題の背景を理解できるように設定について説明します。

2 つの異なるサーバーがあり、2 つの異なる場所で異なる DB タイプの異なるオペレーティング システムを運用しています。

Server 1 (local server):
Windows 2003 Small Business Server OS
MSSQL DB Server
Server-Side Language - C# ASP.NET

Server 2 (website server):
Linux CentOS 6
MySQL DB
Server-Side Language - PHP

サーバー 1 はソフトウェアの内部管理側を実行し、サーバー 2 は外部 Web サイト インターフェイスです (サーバー 2 にはいくつかの管理面 2 があります)。残念ながら、私たちのオフィスではブロードバンドが頻繁に失われています。これは、2 つのサーバー間の通信が常に可能であるとは限らないことを意味します (3G ブロードバンドの冗長性がありますが、動的 DNS が新しい IP アドレスで DNS レコードを更新するのに時間がかかります)。プライマリ ブロードバンドを失います)。これが、各サーバーに独自の DB が必要になった理由です。これらの 2 つのサイドの一方または他方を完全にオフラインにすることはできないためです。

そのため、両方のサーバーに独自のローカルデータベースを持ち、変更を他のサーバーにも適用するように、両方のサーバーに組み込みました。他のサーバーに接続できない場合は、クエリをローカル DB に保存して、他のサーバーが再び使用可能になったときにクエリを適用できるようにします。これにより、次の 2 つの問題が残ります。

  1. このようなデータベース間の同期に関する一般的なポイント - サーバーの再接続時に適用される競合するクエリを回避するにはどうすればよいですか? 私の言いたいことの説明については、以下の例 1 を参照してください。DNS レコードが更新されるまでの数分間だけ接続が失われるため、この問題は最小限に抑えられます。

  2. バックログされたクエリを適用するとき、バックログされたクエリを解決するためにスクリプトを手動で起動するのではなく、スクリプトがクエリを自動的に適用するようにしたいと考えています。ただし、バックログでバックログされたクエリをまだ適用している間にユーザーがページから移動した場合、これがどのような影響を与えるかはわかりません。

例 1:

Web サイト側 (サーバー 2) のユーザーがメール アドレスや電話番号などを変更し、管理側 (サーバー 1) のユーザーがそのユーザーの詳細を変更した場合、これら 2 つのクエリの情報は矛盾します。サーバーが再接続すると、2 つのクエリが他のサーバーに適用されますが、エントリはまだ同期していません。

PS申し訳ありませんが、質問はとても長いです。

4

2 に答える 2

2

データベースレプリケーションを再発明しないでください。代わりに、データベースソフトウェアが提供するものを使用してください。

ただし、これは、両端で同じRDBMSに切り替える必要があることを意味します。MySQLレプリケーションはWAN接続でかなり信頼性が高く、プラットフォームとバージョン間で確実に機能します。

于 2012-12-14T14:36:22.990 に答える
0

私は gertvdijk に同意します。最良の解決策は、両方のサーバーで同じ RDBMS を使用し (ただし、両方のホスト OS で問題なく動作するため、MSSQL ではなく MySQL を使用します)、その RDBMS のレプリケーション ソフトウェアを使用することです。

ただし、それをしたくない、またはできない場合、私が考えることができる次善の策は、両方のサーバーに「トランザクション ログ」を作成することです。UTC の日付/時刻と実行する SQL コマンドをキャプチャするのは、最も単純なものです。

2012-12-14 13:42:13 UPDATE users SET email = 'me2@mydomain.com' WHERE id = 13542
2012-12-14 13:43:55 UPDATE ....
...

明らかに、私が示したものの代わりにパラメーター化されたクエリを使用したいと思うでしょう-実装の詳細に夢中になることなく、私のアイデアを説明する方が簡単です.

そのため、各サーバーはそのトランザクションのログを保持しているため、突然オフィスへの接続が失われます。数分後に起動すると、両方のサーバーがトランザクション ログを交換し、それらを独自のトランザクション ログとマージして、すべてのレコードを UTC 日付/タイム スタンプで並べ替えます。これで、サーバー間の接続が失われたときにまったく同じ列に変更が加えられたとしても、両方のサーバーで発生したすべてのクエリを実行でき、それらが同期していないことを心配する必要はありません。まったく同じ列がまったく同時に変更されることが心配な場合は、マイクロタイムを日付/時刻スタンプに入れることができます。

于 2012-12-14T15:03:45.730 に答える