スマートスタイル TECH BLOG

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

ProxySQL Cluster の紹介

はじめに

ハイパフォーマンスで多彩な機能として人気のデータベース用プロキシ ProxySQL ですが、ネイティブなクラスタ機能を有していることをご存じでしょうか。

ProxySQL Cluster – ProxySQL

v1.4.2 で実験的に実装され、その後 Bug 修正もありつつ、v2.1.0, 2.4.0 で多数の機能改善があり、現在は安定した機能となっています。

今回はこの ProxySQL Cluster について紹介したいと思います。

ProxySQL Cluster の概要

クラスタ、というキーワードが付くと多くの場合は一般的な HA クラスタ(高可用性構成)を思い浮かべてしまうかもしれません。

ProxySQL Cluster はそのような機能ではなく、おおまかに説明すると「クラスタメンバー間で設定の自動同期ができるようになる」というのが機能の主旨です。

ProxySQL 自体は分散型プロキシですので、ProxySQL Cluster は負荷分散クラスタリングの位置付けと言えます。

クラスタ機能を有効にすると、同期可能な設定情報が変更されるたび、チェックサムを生成するようになります。

このチェックサムとその生成・変更日時をクラスタメンバーが互いに監視しあい、他のピアで発生した変更分を(比較して適宜)自ノードに反映する、というものです。

上記については、「現時点のバージョン(執筆時点の最新は v2.4.5) では、」 という但し書きを補足しておきたいと思います。

というのも公式ドキュメント中には、以下の開発ロードマップが記されていて、
プライマリ-セカンダリ構成のクラスタであったり、現在のような Pull 型の同期方式ではなく、MySQL レプリケーションのような Push 型 にデザインする構想があるようです。

Roadmap

This is an overview of the features related to clustering, and not a complete list. None the following is impletemented yet.
Implementation may be different than what is listed right now:

  • support for master election: the word master was intentionally chosen instead of leader
  • only master proxy is writable/configurable
  • implementation of MySQL-like replication from master to slaves, allowing to push configuration in real-time instead of pulling it
  • implementation of MySQL-like replication from master to candidate-masters
  • implementation of MySQL-like replication from candidate-masters to slaves
  • creation of a quorum with only candidate-masters: normal slaves are not part of the quorum

現状では設定同期のみか…、と思われるかもしれませんが、ProxySQL は複数ノードで利用されることが多いので(アプリケーションサーバと同居する構成が推奨)、ProxySQL Cluster を有効にすることで以下のメリットがあります。

  • 設定変更は1ノードのみで行えばよくなる
    • 作業やチェックにかかるコストが削減される
    • もし Ansible や Chef などの構成管理ツールを用いて自動化していた場合は、それらの仕組みが不要になる
    • Ansible だと、Community.Proxysql コレクションが公開されていたりしますが、バージョンアップを追随したりする必要もなくなります。
  • ノード追加が容易になる
    • クラスタメンバーに追加するだけで、設定情報が同期できるので、簡単にスケールアウトすることができます。

また、設定が自動同期される、ということは、例えば DB 側のレプリケーションフェイルオーバが発生し、何らかの仕組みで ProxySQL 内の接続先DB情報(mysql_servers, mysql_replication_hostgroups) が更新された場合、クラスタメンバーもほぼ同タイミングで新しい接続先DBセットを参照できるようにもなります。

これらのメリットを踏まえると、冗長化・スケーラビリティの向上・高可用性構成の補助的な機能向上に貢献、といった効果があると言えます。

同期対象の設定情報

以下のクラスター用 GLOBAL 変数(チェックサム生成要否)を true(デフォルト) にすることで同期対象となります。

基本的に ProxySQL を使用するうえでの主要テーブルが同期対象となっています。

runtime_checksums_values テーブルでは、 version が 1以上のモジュール(設定情報)が該当します。

上記確認結果から分かる通り、6モジュールが v2.4 の時点で同期可能です。

主要な設定情報(mysql_servers,mysql_users,mysql_query_rules)と、GLOBAL変数(admin_variables,mysql_variables)、そしてクラスタメンバー情報テーブル(proxysql_servers)が同期の対象となっています。

version は自ノードで Runtime へ設定を反映(LOAD ... TO RUNTIME)するとカウントアップされます。

