mysql:14143
From: "Kensuke Kaneko" <"Kensuke Kaneko" <kyanny@xxxxxxxxxx>>
Date: Tue, 31 Jul 2007 18:18:32 +0900
Subject: [mysql 14143] Re: アプリケーションレベルでの書き込みの分散について
こんにちは。株式会社ライブドアの金子と申します。
「アプリケーションレベルでの」ということなので、実際に SQL を発行している部分でがんばる方法を検討してみてはどうでしょうか。
user_write1 にまず書き込んでみて、成功ならば user
にも書き込み、両方ともコミット。失敗ならば、ロールバックしてどちらも書き込みせず。というふうにすれば、一貫性を保てると思います。
以下は Perl の DBI モジュールを利用した場合のサンプルコードです。ただし、実際に動かして検証したものではないので、あくまで参考程度ということで、お願いします。(つまり間違っている可能性があります)
my $dbh = DBI->connect(@connect_info_for_user);
$dbh->{AutoCommit} = 0;
if ($user_id < 100000) {
my $dbh_for_user_write1 = DBI->connect(@connect_info_for_user_write1);
$dbh_for_user_write1->{AutoCommit} = 0;
my $sth = $dbh_for_user_write1->prepare("INSERT INTO user_write1 ...");
my $rv = $sth->execute(@bind_params);
if ($rv) {
my $sth = $dbh->prepare("UPDATE user SET ... WHERE ...");
$sth->execute;
$dbh->commit;
$dbh_for_user_write1->commit;
}
else {
$dbh_for_user_write1->rollback;
}
}
else {
my $dbh_for_user_write2 = DBI->connect(@connect_info_for_user_write2);
$dbh_for_user_write1->{AutoCommit} = 0;
# ...
}
ところどころはしょってあるので、環境にあわせて具体的な値で補って読んでください。
やっていることは、接続する DB を user_id の値によって変える、 AutoCommit をオフにする、だけなので、 Perl
ならば Class::DBI や DBIx::Class のような O/R
マッパを使った場合でも可能でしょうし(むしろ使ったほうが良いです) PHP や Ruby などでも、同じことができると思います。(有名な
O/R マッピングライブラリにはそういう機能があるはずです)
以下、参考になりそうな URL です(DBI モジュールのドキュメント)
http://search.cpan.org/~timb/DBI-1.58/DBI.pm#connect
http://search.cpan.org/~timb/DBI-1.58/DBI.pm#AutoCommit_(boolean)
http://search.cpan.org/~timb/DBI-1.58/DBI.pm#commit
07/07/30 に Hiroyuki Yamada<yamahiroyu.y@xxxxxxxxxx> さんは書きました:
> MySQLにおける書き込みの分散について質問させてください。
>
> 現在、書き込みが多いサーバーを運用しており、
> その書き込みをアプリケーションレベルで複数マシンに分散させたいとおもっております。
>
>
> 考えている手段としては、ユーザごとに書き込み先を分散させる方法で、
> 例えば、
>
> user_id 1-100000 => マシン1へ書き込み
> user_id 100001-200000 => マシン2へ書き込み
>
> のようなことです。
>
> 例えば、2つのテーブルがあるとして、
> (現状は、もうちょっと複雑ですが、説明をわかりやすくするために、2つのテーブルで説明します。)
>
> user - ユーザのプロファイル等(書き込み少ない)
> user_write - ユーザの書き込み履歴(書き込み多い)
>
> user への書き込みはあまりなく、user_writeへの書き込みがとても多い状況なので、
> user_writeのみを分散したいと考えています。
>
>
> --------
> user
> --------
>
> --------------- ---------------
> user_write1 user_write2
> --------------- ---------------
>
>
> この際、user_write1 と user を一貫性を保ったまま更新したい場合は
> どのようにするのが一般的でしょうか?
> (両方とも成功する必要があり、片方の失敗は許されない)
>
> MySQL5からのtwo phase commit はこのような複数マシンをまたがったような
> トランザクションにも対応できるのでしょうか?
>
>
> よく出てくるmixiの例などは参考にしていますが、
> (http://blog.livedoor.jp/nipotan/archives/50538571.html)
> 複数マシンへの書き込みに関しては具体的な方法がないので、
> ちょっと困っております。
>
>
> みなさんなら、こういう状況でどうされますでしょうか?
> ご教授ください
>
> Hiroyuki Yamada
>
>
--
Kensuke Kaneko <kyanny@xxxxxxxxxx>
14138 2007-07-30 12:21 ["Hiroyuki Yamada" <y] アプリケーションレベルでの書き込みの分散について 14142 2007-07-31 15:00 ┣["T.Hirotsu" <hirotsu] -> 14143 2007-07-31 18:18 ┣["Kensuke Kaneko" <ky] 14144 2007-07-31 21:26 ┃┗["T.Hirotsu" <hirotsu] 14145 2007-07-31 23:53 ┃ ┗["Hiroyuki Yamada" <y] 14151 2007-08-01 12:04 ┗[<ikari-ml@xxxxxxxxxx] [meiwaku#]Re: アプリケーションレベルでの書き込みの分散について