RailsでロードバランサなしにMySQL のスレーブサーバ群を利用できる、EbisuConnectionを作りました

Tsukasa OISHI

最近、ロードバランサ経由でMySQLのスレーブサーバ群を利用できる、FreshConnectionというライブラリを作っています。
これを利用して、ロードバランサなしにスレーブサーバが使えるようになるライブラリ、EbisuConnectionを作りました。世の中には octopus のように、スレーブサーバが使えるようになるライブラリはたくさんありますが、EbisuConnectionは機能をシンプルに保っています。それほどいろいろな機能が必要ないという方にはいいかもしれません。

https://github.com/tsukasaoishi/ebisu_connection

ロードバランサ経由でスレーブを使うFreshConnectionを作っているのに、ロードバランサなしのライブラリを作ったのは、誰もがロードバランサを使える環境にないからです。余計なハードウェアを増やしたくなかったり、データの流量が膨大すぎてロードバランサがパンクしてしまう環境の人などがいたりします。

EbisuConnectionには以下の特徴があります。

* SELECT系クエリはスレーブサーバへ投げる
* それぞれのスレーブサーバへのバランシングに重み付けができる
* 設定ファイルを変更すれば、Railsの再起動なしにほぼ動的に反映される

EbisuConnectionRails3.2.16とRails4.0.2で動作確認はしています。使いたいときはGemfileに以下を追加してください。

gem "ebisu_connection"

つぎにconfig/database.ymlでスレーブサーバで共通している項目を設定をします。

production:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: kaeru
  pool: 5
  username: master
  password: master
  host: localhost
  socket: /var/run/mysqld/mysqld.sock

  slave:
    username: slave
    password: slave

FreshConnectionと同様に、slaveの位置に設定します。指定していない項目はmasterのものが使用されます。

各スレーブサーバはconfig/slave.yamlで指定します。

- "slave1, 10"
- "slave2, 20"
-
  host: "slave3"
  weight: 30

サーバごとの設定を配列で指定します。
単純に文字列だけを置いた場合は、

  "ホスト名, 重み"

と解釈されます。重みが大きいサーバほど頻繁にクエリが割り振られます。

config/slave.yamlの更新日時が変更になったとき、EbisuConnectionはコネクションをすべて切断し、設定を読み直して次のアクションの処理から新しい設定で接続しなおします。
これはRack内で行っているため、バッチ等では設定の動的反映はききません。