Help us understand the problem. What is going on with this article?

MySQL互換でマルチマスタ同期レプリケーションが可能なPercona XtraDB Clusterで手軽に冗長構成RDBを構築

More than 5 years have passed since last update.

はじめに

みなさんMySQLを使うとき、冗長化はどうしてますか?
Master-Slaveのレプリケーションを頑張って組むか、RDSみたいなフルマネージドサービスを使うか、選択肢は色々あります。

この記事ではシンプルな構成で簡単にMySQL互換の冗長化クラスタを構築する方法を紹介します。
Master-Slaveのように複雑でなく明瞭簡潔なので、構築・運用も楽になります。
コストや自由度の面からRDSはちょっと、という人にもいいかもしれません。

細かくいうと、全ノード書き込み可能なマルチマスタで、同期的にレプリケーションを行うRDBクラスタを構築します。
もちろんトランザクションも処理できますし、障害時にフェイルオーバが発生せずダウンタイムが少ないという特徴もあります。
Percona XtraDB ClusterというオープンソースのRDBMSを使用して構築します。

MySQLフォーク

細かいことは省きますがMySQLの開発元がなんだかんだでOracleになってから、MySQLフォークの開発が盛んになっています。
また、多くのLinuxディストリビューションが標準データベースにMySQLではなくMySQLフォークを選択するようになりました。

MySQLフォークとは、ソースコードが公開されているMySQLから派生したRDBMSです。
特に有名なのは、InnoDBの代替ストレージエンジンのXtraDBを使用しているMariaDBPercona Serverの2つです。

MariaDBはRed Hat Enterprise Linux 7の標準DBとして採用されたことでも注目されています。

PerconaもMariaDBも、簡単にいうと性能強化されたMySQL互換のRDBMSです。
そのため、MySQLからこれらのDBに乗り換えるだけで性能をあげることも可能です。

MariaDBは独自進化に向かっているのに対して、PerconaはOracleのMySQL Enterpriseに完全互換で強化を施した製品を目指しています。
(MariaDBはそのうちまたMySQL互換に寄せていくといってるらしいですが)

Percona製品はPercona社が開発しています。
Percona社はPercona Server以外にもXtraDB、XtraDB Cluster、XtraBackup、Toolkitなど周辺ツールも開発しています。
MariaDBに比べてPercona Serverは日本ではマイナーですが、XtraBackupやToolkitは使っているという方も多いんじゃないでしょうか。

次の理由から私はPerconaの方が好きなので、この記事でもPerconaで冗長化クラスタを組む方法を紹介したいと思います。

  • 強いMySQL互換を目指している
  • データベースエンジンや周辺ツールも同社で開発している
  • 実際使ってみてPercona Serverの方が完成度が高く感じる
  • 名前がかっこいい(XtraDB!!)

Percona XtraDB Cluster

Percona Server

MySQLフォークのところでも説明しましたが、Percona ServerはMySQLを元にPercona社が開発しているRDBMSです。
InnoDBの代わりにXtraDBというストレージエンジンを使用していて、

  • 性能
  • スケーラビリティ
  • 信頼性
  • 機能
  • 管理

などが強化されています。

ベンチマークを見るととてもわかりやすいです。
(Percona社が出してるものですが、、)

Percona社は、元々MySQLのコンサルで実績のある会社です。
技術者が世界各地に点在していて、世界中で活動しています。

Percona XtraDB Cluster

Percona XtraDB Clusterは、Percona Serverを元に冗長化クラスタを構築するためのパッケージです。

次のコンポーネントが同梱されています。

  • Percona Server
  • Galera Library
  • wsrep API
  • Percona XtraBackup

Galera LibraryCordership Oy社が開発しているマルチマスタ同期レプリケーションを実現するためのライブラリです。
Galera Libraryを使うことで、簡単に冗長化を行うことができます。

wsrep API(Write Set Replication API)はマルチマスタ同期レプリケーションのための標準APIです。
レプリケーションプロバイダとアプリケーション間のAPIを定義しています。

マルチマスタ同期レプリケーション

