MariaDB MaxScaleは、MariaDBデータベースサーバー用の高度なプラグインデータベースプロキシです。これは、クライアントアプリケーションとデータベースサーバーの間に位置し、クライアントクエリとサーバー応答をルーティングします。 MaxScaleはサーバーも監視するため、サーバーのステータスやレプリケーショントポロジの変更にすばやく気付くことができます。これにより、MaxScaleはフェイルオーバーや同様の機能を制御するための自然な選択になります。
この2部構成のブログシリーズでは、DockerでMariaDBMaxScaleを実行する方法について完全なウォークスルーを提供します。このパートでは、スタンドアロンのDockerコンテナーとしてのデプロイと、高可用性を実現するDockerSwarmを介したMaxScaleクラスタリングについて説明します。
Docker上のMariaDBMaxScale
DockerHubで使用できるMariaDBDockerイメージは多数あります。このブログでは、MariaDBが管理・公開している「mariadb / maxscale」(タグ:最新)の公式画像を使用します。画像のサイズは約71MBです。この記事の執筆時点では、イメージは必要なパッケージの一部としてMaxScale2.3.4とともにプリインストールされています。
通常、コンテナ環境でこのイメージを使用してMaxScaleを実行するには、次の手順が必要です。
- 実行中のMariaDB(マスタースレーブまたはマスターマスター)レプリケーション/GaleraクラスターまたはNDBクラスター
- MaxScaleモニタリング専用のデータベースユーザーを作成して付与します
- MaxScale構成ファイルを準備します
- 構成ファイルをコンテナにマッピングするか、KubernetesConfigMapまたはDockerSwarmConfigsにロードします
- コンテナ/ポッド/サービス/レプリカセットを開始します
MaxScaleはMariaDBの製品であることに注意してください。つまり、MariaDBサーバー向けに調整されています。 GTID処理、Galera Cluster構成、内部データファイルなどの一部を除いて、ほとんどの機能は引き続きMySQLと互換性があります。使用するバージョンは2.3.4で、Business Source License(BSL)の下でリリースされています。これにより、すべてのコードを開くことができ、3つのサーバーでの使用は無料になります。使用量が3台のバックエンドサーバーを超える場合、それを使用する会社は商用サブスクリプションの料金を支払う必要があります。特定の期間(MaxScaleの場合は2年)が経過すると、リリースはGPLに移行し、すべての使用が無料になります。
明確にするために、これはテスト環境であるため、2つ以上のノードがあっても問題ありません。 MariaDB BSL FAQページに記載されているように:
Q:テストおよび開発環境でBSLの下でライセンスされたMariaDB製品を使用できますか?
A:はい、非本番テストおよび開発環境では、MariaDBからのサブスクリプションを必要とせずにBSLの下でライセンスされた製品を使用できます
このウォークスルーでは、ClusterControlを使用して3ノードのMariaDBレプリケーションを既にデプロイしています。次の図は、展開するセットアップを示しています。
私たちのシステムアーキテクチャは次のもので構成されています:
- mariadb1-192.168.0.91(マスター)
- mariadb2-192.168.0.92(スレーブ)
- mariadb3-192.168.0.93(スレーブ)
- docker1-192.168.0.200(コンテナーのDockerホスト-maxscale、app)
MaxScaleユーザーの準備
まず、MaxScaleのMySQLデータベースユーザーを作成し、ネットワーク内のすべてのホストを許可します192.168.0.0/24:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
次に、必要な権限を付与します。負荷分散を使用してバックエンドサーバーを監視するだけの場合は、次の許可で十分です。
MariaDB> GRANT SHOW DATABASES ON *.* TO 'maxscale'@'192.168.0.%';
MariaDB> GRANT SELECT ON `mysql`.* TO 'maxscale'@'192.168.0.%';
ただし、MaxScaleはルーティングクエリ以上のことを実行できます。たとえば、スレーブを新しいマスターに昇格させるなど、フェイルオーバーとスイッチオーバーを実行する機能があります。これには、SUPERおよびREPLICATIONCLIENT特権が必要です。この機能を使用する場合は、代わりにすべての特権をユーザーに割り当ててください。
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
ユーザー側は以上です。
MaxScale構成ファイルの準備
イメージを開始する前に、作業用の構成ファイルをコンテナーにマップする必要があります。コンテナで提供される最小限の構成ファイルは、必要なリバースプロキシを構築するのに役立ちません。したがって、構成ファイルは事前に準備する必要があります。
次のリストは、構成ファイルを作成するために必要な基本情報を収集するのに役立ちます。
- クラスタータイプ-MaxScaleは、MariaDBレプリケーション(マスタースレーブ、マスターマスター)、Galeraクラスター、Amazon Aurora、MariaDB ColumnStore、およびNDBクラスター(別名MySQLクラスター)をサポートします。
- バックエンドIPアドレスおよび/またはホスト名-すべてのバックエンドサーバーの到達可能なIPアドレスまたはホスト名。
- ルーティングアルゴリズム-MaxScaleは、2種類のクエリルーティング(ラウンドロビンでの読み取り/書き込み分割と負荷分散)をサポートしています。
- MaxScaleでリッスンするポート-デフォルトでは、MaxScaleはラウンドロビン接続にポート4006を使用し、読み取り/書き込み分割接続に4008を使用します。必要に応じてUNIXソケットを使用できます。
現在のディレクトリに、maxscale.cnfというテキストファイルを作成して、起動時にコンテナにマップできるようにします。次の行をファイルに貼り付けます:
########################
## Server list
########################
[mariadb1]
type = server
address = 192.168.0.91
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb2]
type = server
address = 192.168.0.92
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb3]
type = server
address = 192.168.0.93
port = 3306
protocol = MariaDBBackend
serv_weight = 1
#########################
## MaxScale configuration
#########################
[maxscale]
threads = auto
log_augmentation = 1
ms_timestamp = 1
syslog = 1
#########################
# Monitor for the servers
#########################
[monitor]
type = monitor
module = mariadbmon
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
auto_failover = true
auto_rejoin = true
enforce_read_only_slaves = 1
#########################
## Service definitions for read/write splitting and read-only services.
#########################
[rw-service]
type = service
router = readwritesplit
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
max_slave_connections = 100%
max_sescmd_history = 1500
causal_reads = true
causal_reads_timeout = 10
transaction_replay = true
transaction_replay_max_size = 1Mi
delayed_retry = true
master_reconnection = true
master_failure_mode = fail_on_write
max_slave_replication_lag = 3
[rr-service]
type = service
router = readconnroute
servers = mariadb1,mariadb2,mariadb3
router_options = slave
user = maxscale
password = my_s3cret
##########################
## Listener definitions for the service
## Listeners represent the ports the service will listen on.
##########################
[rw-listener]
type = listener
service = rw-service
protocol = MariaDBClient
port = 4008
[ro-listener]
type = listener
service = rr-service
protocol = MariaDBClient
port = 4006
すべてのセクションについて少し説明します:
- サーバーリスト-バックエンドサーバー。このクラスターのすべてのMariaDBサーバーを独自のスタンザで定義します。スタンザ名は、サービス定義をさらに下に指定するときに使用されます。コンポーネントタイプは「サーバー」である必要があります。
- MaxScale構成-MaxScale関連のすべての構成をそこで定義します。
- 監視モジュール-MaxScaleがバックエンドサーバーを監視する方法。コンポーネントタイプは、「monitor」の後に監視モジュールのいずれかが続く必要があります。サポートされているモニターのリストについては、MaxScale2.3モニターを参照してください。
- サービス-クエリをルーティングする場所。コンポーネントタイプは「サービス」である必要があります。サポートされているルーターのリストについては、MaxScale2.3ルーターを参照してください。
- リスナー-MaxScaleが着信接続をリッスンする方法。ポートまたはソケットファイルにすることができます。コンポーネントタイプは「リスナー」である必要があります。通常、リスナーはサービスに関連付けられています。
したがって、基本的には、MaxScaleが2つのポート4006と4008でリッスンするようにします。ポート4006は、特にラウンドロビン接続用であり、MariaDBレプリケーションの読み取り専用ワークロードに適しており、ポート4008は、特に重要な読み取りおよび書き込みワークロード用です。また、フェイルオーバー、スイッチオーバー、またはスレーブの再参加が発生した場合に、MaxScaleを使用してレプリケーションに対するアクションを実行するため、「mariadbmon」と呼ばれるモニターモジュールを使用します。
コンテナの実行
これで、スタンドアロンのMaxScaleコンテナを実行する準備が整いました。 -vを使用して構成ファイルをマップし、リスナーポート4006と4008の両方を公開していることを確認します。オプションで、ポート8989でMaxScaleRESTAPIインターフェイスを有効にできます。
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
確認方法:
$ docker logs -f maxscale
...
2019-06-14 07:15:41.060 notice : (main): Started REST API on [127.0.0.1]:8989
2019-06-14 07:15:41.060 notice : (main): MaxScale started with 8 worker threads, each with a stack size of 8388608 bytes.
上記のログを確認するときにエラーが表示されないことを確認してください。 docker-proxyプロセスが公開されたポート(4006、4008、および8989)でリッスンしているかどうかを確認します:
$ netstat -tulpn | grep docker-proxy
tcp6 0 0 :::8989 :::* LISTEN 4064/docker-proxy
tcp6 0 0 :::4006 :::* LISTEN 4092/docker-proxy
tcp6 0 0 :::4008 :::* LISTEN 4078/docker-proxy
この時点で、MaxScaleが実行されており、クエリを処理できます。
MaxCtrl
MaxCtrlは、通信にMaxScaleRESTAPIを使用するMaxScaleのコマンドライン管理クライアントです。これは、従来のMaxAdminコマンドラインクライアントの代替ソフトウェアとなることを目的としています。
MaxCtrlコンソールに入るには、コンテナ内で「maxctrl」コマンドを実行します。
$ docker exec -it maxscale maxctrl
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬─────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴─────────────┘
すべてが正常かどうかを確認するには、次のコマンドを実行するだけです。
maxctrl: list servers
maxctrl: list services
maxctrl: list filters
maxctrl: list sessions
すべてのコンポーネントの詳細を取得するには、代わりに「show」コマンドをプレフィックスとして付けます。例:
maxctrl: show servers
┌──────────────────┬──────────────────────────────────────────┐
│ Server │ mariadb3 │
├──────────────────┼──────────────────────────────────────────┤
│ Address │ 192.168.0.93 │
├──────────────────┼──────────────────────────────────────────┤
│ Port │ 3306 │
├──────────────────┼──────────────────────────────────────────┤
│ State │ Slave, Running │
├──────────────────┼──────────────────────────────────────────┤
│ Last Event │ new_slave │
├──────────────────┼──────────────────────────────────────────┤
│ Triggered At │ Mon, 17 Jun 2019 08:57:59 GMT │
├──────────────────┼──────────────────────────────────────────┤
│ Services │ rw-service │
│ │ rr-service │
├──────────────────┼──────────────────────────────────────────┤
│ Monitors │ monitor │
├──────────────────┼──────────────────────────────────────────┤
│ Master ID │ 5001 │
├──────────────────┼──────────────────────────────────────────┤
│ Node ID │ 5003 │
├──────────────────┼──────────────────────────────────────────┤
│ Slave Server IDs │ │
├──────────────────┼──────────────────────────────────────────┤
│ Statistics │ { │
│ │ "connections": 0, │
│ │ "total_connections": 0, │
│ │ "persistent_connections": 0, │
│ │ "active_operations": 0, │
│ │ "routed_packets": 0, │
│ │ "adaptive_avg_select_time": "0ns" │
│ │ } │
├──────────────────┼──────────────────────────────────────────┤
│ Parameters │ { │
│ │ "address": "192.168.0.93", │
│ │ "protocol": "MariaDBBackend", │
│ │ "port": 3306, │
│ │ "extra_port": 0, │
│ │ "authenticator": null, │
│ │ "monitoruser": null, │
│ │ "monitorpw": null, │
│ │ "persistpoolmax": 0, │
│ │ "persistmaxtime": 0, │
│ │ "proxy_protocol": false, │
│ │ "ssl": "false", │
│ │ "ssl_cert": null, │
│ │ "ssl_key": null, │
│ │ "ssl_ca_cert": null, │
│ │ "ssl_version": "MAX", │
│ │ "ssl_cert_verify_depth": 9, │
│ │ "ssl_verify_peer_certificate": true, │
│ │ "disk_space_threshold": null, │
│ │ "type": "server", │
│ │ "serv_weight": "1" │
│ │ } │
└──────────────────┴──────────────────────────────────────────┘
データベースへの接続
アプリケーションのデータベースユーザーには、MaxScaleホストを付与する必要があります。これは、MariaDBサーバーの観点からは、MaxScaleホストしか認識できないためです。写真にMaxScaleがない次の例を考えてみましょう。
- データベース名:myapp
- ユーザー:myapp_user
- ホスト:192.168.0.133(アプリケーションサーバー)
ユーザーがMariaDBサーバー内のデータベースにアクセスできるようにするには、次のステートメントを実行する必要があります。
MariaDB> CREATE USER 'myapp_user'@'192.168.0.133' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.133';
写真のMaxScaleでは、代わりに次のステートメントを実行する必要があります(アプリケーションサーバーのIPアドレスをMaxScale IPアドレス192.168.0.200に置き換えます):
MariaDB> CREATE USER 'myapp_user'@'192.168.0.200' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.200';
アプリケーションから、データベースへの接続に使用できる2つのポートがあります。
- 4006-ラウンドロビンリスナー、読み取り専用ワークロードに適しています。
- 4008-書き込みワークロードに適した読み取り/書き込み分割リスナー。
アプリケーションでMySQLポートを1つだけ指定できる場合(Wordpress、Joomlaなど)、代わりにRWポート4008を選択してください。これは、クラスタータイプに関係なく、最も安全なエンドポイント接続です。ただし、アプリケーションが複数のMySQLポートへの接続を処理できる場合は、読み取りをラウンドロビンリスナーに送信できます。このリスナーは、読み取り/書き込み分割リスナーと比較すると、オーバーヘッドが少なく、はるかに高速です。
MariaDBレプリケーションのセットアップでは、データベースのホスト/ポートの組み合わせとして、これらのエンドポイントのいずれかに接続します。
- 192.168.0.200ポート4008-MaxScale-読み取り/書き込みまたは書き込み専用
- 192.168.0.200ポート4006-MaxScale-バランスの取れた読み取り専用
- 192.168.0.91ポート3306-MariaDBサーバー(マスター)-読み取り/書き込み
- 192.168.0.92ポート3306-MariaDBサーバー(スレーブ)-読み取り専用
- 192.168.0.93ポート3306-MariaDBサーバー(スレーブ)-読み取り専用
Galera ClusterやNDBClusterなどのマルチマスタークラスタータイプの場合、代わりにポート4006をマルチ書き込み平衡接続として使用できます。 MaxScaleを使用すると、データベースに接続するときに選択できる多くのオプションがあり、それぞれに独自の利点があります。
DockerSwarmを使用したMaxScaleクラスタリング
Docker Swarmを使用すると、SwarmConfigとともに複数のレプリカを使用してSwarmサービスを介してMaxScaleインスタンスのグループを作成できます。まず、構成ファイルをSwarmにインポートします:
$ cat maxscale.conf | docker config create maxscale_config -
確認方法:
$ docker config inspect --pretty maxscale_config
次に、MaxScaleデータベースユーザーに、ネットワーク内の任意のSwarmホストから接続することを許可します。
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
MariaDB> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
MaxScaleのSwarmサービスを起動するときに、以下のように同じ構成ファイルにマッピングする複数のコンテナー(レプリカと呼ばれる)を作成できます。
$ docker service create \
--name maxscale-cluster \
--replicas=3 \
--publish published=4008,target=4008 \
--publish published=4006,target=4006 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale
上記は、Swarmノード全体に広がる3つのMaxScaleコンテナを作成します。確認方法:
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
yj6u2xcdj7lo maxscale-cluster replicated 3/3 mariadb/maxscale:latest *:4006->4006/tcp, *:4008->4008/tcp
アプリケーションがSwarmネットワーク内で実行されている場合は、アプリケーションのデータベースホストとしてサービス名「maxscale-cluster」を使用できます。外部的には、公開されたポート上の任意のDockerホストに接続でき、Swarmネットワークは、ラウンドロビン方式で接続を正しいコンテナーにルーティングしてバランスを取ります。この時点で、私たちのアーキテクチャは次のように説明できます。
第2部では、サービス制御、構成管理、クエリ処理、セキュリティ、クラスター調整など、DockerでのMaxScaleの高度なユースケースを見ていきます。