VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
レプリカの用途
- 読み取りのスケーリング。 ダッシュボード、検索、エクスポート、および API の読み取りがソースから移動し、ソースの容量を書き込みのために残します。
- 高コストなクエリの分離。 アナリストの 40 秒かかる集計はレプリカで実行され、誰もブロックしません。
- ウォームスタンバイ。 最新のレプリカは、ソースが障害を起こしたときに昇格できます。
読み取りのルーティング
MySQL はクエリをルーティングしてくれません。スタックの中の何かが、書き込みをソースへ、選択した読み取りをレプリカへ送る必要があります。- アプリケーションレベルのルーティング。 ほとんどのフレームワークが直接サポートしています(Django のデータベースルーター、Rails の
connects_to/ロール、Laravel の読み取り/書き込み接続)。シンプルで明示的で、アプリケーションがクエリごとに決定します。 - プロキシ。 ProxySQL などはステートメントの種類やルールでルーティングするため、アプリケーションは 1 つの接続文字列を保ちます。これはフェイルオーバーも一元化します。
レプリケーションラグ: 本当に難しい部分
レプリケーションはデフォルトで非同期です。ソースでのコミットはレプリカが変更を適用する前に返るため、その直後のレプリカの読み取りは、すでに成功した書き込みを見逃すことがあります。ラグはレプリカで測定します。Seconds_Behind_Source フィールドが標準的なシグナルです。通常はゼロ付近で、書き込みのバースト、大きなトランザクション、およびスキーマ変更の下で急上昇します。これにアラートを設定し、読み取りパスごとの許容値を把握しておいてください。
典型的な障害は read-your-own-writes です。ユーザーがプロファイルを保存し(ソースへの書き込み)、次のページがレプリカからそれを読み込むと、レプリカはまだその書き込みを適用していません。ユーザーには自分の変更が消えたように見えます。標準的な緩和策を、コストの低い順に示します。
- 書き込み後の固定。 セッションが書き込んだ後、そのセッションの読み取りを数秒間ソースにルーティングします。多くのフレームワークとプロキシがこのパターンを直接サポートしています。
- 許容度によるルーティング。 金銭の残高や編集直後のページはソースから読み取り、閲覧ページ、検索、および分析はレプリカから読み取ります。
- GTID によるセッション一貫性。 書き込み後にトランザクション識別子を取得し、レプリカの読み取りで
WAIT_FOR_EXECUTED_GTID_SET()を使ってそれを待ちます。正確ですが、リクエストを通して GTID を引き回す仕組みが必要です。
2 つの実践的なルール
- レプリカは余り物ではなく、同等以上のハードウェアであるべきです。 ソースより遅いレプリカは、まさにレプリカを追加する理由となった負荷の下で遅れていきます。
- 昇格をリハーサルしてください。 一度も昇格させたことのないレプリカは、一度も復元したことのないバックアップと同じです。必要になる前にフェイルオーバーの手順を練習してください。
関連項目
- レプリケーションの基本 — このガイドの土台となるレプリケーションの構築
- バイナリログ — レプリカが再生するログストリーム
- コネクションプーリング — 読み取りと書き込みを分けた後の、ロールごとのプーリング