Percona XtraDB Clusterではアクティブ-アクティブなマルチマスタ同期レプリケーションを実現できます。
つまり、クラスタを構成する全ノードがマスタであり、全ノードで書き込み/読み込みが可能で、全ノード間で同期的にレプリケーションが行われます。
ここが一般的なMySQLの冗長化とは異なる部分です。

MariaDB、MySQLでもGaleraを使用したマルチマスタ同期レプリケーションクラスタが構築可能です。

全ノードがアクティブであるため、障害時にFailoverが発生することもなくダウンタイムがありません。
また、動的にノードの追加・削除が可能なため、無停止での設定変更やバージョンアップを行うことができます。
そしてこれらの操作も非常にシンプルです。

CAP定理でいうと、GaleraはCA、つまり一貫性と可用性を実現しています。
トランザクション処理のためのACID特性も保証されています。

Split Brainも発生しないように設計されており、信頼性の高いシステムが構築できます。

作るもの

前置きが長かったですが、ここから実際に構築していきます。

今回はVagrantで複数のVMを立ち上げ、クラスタを構築します。
そして最後にRailsのアプリケーションからクラスタにアクセスします。

構成

構成は次の図のようになります。

20141223 PXC.001.png

VagrantでVM(CentOS 7)を3台立ち上げ、各VMにPercona XtraDB Cluster(PXC)をインストールします。
その3台でクラスタを構築します。
(3台というのはPerconaが推奨しているクラスタの最小構成数です)

Railsアプリ用にも1台VMを立ち上げ、RailsアプリからはHAProxyを経由してDBにアクセスするようにします。

バージョン

今回使用したソフトウェアのバージョンは次の通りです。

  • Vagrant 1.7.1
  • VirtualBox 4.3.18
  • CentOS 7.0
  • Percona XtraDB Cluster 5.6.21
  • Percona XtraBackup 2.2.7
  • Galera 3.8

Percona XtraDB Cluster構築

まずは、PXCを構築します。

1. VagrantでCentOS起動

PXC入りCentOS 7を3台立ち上げるVagrantfileをGistに用意したので、そちらを使ってください。
https://gist.github.com/nownabe/27ffdd8fed6a3f1707e8

$ mkdir pxc_demo
$ cd pxc_demo
$ curl -O https://gist.githubusercontent.com/nownabe/27ffdd8fed6a3f1707e8/raw/62df5d42e00c483f8cbaa3818e7e5eb092836f85/Vagrantfile
$ vagrant up

少し時間がかかります。

(おまけ) Percona XtraDB Clusterのインストール

今回はVagrantfileのprovisionで自動でインストールしましたが、手動でインストールするときは次の手順になります。
(と言ってもVagrantfileに書いてある内容そのままですが)

$ sudo yum install -y epel-release
$ sudo yum install -y http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
$ sudo yum install -y Percona-XtraDB-Cluster-56

epelは、PXCと依存関係のあるsocatインストールで必要になります。

2. my.cnf

次に、PXC用の/etc/my.cnfを説明します。
上記のVagrantfileを使用した場合は、すでに設定されているのでここは眺めるだけでOKです。

wsrep_node_addressのみ各ノードごとに異なります。

/etc/my.cnf
[mysqld]

datadir=/var/lib/mysql
user=mysql

# Galera Libraryのパス
wsrep_provider=/usr/lib64/libgalera_smm.so

# クラスタを構成するノードのアドレス
wsrep_cluster_address=gcomm://10.6.3.101,10.6.3.102,10.6.3.103

# Galeraを使うときはROWにする必要があります
binlog_format=ROW

# Galeraが正式にサポートしているのはInnoDBだけです(Perconaは内部的にはXtraDBを使っています)
default_storage_engine=InnoDB

# これもGaleraの要件です
innodb_autoinc_lock_mode=2

# ノードのアドレス
wsrep_node_address=10.6.3.101

# SSTにxtrabackupを使用します。SSTはPXCにおけるノード間データ転送のひとつで、rsync、mysqldumpも使えます。
wsrep_sst_method=xtrabackup-v2

# クラスタ名
wsrep_cluster_name=pxcdemo

# SSTの認証情報
wsrep_sst_auth="sstuser:s3cret"

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

3. クラスタ起動

3.1 クラスタ初回起動について

今回クラスタの起動で2つの特殊な操作を行います。

  • 1台目の起動
  • SST用ユーザの作成

