スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQL Shell 8.1 新機能 : MySQL InnoDB Cluster Read Replicas について (2)

はじめに

前回の記事から少し間が空いてしまいましたが、前回は InnDB Cluster にリードレプリカを追加・削除する方法を確認してみました。

MySQL Shell 8.1 新機能 : MySQL InnoDB Cluster Read Replicas について (1)

今回の記事では以下の高可用性部分について焦点を当ててみたいと思います。

  • 非同期レプリケーションの自動フェイルオーバー機能
  • レプリケーションソースの変更方法
  • MySQL Router – リードレプリカへのルーティングポリシー設定

なお、2024/1/16 に MySQL 8.3 がリリースされたので、本記事で検証で使用する MySQL Shell と MySQL Router を 8.1 から 8.3 に変更して動作確認を行いました。

(参考)

[MySQL Shell のアップグレード] [MySQL Router のアップグレード]

非同期レプリケーションの自動フェイルオーバー機能

レプリケーションソースをプライマリーノードにしている場合

前回の記事で紹介したリードレプリカの追加の際に、レプリケーションソースをプライマリーメンバーに指定するオプションで構成した例です。

  • cluster.addReplicaInstance()replicationSources: primary を設定

この場合、プライマリーメンバーの MySQL インスタンスが障害でダウンした場合、他のセカンダリーメンバーが新しいプライマリーメンバーに昇格しますが、リードレプリカとの接続も新プライマリーメンバーに自動的に切り替わるようになります。

早速試してみましょう。

プライマリーメンバーの mysqld を停止します。

リードレプリカの MySQL エラーログを確認してみると、レプリケーションソースへの接続リトライが行われ、結果別のレプリケーションソースへ接続したことが分かります。

リトライの回数、間隔は非同期レプリケーションパラメータの SOURCE_RETRY_COUNT, SOURCE_CONNECT_RETRY が以下のように設定されているため、3秒おき10回以内は再接続を試行するということになります。

フェイルオーバーが完了し、クラスターの状態を確認してみると、リードレプリカのレプリケーション接続も新プライマリーメンバーである ss_gr_mysql_02 に切り替わりました。

SHOW REPLICA STATUS の結果も同一ですね。

ダウンした旧プライマリーメンバーを復旧させ、クラスターに再参加した後、 cluster.setPrimaryInstance() でプライマリーメンバーをフェイルバックさせてみます。

フェイルバック時もプライマリーメンバーに接続が自動的に追随しました。

レプリケーションソースをセカンダリーメンバーにしている場合

cluster.addReplicaInstance()replicationSources: secondary を設定した場合は、以下のように動作します。(詳細は割愛します)

  1. レプリケーションソースのセカンダリーメンバーがダウンした場合、別のセカンダリーメンバーが存在する場合はそちらに接続フェイルオーバーする。
  2. セカンダリーメンバーが存在し無くなった場合、(最後に残っている)プライマリーメンバーに接続フェイルオーバーする。

レプリケーションソースの変更方法

既に設定済みのレプリケーションソースを変更するには、 Cluster.setInstanceOption()replicationSources オプションで可能です。

設定は変更されましたが、上記メッセージにある通り構成を反映させるには Cluster.rejoinInstance() の実行が必要です。

無事レプリケーションソースが変更されました。

リードレプリカの昇格/降格

リードレプリカをクラスターメンバーへ昇格

リードレプリカは事前準備で InnoDB Cluster ノード追加と同じ構成チェック(と設定)を行っていて、かつデータ同期されていますのでクラスターメンバーとして昇格させることも容易です。

具体的には一度リードレプリカを削除して、クラスターへ追加する、という形を取ります。

新たなセカンダリーメンバーとして追加されました。

セカンダリーメンバーをリードレプリカへ降格

今度は既存のセカンダリーメンバー ss_gr_mysql_03 を一度クラスターから削除し、リードレプリカとして追加してみます。

リードレプリカとして追加に成功しました。

MySQL Router のルーティングポリシーを設定する

最後に、InnoDB Cluster の DB 接続プロキシである MySQL Router がリードレプリカのルーティング設定をどのように行うかを確認してみたいと思います。

まず、InnoDB Cluster にリードレプリカを追加(cluster.addReplicaInstance())すると MySQL Router のログに以下のメッセージ出力が確認できます。

デフォルトのルーティングポリシーは、すべての読み取り専用トラフィックをセカンダリーメンバーにラウンドロビン(※)で転送するようになっています。

※正確には round-robin-with-fallback です。
MySQL :: MySQL Router 8.3 :: 4.3.3 Configuration File Options

round-robin-with-fallback: for load-balancing, each new connection is made to the next available secondary server in a round-robin fashion. If a secondary server is not available then servers from the primary list are used in round-robin fashion.

InnoDB Cluster Read Replicas では追加したリードレプリカにルーティングを向けることも可能です。

それには cluster.setRoutingOption()read_only_targets オプションを変更します。

MySQL Shell API: Cluster Class Reference

  • read_only_targets
    • all:すべてのリードレプリカとセカンダリーメンバーが読み取り専用トラフィックに使用されます。
    • read_replicas:読み取り専用トラフィックには読み取りレプリカのみが使用されます。
    • secondaries:セカンダリーメンバーのみが読み取り専用トラフィックに使用されます。(デフォルト)
    • 上記の MySQL Router ログの出力はこの設定の状態です。

設定変更に際して、クラスター上の MySQL Router の名称が必要になるのでまずは確認しましょう。

"ss_router_mysql_01::system" がクラスター上のルーター名です。

cluster.setRoutingOption() でまずはリードレプリカのみにルーティングする設定(read_replicas)に変更してみます。

左から順番に、ルーター名,オプション名,オプション設定値を設定します。

ルーティングポリシーをデフォルトから変更した内容は cluster.routingOptions() で確認できます。

MySQL Router のログに設定変更内容が認識された旨、出力が確認できました。

リードレプリカのみに接続が振り分けられるようになりました。

次に、all に設定してみます。

リードレプリカとセカンダリーメンバーにルーティングされるようになりました。

MySQL Router のログ出力で以下の通り all が設定された旨が分かります。

まとめ

前回の記事と続けてご覧いただけると、本機能を使えば手軽にリードレプリカを追加・削除でき、かつレプリケーションソースの自動接続フェイルオーバーやクライアント(MySQL Router 経由)接続のルーティング設定等、優れた機能をもつ環境に構成が容易にできるようになるということが分かると思います。

まだリリースして間もない新機能ではありますが、 InnoDB Cluster + リードレプリカ(または多用途の非同期レプリカ)という組み合わせは汎用的で多くのニーズがあると考えます。

今後の発展(改善や機能拡張)にも注目していきたいと思います。

Return Top