2012年10月アーカイブ

YAPC::Asiaの前にDBIx::DSN::Resolverってのを書いてリリースしていますが、実際のWebアプリケーションで使うにはキャッシュやDNSRR対応などアプリケーション側でコードを書く必要があって面倒なので、簡単に使えるようラッパーとなるモジュールを書いてリリースしました。

https://metacpan.org/module/DBIx::DSN::Resolver::Cached

DBIx::DSN::Resolver::Cached を使うことでDNSに掛かる負荷を押さえつつ簡単に負荷分散もできます。

use 5.10.0;
use DBIx::DSN::Resolver::Cached;

sub connect_db {
    state $r = DBIx::DSN::Resolver::Cached->new(
        ttl => 30,
        negative_ttl => 10
    );
    $resolver->resolv('dbi:mysql:database=mytbl;host=mixi.jp');
}

say connect_db() for 1..10;

ホスト名解決の結果をキャッシュしつつ、複数のIPが返って来た時はラウンドロビンで使うIPアドレスを選ぶので、上のサンプルを実行すると

dbi:mysql:database=mytbl;host=110.44.x.198
dbi:mysql:database=mytbl;host=110.44.x.199
dbi:mysql:database=mytbl;host=114.31.x.33
dbi:mysql:database=mytbl;host=110.44.x.196
dbi:mysql:database=mytbl;host=110.44.x.197
dbi:mysql:database=mytbl;host=114.31.x.34
dbi:mysql:database=mytbl;host=110.44.x.200
dbi:mysql:database=mytbl;host=114.31.x.32
dbi:mysql:database=mytbl;host=110.44.x.198
dbi:mysql:database=mytbl;host=110.44.x.199

のようになります。名前解決の問い合わせを1度しかしていないのはstraceなどを使うと確認できます。

DBIx::DSN::Resolver::Cached はデフォルトで、Cache::Memory::Simple を使っていますが、これを差し替える事も可能です。

state $r = DBIx::DSN::Resolver::Cached->new(
    cache => Cache::Memcahced::Fast->new(..),
);

このようにすればmemcachedも使えます。

ちなみに、mobageはMyDNSを使ってDNSベースの負荷分散を実現しているようですが、弊社ではMySQLバックエンドなPowerDNSが使えるようになっています

Weighted RoundRobinや負荷分散先のサーバが落ちた時の処理などはこのモジュールではサポートしていません。もっと細かくやりたい場合は DBIx::DSN::Resolver で resolver を弄ったほうが捗ると思います。

YAPC::Asiaのスライドで予告していた通り、実際に弊社のいくつかのサービスで使っている my.cnf を公開しました。

github: https://github.com/kazeburo/mysetup/tree/master/mysql

今回、公開した理由はMySQl Beginners Talksの発表の中でも触れている通りです。MySQLのソースコード中に含まれるサンプルのmy.cnfが最近のサーバハードウェアや運用に合わなくなって来ているという状況で、自分の設定にイマイチ自信が持てていない人は少なくないはず。そこで各社秘伝のタレ的な my.cnf をOpen & Shareすることで、モダンなmy.cnfを作り上げる事ができるんじゃないかという考えの下、今回 github にて公開しました。

mycnf.png

ファイルは4つあり、それぞれ MySQL 4.0、5.1、5.5、そしてテスト中のMySQL 5.6用のMySQLの設定ファイルです。

my.cnf について捕捉

説明がまったくないと公開しても意味がなさそうなので、少し補足です

サーバ環境

このmy.cnfが前提する環境は次の通りです

  • MyISAMは使わず、InnoDBのみ。MySQL 5.1以降ではInnoDB Pluginを使用する
  • サーバは 16GBのメモリを搭載し、そのメモリをMySQLがすべて使える

MyISAM系のメモリ設定は少なめにして、物理メモリの多くをinnodb_buffer_poolに割り振っています

ホスト名とserver-id

この2つの箇所は、サーバに設置する際にプログラムにより置き換えられます

prompt          = '\u@<HOSTNAME> mysql>'
server-id       = <SERVER_ID>

<HOSTNAME> は「\h」でも構わないと思いますが、弊社のサーバではhostnameとサービス上のサーバ名が異なる場合があるので管理サーバに問い合わせて埋め込んでいます。server-idはIPアドレスの第三オクテット、第四オクテットから自動計算されます

IPADDR=$(/sbin/ifconfig |grep -A 1 eth1 |grep inet|awk -F: '{print $2}'|awk '{print $1}')
SID=$(perl -e '@l=split /\./,$ARGV[0];print $l[2]*256+$l[3]' $IPADDR)
HOSTID=$(curl -s http://host-manager/lookup)
sed -i "s/<SERVER_ID>/$SID/" /path/to/my.cnf
sed -i "s/<HOSTNAME>/$HOSTID/" /path/to/my.cnf

チューニングのポイント

サーバによって次のような変更を行っています。

まず、サーバに搭載するメモリによって innodb_buffer_pool を変更します

innodb_buffer_pool = メモリの75%

書籍やWebサイトでは80%程度と書かれていますが、自分が今まで使ってきた環境では75%以上にするとSwapしてしまいます

仮想マシンなどIO性能が落ちる場合は以下の設定を変更します

innodb_write_io_threads = 8 => 少なめに
innodb_read_io_threads = 8 => 少なめに
innodb_log_file_size = 128M => 少なめに
innodb_flush_log_at_trx_commit = 1 => 2に変更

MySQL5.1以降で逆に、SSDなど高速なデバイスが使用する際は

innodb_io_capacity = 2000〜

この設定を追加しています。

さいごに

今回公開したmy.cnfのforkやpullreqは大歓迎です。そして自分も含め、MySQLの設定についての知識がもっと広がっていったらいいなと思っています

5.6!5.6!5.6!

今年も無事にYAPC::Asiaに参加と発表させて頂く事が出来ました。牧さん、941さん、JPAの皆様、ボランティアの皆様、参加した全てのPerl Mongersに感謝です。

今年の発表は、去年のこの時期にやっていたlivedoor Blogのサーバ集約作業とその為につくったツールや自動化について紹介させて頂きました。



質問でも出てきた「作成した移行スクリプトの検証」ですが、メンテナンス時間内にデータベースのコピーが完了するかどうかの検証とあわせて、実際に実行して確認していました。今にして思えばdry-runモードを作ってテストケース書いて確認するぐらいやってもよかったかもしれません。次回(があれば)チャレンジしたいです。

もう一つ言い忘れてましたが、mysql40dumpはMySQL 5.1、5.5でも検証済みで弊社でもヘビーにサーバ運用に使っています。自動でmaster/slaveの情報を埋めてくれるので、レプリケーションを作成する時にかなり便利です。3台〜5台ぐらい同時に作業していても苦になりません。mysql40dumpを作った事でデータベースの集約作業やSlaveサーバの追加作業などの運用がかなり捗っています。

mysql40dumpはgithubにて公開中なのでお試しください:
https://github.com/kazeburo/mysql40dump

あと、予告していた my.cnf も公開しました。MySQLを設定する際の叩き台としてどうぞ:
https://github.com/kazeburo/mysetup


今回のYAPC::Asiaでは、去年より自分の作ったプロダクトやモジュールを他の方が紹介して貰っていたのがうれしいところ。GrowthForecastはいろんなスライドに出てきたし、ProcletDBIx::DSN::Resolverも出て来てました。来年に向けてもっと精進してきたい所存でございます