引用:Configuring ProxySQL – ProxySQL

ProxySQL Cluster の公式ドキュメントページには明記が無いですが、Admin Variables ページ の 各 admin-checksum_% 変数の説明文や、リリースノートソースコードを見ると、正確には以下の設定情報も同期されます。

  • mysql_users の同期時に、ldap_auth_plugin プラグインが見つかったら、ldap_variables(ldap-%) と mysql_ldap_mapping を同期
  • mysql_query_rules の同期時に、mysql_query_rules_fast_routing も同期
  • mysql_servers の同期時に、以下のデータも同期
    • mysql_replication_hostgroups
    • mysql_group_replication_hostgroups
    • mysql_galera_hostgroups
    • mysql_aws_aurora_hostgroups

※以下の公式ブログ記事は、v1.4 で ProxySQL Cluster が初期リリースされた頃の内容で、4モジュールのみが同期対象となっていますのでご注意ください。

Native ProxySQL Clustering now available – ProxySQL

注意事項

  • すべての設定が同期されるわけではない点に気を付けてください。

    具体的には、以下の設定は現時点のバージョンでは同期されません。(今後追加されるかもしれません)

    • Firewall whitelist 関連
      • mysql_firewall_whitelist_rules
      • mysql_firewall_whitelist_sqli_fingerprints
      • mysql_firewall_whitelist_users
    • REST API 設定
      • restapi_routes
    • Scheduler 設定
      • scheduler
  • v2.1.0 以降は、クラスタメンバー同士の ProxySQL のバージョンを揃える必要があります。(異なるバージョン間の同期不整合を防ぐため)

クラスタ設定の確認

それでは、実際に ProxySQL Cluster の構築を行ってみたいと思います。

使用環境

  • ProxySQL : v2.4.5
  • OS : Rocky Linux 8.6

インストール手順は公式ドキュメントページをご参照ください。

または、公式の Docker イメージもありますので、そちらで手軽に試すこともできます。

クラスタ構成シナリオ

今回は各種設定済み ProxySQL ノードをシードとして、クラスタを構成してみたいと思います。

※未設定状態の 新規 ProxySQL ノード同士でまずクラスタを構成したのち、設定を投入して同期する、という流れも可能です。

  • シードノード(hostname:rha-proxy-01) は、mysql_servers, mysql_users, mysql_query_rules に各種設定を投入済み、GLOBAL 変数も一部変更済みの状態です。
  • 追加ノード(rha-proxy-02)は、ProxySQL サービスを起動後、管理者ユーザのパスワードを変更したのみの状態です。

クラスタ用パラメータの設定

シードノード、追加ノードそれぞれで ProxySQL の CLI 管理コンソールにログインし、同一の各パラメータを設定していきます。
※bootstrap用の構成ファイル(/etc/proxysql.cnf) に設定して起動、という方法でも勿論可能です。

まずは、クラスタ構成に最低限必要なパラメータとして、クラスタメンバー間の相互認証用にクラスタ専用のユーザ名とパスワードを設定します。
admin-admin_credentials にも追加しておく必要があります。

なお、ProxySQL ノード同士の認証は MySQL プロトコルで行われます。

ちなみに ProxySQL Cluster にはクラスタ名の設定がありません。複数の異なるクラスタを構成したい場合は、クラスタごとに一意となる admin-cluster_username を設定します。(1つの ProxySQL ノードが複数のクラスタに属することはできません)

以降のパラメータはデフォルトのままでも構いませんが、今回は説明のため敢えて取り上げています。

以下は、チェック間隔のパラメータです。デフォルト値を記載していますが、適宜変更してください。

以下は、他のピアから設定を同期した後、自ノードの Disk にすぐ同期(永続化)するか否かを指定するパラメータです。(デフォルト:true)

以下は、指定回数チェックされるのを待ってから同期を行うパラメータです。

  • これは、各ProxySQL はそれぞれが独立してバックエンドDBの状態をチェックしていていて、以下のようなイベントが発生した場合、互いに同じ動作を行うので、同期する必要が無く、非常に短い時間で同じ設定内容に収束する可能性があるためです。

    • レプリケーショントポロジーの変化を検出
    • 一時的にNW遅延状態などの理由でヘルスチェック失敗したバックエンドDBとの接続を切断 (参考:Backend Monitoring – ProxySQL)
    • レプリケーション遅延発生により閾値(mysql_servers.max_replication_lag)を超過したレプリカサーバが追い付くまで接続断

    admin-cluster_*_diffs_before_sync で指定した回数のチェックののち、まだローカルとリモートとで設定に差分がある場合、同期が実行されるようになります。

ここまでのパラメータを Runtime にロードおよび Disk に永続化しておきます。

ちなみに、それぞれのクラスタメンバーが異なる設定変更を各自で実行した場合、最後にロードされた設定が反映されます。(後勝ち方式)
ただし、異なる設定が同時にロードされた場合においては、競合の解決が不可能なため、収束しないポイントまで反映することになります。

クラスタノードの登録

こちらもシードノード、追加ノードそれぞれで同一設定を投入します。
proxysql_servers へクラスタメンバーを登録し、Runtime にロードするとすぐに、ピアのチェックと設定の同期が行われます。

各ProxySQLのログファイル(/var/lib/proxysql/proxysql.log)に、クラスタの同期状況が次々と出力されていきます。(ログ量が多いのでここでは割愛します)

シードノードで事前投入していた設定情報のうち同期対象の設定内容は、もれなく追加ノードにも反映されていました。(こちらも割愛します)

これでクラスタの構成は完了です。

なお、公式ドキュメントには 3ノードでの設定例が紹介されていますが、最小ノードが3ということではありません。
クラスタとしての Bootstrap は (今回のように)1ノードからでも可能です。

ノード追加時

ノード追加する際は、やはり同じように新規ノードでクラスタ用のパラメータを設定した後、proxysql_servers へは以下のように設定投入します。

  • 新規ノードにて、全クラスタメンバーの情報を登録します。
    • この時点で、新規ノードは既存クラスタメンバーから設定情報を Pull して同期します。
      しかし、既存メンバーは新規ノードをソースとした同期は行いません。(自ノードの proxysql_servers テーブルに登録がないのでソースとしての信頼性が無いと見做されるため)
  • 既存の任意の1ノードにて、新規ノードの情報を登録します。
  • すべてのクラスタメンバーのproxysql_servers テーブルに新規ノードの情報が追加されて初めて、新規ノードは正式にクラスタメンバーとして参加となります。

クラスタの状態確認

以下、新たに追加されたクラスタ用の各種テーブルを参照することで、クラスタの状態を確認することができます。

  • proxysql_servers テーブルでクラスタに参加しているメンバーを確認することができます。

    weight(重み付け) は現在機能せず、今後の開発ロードマップでの拡張が予定されているようです。

  • クラスタ同期の状況を監視するための以下のテーブルが stats に追加されています。

    上記のうち、stats_proxysql_message_metrics, stats_proxysql_message_metrics_reset, stats_proxysql_servers_status はまだ使用できず、空のテーブルです。

    • stats_proxysql_servers_checksums テーブルではクラスタメンバーごとの各同期モジュールのチェックサムや変更日時を俯瞰することができます。

    • stats_proxysql_servers_clients_status テーブルではクラスタに参加するときの各ノードの UUID(起動オプション -U または --uuid で指定可能。指定なしの場合は自動生成) やホスト名、ポート番号といった情報が確認できます。

    • stats_proxysql_servers_metrics テーブルでは各クラスタメンバーの稼働状況統計が確認できます。

ノード削除時

いずれかのクラスタメンバーノードで proxysql_servers テーブルから対象ノードのレコードを削除します。
削除対象ノードから実行しても問題ありません。(この設定変更までクラスタメンバーに伝搬されるため)

その他注意事項など

本記事で取り上げていない仕様や制約事項などは 公式ドキュメント の Q&A セクションを確認することをお勧めします。

おわりに

今回紹介しました通り、ProxySQL Cluster は専用の設定を追加するだけの簡単な手順でクラスタ化が構成可能です。

個々の ProxySQL ノードで設定の同期が困難な環境は安易に導入できないかもしれませんが、多くの場合は標準的にクラスタ化しておくことのメリットは大きいのではと思いますので、ぜひ試してみてはいかがでしょうか。

開発ロードマップに挙がっている機能拡張が今後どのように進んでいくのかも非常に楽しみです。

Return Top