あなたは称賛に値する努力をしていますが、他のコメント提供者が述べているように、いくつかの理由であなたの解決策は実行可能ではありません。
セッションレベルでauto_increment_offsetとauto_increment_incrementを実際に使用する必要はありません。それらをサーバーレベルで設定する必要があります。RDSでそれができない場合は、これがRDSがおそらく最良のソリューションではないもう1つの理由です。
私が出てきて、MySQLサーバーのグローバルネットワーク(RDSではなくEC2)をマルチマスターリングにデプロイすることを提案した場合、データは1 => 2 => 3 => 4 => 1を複製し、各サーバーは着信複製を無視します独自のサーバーIDを持つメッセージの場合、私の仲間のMySQL DBAは、私の心を失い、管理が困難な状況に陥ったと非難します。しかし、私はこれがはるかに簡単になると確信しています少なくとも、データは実際に変更されたのとほぼ同じ順序で世界中で変更されるため、提案したものよりも解決策が得られます。これにより、複数の場所から発生する更新の競合の可能性が減少します。MySQLレプリケーションは非同期です。つまり、サーバー1はサーバー2でトランザクションがコミットされるのを待たずに、クライアントに成功を返します(トランザクションがコミットされたことを示します)が、その事実とそれがコミットされたという事実を混同しないでください。順次-トランザクションは、コミットされた順序で各サーバーに複製されます。(MySQL 5.6の新しいオプションでは、並列レプリケーションスレッドを使用することで、これに対するいくつかの例外が許可されますが、これはこの説明では重要ではありません)。
自動インクリメント値の競合を回避するためのスキームを考案したため、より大きな問題は更新と削除に起因する可能性があります。今説明したシナリオでは、サーバー2がレコードを削除し、サーバー4が同じレコードを同時に削除した場合、サーバー2から削除を受信すると、サーバー4は着信イベントの複製を停止します。異なっていた。あなたのシナリオも同様に失敗します。違いは、実際のMySQLレプリケーションを使用すると、競合イベントが発生した後は何も起こらないため、競合を解決するまで、上記のシーケンシャルな性質とMySQLレプリケーションが完全に停止するため、少なくともデータが不整合に分岐することはありません。競合が発生したときはいつでも。マスターサーバーのリングでは、複製を停止したサーバーはアップストリームシステムから複製イベントのログを収集し続けますが、競合が解決されて複製が再開されるまでローカルで変更されない限り、実行は停止し、そのサーバー上のデータは凍結されます。
また、シナリオでは、更新時に各列の「from」と「to」の値を保持する必要があることにも注意してください。ロールバックすることがわかっていない限り、何もロールバックできないためです。
その点に注意して、ロールバックは後でではなく、リアルタイムで発生する必要があります。2つの銀行口座間で送金し、何らかの理由で送金をロールバックする必要がある場合、銀行のWebサイトを使用している間、銀行はそのトランザクションを途中でロールバックできないことを確認する必要があります。彼らのサーバーの1つが私の銀行口座の残高が異なるという理由だけで夜。
ここに考えがあります:あなたのシナリオでは、私が「転送先」に転送していたアカウントはすべてのサーバー間で一貫していましたが、「送信元」に転送していたアカウントはそうではありませんでした。 「from」アカウントですが、「to」アカウントにデポジットを残しますか?そうかもしれないと思います。
CAP定理によって制限されることに注意してください。グローバルに一貫性があり、利用可能で、ノード間の分離を許容できるシステムはありません。せいぜい、2つ選ぶことができます。
その考えで、私が持っている質問はこれです:なぜあなたのグローバルシステムのすべてのノードを同期させる必要があるのですか?主な理由がパフォーマンスである場合は、読み取りレプリカをリージョン間で分散させて、単一のグローバルマスターサーバーを展開する可能性を検討してください。SELECT
ほとんどのクエリがローカルのリードレプリカにINSERT
送信DELETE
され、、、、、、UPDATE
およびCALL
(データを更新するストアドプロシージャ)がグローバルマスターサーバーに送信されるように、データベース接続スレッドの2つのプールを使用してアプリケーションを作成します。したがって、最大の懸念は、結果整合性しかないという事実になります。リードレプリカで。適切なサイズのサーバーと適切に記述されたクエリを使用すると、これは非常に高速です(光および電気信号のグローバルな移動に関する物理法則に従います)が、瞬時ではありません。これを達成するためにあなたがしなければならないことは、データベースに最近変更を加えたセッションの場合です。それらの読み取りはグローバルマスターにヒットする必要があるかもしれません-注文する場合、すぐに注文を確認する必要があるので、マスターはすぐに見るのに最適な場所。後で、ローカルレプリカを確認すると機能します。クロスリージョンの問題があるため、これではまだRDSの範囲外です...しかし、EC2上のMySQLは適しています。
リードレプリカはマスターに非常に小さな負荷をかけますが、この負荷でさえ、単一のリードレプリカをマスターに接続し、次にダウンストリームのリードレプリカをその中間サーバーに接続することで軽減できます。
slave_compressed_protocol
マスターとレプリカで=1に設定すると、マシンは圧縮接続を使用してレプリケーションイベントを転送できるようになります。複製されるデータの性質に応じて、これは3:1から10:1の範囲であり、データの圧縮と解凍の遅延は重要ではないようです。
さらに、プライマリマスターに隣接して(おそらく別のA / Zに)2番目のマスターをセットアップし、これら2つのサーバーをマスターマスターの複製でリンクし、リードレプリカを2番目のマスターにチェーンし、自動増分増分とオフセットを使用できます。適切ですが、通常の状態では2番目のマスターへの書き込みまたは2番目のマスターへの読み取りは行わないでください。なぜあなたはこれをしますか?このようにして、プライマリマスターに障害が発生した場合に、アプリケーションをリダイレクトしてアクセスすることにより、すぐにサービスを開始できる2番目のグローバルマスターがあります。
もちろん、アプリケーションの性質は、実際に必要なグローバル統合の量に大きな影響を及ぼします。この問題を解決するには、アーキテクチャの変更が必要かどうかを判断するために、アプリケーションがどのように機能するかを再考する必要があります。
DBAとして、私はRDSが私に課す制限と柔軟性の制約のいくつかが好きではありません。制御不能の見返りとして私が本当に得ているのは、バックアップとポイントインタイム復元が比較的簡単なことだけです...私は好きです...しかし、私にとって、これらは制限を補っていません。
脚注:3番目の段落で、「トランザクションは、コミットされた順序で各サーバーに複製されます」と述べました。しかし、それは必ずしも実際の壁掛け時計の実際の順序を意味するわけではありません...実際には、サーバーによってコミットされている他のトランザクションと比較して、各サーバーにコミットされている順序を意味します。 ..したがって、サーバー#3の別のトランザクションの前に実際にコミットされたサーバー#1のトランザクションは、トランザクションがサーバー#2を介して伝播するのにかかった時間に応じて、サーバー#3からのトランザクションの前ではなく後にサーバー#4に到着する可能性があります。サーバー#3にコミットします。ただし、これは原則として「十分に真実」です。これは、#1のトランザクションがサーバー#3で、#3で発生したものと競合していると認識された場合に発生するためです。