これらはクラスタの初回起動時に必要な操作になります。

まず、1台目の起動について説明します。

PXCでは普通にサービスを起動すると、/etc/my.cnfwsrep_cluster_addressを見て、それらのいずれかのノードに接続しに行きます。
しかし、クラスタに1台もノードがいない状態だと接続に失敗し、起動自体にも失敗します。
そのため1台目だけは特別なコマンドで起動を行う必要があります。

次はSST用ユーザの作成について説明します。

2台目以降のPXCは起動するとwsrep_cluster_addressをみてクラスタに接続します。
そして、SST(Snapshot State Transfer)によりクラスタのいずれかのノードからデータを同期します。
同期が完了するとクラスタのメンバーとして稼働し始めます。

今回の設定だとSSTに認証が必要なため、 接続される側でSST用のユーザを作っておく必要があります。
2台目以降にはユーザ情報も自動で同期されるので、1台目で1度作ればOKです。

3.2 1台目起動

では1台目を起動します。

$ vagrant ssh pxcnode-01 -c 'sudo systemctl start mysql@bootstrap'

1台目はsystemctl start mysql@bootstrapというコマンドで起動します。
CentOS 6の場合は、service mysql bootstrap-pxcになります。

SST用のユーザを作成します。

$ vagrant ssh pxcnode-01 -c 'mysql -uroot'
mysql> create user 'sstuser'@'localhost' identified by 's3cret';
mysql> grant RELOAD, LOCK TABLES, REPLICATION CLIENT on *.* to 'sstuser'@'localhost';
mysql> flush privileges;
mysql> exit

3.3 2台目、3台目起動

2台目と3台目は普通に起動します。

$ vagrant ssh pxcnode-02 -c 'sudo systemctl start mysql'
$ vagrant ssh pxcnode-03 -c 'sudo systemctl start mysql'

起動すると、自動でpxcnode-01からSSTによるデータ同期が始まります。
今回はほとんどデータがない状態なのですぐ終わります。

4. 動作確認

3つのノードで書き込みと確認を行っていきます。

まず、#1でデータベースを作成します。

$ vagrant ssh pxcnode-01 -c 'mysql -uroot -e "create database demo"'

#2で作成されたデータベースを確認し、テーブルを作成します。

$ vagrant ssh pxcnode-02 -c 'mysql -uroot -e "show databases"'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| demo               |
| mysql              |
| performance_schema |
| test               |
+--------------------+
$ vagrant ssh pxcnode-02 -c 'mysql -uroot demo -e "create table demotable (name varchar(64))"'

#3でテーブルを確認し、挿入します。

$ vagrant ssh pxcnode-03 -c 'mysql -uroot demo -e "show tables"'
+----------------+
| Tables_in_demo |
+----------------+
| demotable      |
+----------------+
$ vagrant ssh pxcnode-03 -c 'mysql -uroot demo -e "insert into demotable values (\"from #03\")"'

#1で挿入したデータを確認します。
また、Rais用のユーザとHAProxyのヘルスチェック用のユーザも作成しておきます。

$ vagrant ssh pxcnode-01 -c 'mysql -uroot demo -e "select * from demotable"'
+----------+
| name     |
+----------+
| from #03 |
+----------+
$ vagrant ssh pxcnode-01 -c "mysql -uroot -e \"grant all privileges on *.* to 'demo'@'%'\""
$ vagrant ssh pxcnode-01 -c "mysql -uroot -e \"grant usage on *.* to 'haproxy'@'%'\""

こんな感じで、Percona XtraDB Clusterを使うと手軽に冗長構成RDBを構築することができます。

アプリケーションからアクセス

1. VagrantでCentOS起動

HAProxy + Rails用のVMを立ち上げます。
Rubyをビルドするので、少し時間がかかります。

$ mkdir pxc_demo_rails
$ cd pxc_demo_rails
$ curl -o Vagrantfile https://gist.githubusercontent.com/nownabe/27ffdd8fed6a3f1707e8/raw/5f66c1301a7f093ec7d99caff40584ed8a4a03ea/Vagrantfile-ruby
$ vagrant up

2. HAProxy設定

HAProxyの設定ファイルを編集して、サービスを起動します。
これもGistにあるので、ダウンロードして使ってください。

