MariaDB Galera Clusterを動かしてみた

YAPCに参加したときに @yoku0825 さんに、とりあえずふわっとホスティングの領域で使える止まらないDBほしいんすよね〜って雑に話したら、MariaDB Galera Clusterを教えてもらったので試してみた。

こんな感じで雑にベンチを取れるようにしてあります。

$ docker-compose up
$ docker-compose exec node-1 /bin/bash
% bench

MariaDB Galera Clusterとはなんぞやっていう話は色々記事があるのだけど、マルチマスターなクラスターで、3台以上で構成され、ノードの追加時は特に何もしなくても自動で実行される同期さえ終われば、ノードが追加されるという夢みたいなDBクラスターです。

$ docker-compose exec node-1 mysql -e "create database pyama_db"
$ docker-compose exec node-2 mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| pyama_db           |
| test               |
+--------------------+

これはnode-1からcreate databaseして、それがnode-2に同期されているという話なのですが、それがすごく簡単に出来るんですよね。こんな感じの設定ファイルを書いて

[galera]
wsrep_on=ON
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_name=DBCLUSTER
wsrep_sst_method=rsync
wsrep_slave_threads=2
wsrep_cluster_address=gcomm://node-1,node-2,node-3

1台目の起動でクラスタの初期化。

$ sudo -u mysql mysqld --wsrep-new-cluster

2台目移行はなんと普通にmysql起動するだけです。

$ sudo -u mysql mysqld

簡単すぎてうけませんか?

一方でマルチマスターであるがゆえに、テーブル単位のロックが出来ないなどいくつかの制約はあります。

それらの制約を避けるために MaxScaleと組み合わせて 書き込みは単一のノードに行い、リードは分散させるという構成を取るのがベターなようです。

制約の詳細についてはこちらをご確認下さい。

気になる性能ですがsysbenchをこんな感じで実行し、3ノード構成のクラスタと、スタンドアローン構成で比較してみました。

クラスタ

SQL statistics:
    queries performed:
        read:                            305130
        write:                           79243
        other:                           51527
        total:                           435900

スタンドアローン

SQL statistics:
    queries performed:
        read:                            594454
        write:                           169844
        other:                           84922
        total:                           849220

read,write共にスタンドアラーンと比較して2倍程度の性能劣化があるようです。readについてはスケールアウトして分散すればよいのですが、writeについては制約条件をクリアするために単一ノードで実行する必要があるので、サイジングを工夫するなどの対応が必要そうです。

次に、疑問に思ったのが、構築のときに特に同期設定など行っていないのに、なぜマルチマスター組めるのだ?という疑問が湧いたのですが、それはこちらに書いてありました。

同期はMariaDB(MySQL)のレプリケーションのレイヤーではなく、GALERA REPLICATION PLUGINによって行われ、グルーピングは GROUP COMMUNICATION PLUGINS によって行われることがわかります。

僕は初めて Amazon Aurora 出てきたときに、なんだこのなど技術は・・・とか思っていたのですが、こういう実装見ると、確かにクエリのレイヤーじゃなくてプロトコルのレイヤーで頑張ればこういうの作れるな・・・という気落ちになりました。

クラスターを試すにあたり、下記の記事が大変参考になりました。

既存のアプリケーションと組み合わせるには制約条件の回避、適用など必要な作業が多そうですが、新規導入であればすんなり動く気がするので、すきがあればプロダクションに突っ込んで見たいと思います。