YAPC::Asia Tokyo 2012 始まりましたね。
それとはあまり関係なく DBIx::DSN::Resolver というモジュールを書いてリリースしました
https://metacpan.org/release/DBIx-DSN-Resolver
何をするモジュールなのかというと、DBIでデータベースに接続する際に使うDSN中のホスト名を名前解決してくれるモジュールです。mobage本でxaicronが書いていたのを参考にして作りました
dbi:mysql:database=mytbl;host=dbserver.local
これを
dbi:mysql:database=mytbl;host=10.9.4.1
と変換してくれます。
また、名前解決する機能を差し替える事ができるので、そこでキャッシュを挟む事も可能です。Cache::Memory::Simpleを使うと以下のように書けます
use Socket;
use DBIx::DSN::Resolver;
use Cache::Memory::Simple;
my $DNS_CACHE = Cache::Memory::Simple->new(
size => 256,
);
my $r = DBIx::DSN::Resolver->new(
resolver => sub {
my $host = shift;
my $ipr = $DNS_CACHE->get($host);
my $ip = $ipr ? $$ipr : undef;
if ( !$ipr ) {
$ip = Socket::inet_aton($host);
$DNS_CACHE->set($host,\$ip,5);
}
return unless $ip;
Socket::inet_ntoa($ip);
}
);
$dsn = $resolver->resolv($dsn);
他にもData::WeightedRoundRobinと組み合わせたり、キャッシュをmemcachedで行ったりするのも簡単にできるかと思われます。
なんでこれが有用かというと、アプリケーションの設定で、
db => {
dsn => '10.9.4.1',
user => .., pass => ..
}
とIPアドレスで書くより
db => {
dsn => 'dbserver.local',
user => .., pass => ..
}
と書いた方が解りやすいし、DB障害時にDNSを使ってのfailoverもできます。けど毎回DNSに問い合わせると今度はDNSサーバに負荷がかかるし、遅いのでキャッシュをしておきたい、そんな時に使えるモジュールです