$ vagrant ssh -c 'sudo curl -o /etc/haproxy/haproxy.cfg https://gist.githubusercontent.com/nownabe/27ffdd8fed6a3f1707e8/raw/14d7f25fbd76c554c451610f2ac033bf809297bf/haproxy.cfg'
$ vagrant ssh -c 'sudo systemctl start haproxy'

以下、コンフィグの解説(抜粋)です。

haproxy.cfg
# HAProxyのステータスをWebで見れるようにする設定です
listen hastats *:80
    mode http
    maxconn 64
    timeout connect 5000
    timeout client 10000
    timeout server 10000
    stats enable
    stats show-legends
    stats uri /haproxy?hastats

    # ステータス画面のユーザ名とパスワードを設定しています
    stats auth admin:p@ssw0rd

# MySQLの分散設定です
listen mysql *:3306
    mode tcp

    # mysql-checkという専用のヘルスチェック方式で、MySQLサーバに負荷をかけないようにしています
    option mysql-check user haproxy

    # ラウンドロビンでPXCの3ノードに分散します
    balance roundrobin
    server pxcnode-01 10.6.3.101 check
    server pxcnode-02 10.6.3.102 check
    server pxcnode-03 10.6.3.103 check

Railsアプリを作成する前に、ちゃんと負荷分散できてるか確認してみましょう。
次のコマンドでPXCから接続先のIPが取得できます。

$ vagrant ssh -c "mysql -udemo -h 127.0.0.1 -e 'show variables like \"wsrep_provider_options\"' | tail -1 | awk '{print \$4}'"
10.6.3.101;
$ vagrant ssh -c "mysql -udemo -h 127.0.0.1 -e 'show variables like \"wsrep_provider_options\"' | tail -1 | awk '{print \$4}'"
10.6.3.102;
$ vagrant ssh -c "mysql -udemo -h 127.0.0.1 -e 'show variables like \"wsrep_provider_options\"' | tail -1 | awk '{print \$4}'"
10.6.3.103;
$ vagrant ssh -c "mysql -udemo -h 127.0.0.1 -e 'show variables like \"wsrep_provider_options\"' | tail -1 | awk '{print \$4}'"
10.6.3.101;

ちゃんとラウンドロビンで分散されていることがわかります。

ブラウザでhttp://10.6.3.100/haproxy?hastatsにアクセスしてユーザとパスワードを入力すると、HAProxyのステータスが表示されます。
mysqlのSessionsのTotalを見ると、どのPXCノードに何回接続したかを確認できます。

スクリーンショット 2014-12-25 0.56.27.png

4. Railsアプリ作成

では、Railsのアプリを作ります。
といってもPXCの動作確認が目的なのでScaffoldだけです。

ここからVMにSSHでログインして作業します。

$ vagrant ssh

まずはRailsアプリを作成しましょう。

$ rails new pxcdemo -d mysql -B
$ cd pxcdemo
$ echo "gem 'therubyracer', platform: :ruby" >> Gemfile
$ bundle install --path vendor/bundle
$ bundle exec rails g scaffold article title:string author:string body:text

config/database.ymlを書き換えます。

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: demo
  password:
  host: 127.0.0.1

development:
  <<: *default
  database: demo

Migrateしてサーバを起動します。

$ bundle exec rake db:migrate
$ bundle exec rails s -b 0.0.0.0

5. 動作確認

Railsのサーバが起動できたら、ブラウザでhttp://10.6.3.100:3000/articlesにアクセスして、適当にデータ入力してみてください。
スクリーンショット 2014-12-25 0.53.35.png

HAProxyのステータス画面(http://10.6.3.100/haproxy?hastats)にアクセスすると、接続数が増えてることがわかります。

こんな感じで、HAProxyを使うことで簡単にアプリからPercona XtraDB Clusterにアクセスすることができます。
HAProxyを各アプリケーションサーバに同居させることで、単一障害点を排除できます。

おわりに

長くなりましたが、以上です。
Percona XtraDB Clusterの構築方法と、アプリからの使用方法を書いてみました。

PXCを使うと本当に簡単に冗長化・負荷分散が実現できるので超おすすめです。
是非使ってみてください。

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした