6インチ Kindle スクリーンショット色々
最近、4人目の子供も生まれ、子供たちが成長するにつれて家がどんどん手狭になっていくため、Kindle(DX じゃない方)と ScanSnap S1500、裁断機 を買って家の本を電子化していっています。
で、Kindle にはスクリーンショットが撮れる機能があるため、どんな感じで Kindle 上で表示されるのか、様々な種類の本で示したいと思います。
Kindle の購入を検討している方のご参考になれば幸いです。
(画像はクリックすると大きいサイズで表示されます。)
Kindle Store から購入した本(Perl Best Practices)
Perl Best Practices は既に持っているのですが、Damian Conway の直筆サイン入りなので裁断機でバラして電子化するわけにはいかず、Kindle Edition を買ってみました。
文字サイズは3番目に小さい文字。
コードとそうじゃない部分や、ボールドとそうじゃない部分がもっと区別がつきやすいといいなー、と思ったけど、それ以外は今のところ特に不満なし。
青空キンドルで生成された PDF
青空キンドル で青空文庫のテキストを PDF にしたものです。
とても読みやすいです。
ここから以下は、すべて ScanSnap で PDF 化したものです。
文庫本(麻雀放浪記(一) 青春編)
青空キンドルより文字は若干小さめ。でも許容できる範囲。
新書(北方謙三の『水滸伝』ノート)
Kindle で読むとやや文字が小さいけど、許容範囲内。
フルカラーの新書(暗黒宇宙で銀河が生まれる)
フルカラーのものは残念な感じ。カラーページがモノクロになるのはしかたないにしても、ScanSnap でスキャン時の色設定を、カラーやグレースケールにすると、文字が薄くなってしまって読みにくい。設定の調整でもっと見やすくできるかもだけど、そんな苦労をするよりは、iPad でフルカラーで見る方がいいと思う。
単行本(楊令伝 十二 九天の章)
Kindle で読むとやや文字が小さいけど、許容範囲内。実際一冊読み切ってみたけど、特に目が疲れるということもなかった。
漫画(海皇紀 1, 寸法 17.2 x 11.6 x 1.8 cm)
漫画ではもっとも一般的なサイズと思われるもの。
本編はグレースケールではなく白黒で取り込んでいるせいか、若干荒い感じ。でもそれほど読みづらくはない。
漫画(OL進化論 14, 寸法 20.8 x 14.8 x 1.6 cm)
四コマ漫画に多い、ちょっと大きめサイズの本。
真ん中のカラーページを取り込んだモノは、やはり見づらい。白黒ページはかなり見やすい。
技術本(DNS & BINDクックブック)
オライリー本。
グレースケールでの取り込みは文字が薄くなり読みにくいので、白黒で取り込んでいるが、そのせいかグレーで網掛けになっている部分は見づらい感じ。また、6インチ Kindle では文字が小さくて読みにくい。これは DX じゃないと読む気になれない。
Updated on 2010/02/07 19:56
Karesansui 試してみた
Karesansui が KVM に対応というニュース を見たので、試してみることにした。
チュートリアル では OS インストールから解説されていてとても親切なんだけれど、うちの既存環境は CentOS 5.3 から 5.4 にアップグレードして KVM 環境を整えたせいか、いくつかはまったポイントが。
チュートリアルでは、kvm-qemu-img を削除しておけ、と書いてるんだけど、うちの環境では、以下の qemu と名のつくパッケージをすべて削除する必要があった。
- qemu
- qemu-system-sh4
- qemu-system-ppc
- qemu-system-arm
- qemu-system-x86
- qemu-system-cris
- qemu-system-sparc
- qemu-system-mips
- qemu-system-m68k
- qemu-user
- qemu-common
- qemu-img
また、PyXML も別途インストールが必要だった。
あとはチュートリアルの通りに、karesansui-install を実行して、画面に従ってインストール。設定も特にいらず、簡単。
まだインストールしてブラウザでアクセスしただけなんだけど、気になった点がいくつか。
- 既にある KVM ゲストが一覧に表示されない
- おそらくどこか(/var/opt/karesansui/karesansui.db あたり?)にゲスト情報を持つことになってるんだろうけど、libvirt あたりつかって既存のゲストを自動認識、とかしてくれるといいな
- 同じ理由で、Cobbler + Koan でゲスト作成しても認識してくれなさそう
- リモートホストのゲスト管理
- 複数ホスト構成にするには? を見ると、すべてのホストに Karesansui をインストールすることで、一カ所でまとめて管理できるみたいだけど、Karesansui 入れるのは一カ所だけで、あとは libvirtd さえ動いてれば OK、とかできるといいなー。おそらく事情があってこうなってないんでしょうけど。
まあ、オープンソースなんでグダグダ言ってないでパッチ書け、ってとこですかね。とりあえず動作を追ってみるところからはじめてみます。
PowerDNS テスト記録
前回のエントリ のつづき。今度は BIND + DLZ との比較ではなく、PowerDNS 単体、実サーバ上でパフォーマンス測定したり、長時間負荷かけてみたり、更新かつキャッシュパージしながら参照したり、といったテストをした時の記録。こちらもやはり2年ちょいぐらい前に作ったモノ。
目次
- Starting Points
テスト環境について
- DNSサーバ
- AMD Athlon(tm) 64 X2 Dual Core Processor 4600+
- 2GB メモリ
- MySQLサーバ
- AMD Athlon(tm) 64 X2 Dual Core Processor 4600+
- 2GB メモリ
- テスト用 DNS クライアント
- AMD Athlon(tm) 64 X2 Dual Core Processor 4600+
- 2GB メモリ
テストデータの投入
テスト用ゾーンデータを SQL 形式で準備
具体的なデータは大人の事情で省略。ゾーン数が26万、レコード数が280万ほど。バックエンドが MySQL なので、SQL 形式でデータを準備。
SQL データを MySQL へ投入
$ time mysql --disable-pager -uroot -f pdns < zone.sql 2> err.log
real 54m56.423s
user 0m30.502s
sys 0m32.974s
投入後のレコード数を見てみる。
mysql> select count(*) from domains;
+----------+
| count(*) |
+----------+
| 263238 |
+----------+
1 row in set (0.14 sec)
mysql> select count(*) from records;
+----------+
| count(*) |
+----------+
| 2798571 |
+----------+
データベースディレクトリのサイズ。
# cd /var/lib/mysql
# du -sk
726304 .
queryperf 用データ生成
以下のようなスクリプトで、BIND ゾーンファイルからデータファイルを生成。
use strict;
use warnings;
use Path::Class;
my $dir = shift or die "usage : $0 <dir>\n";
dir($dir)->recurse(
callback => sub {
my $file = shift;
return if $file !~ m{.+/([^/]+)\.zone$};
my $zone = $1;
open my $fh, '<', $file or die $!;
while ( <$fh> ) {
if ( $_ =~ /([^\s]*)\s+(A|MX|CNAME)\s+(.+)$/ ) {
my $domain = $1 ? "$1.$zone" : $zone;
my $type = $2;
my $value = $3;
$value =~ s/^\d+\s+// if $type eq 'MX';
print "$domain $type\n";
}
}
}
);
exit;
データファイルの内容は、こんな感じ。これが 2,517,990 行ある。
example.com A
example.com MX
www.example.com A
ftp.example.com
example.jp A
example.jp MX
www.example.jp A
ftp.example.jp
...
参照負荷/パフォーマンステスト
負荷のかけかた/パフォーマンス測定方法
負荷をかけるのとパフォーマンスを測定するのは、BIND 付属の queryperf コマンドを利用。queryperf コマンドは、上記で生成した大量負荷用データファイル内のレコードに対するクエリを、上から順番に実行していく。
負荷をかける前のプロセスの状態
起動直後(何もキャッシュしていない状態)の pdns_server プロセスの状態。
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 31715 0.0 0.0 16556 1212 ? Ssl 11:03 0:00 /usr/local/sbin/pdns_server --daemon --guardian=yes
root 31717 0.2 0.1 88688 2660 ? Sl 11:03 0:00 /usr/local/sbin/pdns_server-instance --daemon --guardian=yes
- 実際に処理を担当し、プロセスをキャッシュする(と思われる)子プロセスの仮想メモリサイズは約 90M。
大量/長時間負荷をかけた場合の安定度
5時間にわたって負荷をかけつづけた結果。
$ queryperf -s 192.168.50.43 -d queryperf.dat -l 19800
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 192.168.50.43)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 19800 seconds
Ran through file: 43 times
Queries sent: 110458827 queries
Queries completed: 110454675 queries
Queries lost: 4152 queries
Queries delayed(?): 0 queries
RTT max: 0.820253 sec
RTT min: 0.000053 sec
RTT average: 0.003381 sec
RTT std deviation: 0.045216 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 02:11:58 2007
Finished at: Thu Sep 27 07:42:01 2007
Ran for: 19803.489895 seconds
Queries per second: 5577.535858 qps
この時の pdns_server プロセスの仮想メモリサイズ。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 28130 0.0 0.0 15464 1212 ? Ssl 02:11 0:00 /usr/local/sbin/pdns_server --daemon --guardian=yes
root 28132 65.2 20.7 550480 427176 ? Sl 02:11 329:49 /usr/local/sbin/pdns_server-instance --daemon --guardian=yes
- この状態で全レコードをキャッシュしている模様(MySQLの負荷がまったくない状態になってる)
- 200万以上のレコードをすべてキャッシュしても、pdns_serverプロセスの仮想メモリサイズは 550M ほど。
- 5577クエリ/秒を5時間続けても、安定して動いている。
- 大量クエリ発行中に、別のところから dig を叩いても、すぐにレスポンスが返る。
- 結論としては、5000クエリ/秒のパフォーマンスを長時間安定して出すことができている、と言えそう。
1件のレコードのみを繰り返し検索した場合のパフォーマンス(ローカル)
example.jp の A レコードを queryperf で localhost に対してひたすら問い合わせ。メモリには1件だけキャッシュされた状態となる。
これにより VM環境でのテスト と比較してみる。
$ queryperf -s localhost -d 1record.dat -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 127.0.0.1)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 523722 times
Queries sent: 523723 queries
Queries completed: 523723 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 0.000850 sec
RTT min: 0.000075 sec
RTT average: 0.000348 sec
RTT std deviation: 0.000006 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 12:34:52 2007
Finished at: Thu Sep 27 12:35:02 2007
Ran for: 10.000307 seconds
Queries per second: 52370.692220 qps
VM環境でのテストでは、約4000クエリ/秒なので、10倍以上のパフォーマンス。
1件のレコードのみを繰り返し検索した場合のパフォーマンス(リモート)
ローカルの場合と同じく、example.jp の A レコードを今度はネットワーク越しにひたすら参照して比較してみる。
$ queryperf -s 192.168.50.43 -d 1record.dat -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 192.168.50.43)
[Timeout] Query timed out: msg id 18924
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 390784 times
Queries sent: 390785 queries
Queries completed: 390784 queries
Queries lost: 1 queries
Queries delayed(?): 0 queries
RTT max: 1.677650 sec
RTT min: 0.000075 sec
RTT average: 0.000454 sec
RTT std deviation: 0.002683 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 12:38:04 2007
Finished at: Thu Sep 27 12:38:16 2007
Ran for: 12.191577 seconds
Queries per second: 32053.605534 qps
ローカルに比べると、32053 / 52370 = 約60% ほどにパフォーマンスがおちる。
全レコードをキャッシュした状態でのパフォーマンス
長時間クエリを走らせて、すべてのクエリをキャッシュさせた状態でパフォーマンスを計測。
$ queryperf -s 192.168.50.43 -d ./queryperf.dat -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 192.168.50.43)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 0 times
Queries sent: 60000 queries
Queries completed: 60000 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 0.734255 sec
RTT min: 0.000214 sec
RTT average: 0.003470 sec
RTT std deviation: 0.046068 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 12:22:15 2007
Finished at: Thu Sep 27 12:22:25 2007
Ran for: 10.448189 seconds
Queries per second: 5742.621999 qps
『1件のレコードのみを繰り返し検索した場合のパフォーマンス(リモート)』と比較して、5742 / 32053 = 17% ほどにパフォーマンスが落ちる。(約1/6)
データ量が 2,500,000 倍で、パフォーマンスが 1/6 は数値としてはかなり優秀だと思う。これについて軽く考察してみる。
例えば、大量データの探索によく使われている二分木構造でレコードが管理されていると仮定した場合、250万レコード登録されていると、目的のレコードを探し当てるまでのツリーの探索回数は、最大で22回、平均で20回となる。
したがって、バイナリツリーでレコードが管理されていると想定した場合には、レコード数が 1 から 2,500,000 に増えれば、パフォーマンスは理論的には 1/20 に落ちる、ということになる。これが 1/6 程度に抑えられているので、大量にキャッシュを保持した状態でも、かなり高いパフォーマンスを実現している、と言えるのではないかと。
また、同様のパフォーマンステストをネットワーク越しではなくローカルで実行してみると、以下の様になった。
$ queryperf -s localhost -d queryperf.dat -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 127.0.0.1)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 0 times
Queries sent: 60005 queries
Queries completed: 60005 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 0.738513 sec
RTT min: 0.000142 sec
RTT average: 0.003365 sec
RTT std deviation: 0.045920 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 13:47:33 2007
Finished at: Thu Sep 27 13:47:43 2007
Ran for: 10.134120 seconds
Queries per second: 5921.086389 qps
これを『1件のレコードのみを繰り返し検索した場合のパフォーマンス(ローカル)』と比較してみる。こちらの方がネットワークのボトルネックを考慮しなくて良いので、より正確なパフォーマンス劣化具合が見られる。
ローカルの場合には、5930 / 52370 = 約 1/10 となる。これでもなお理論値の 1/20 よりは高いパフォーマンスが出ている。
全レコードの半分ほどをキャッシュした状態でのパフォーマンス
参考までに、キャッシュで保持しているデータを半分ほどにした時のパフォーマンスを見るために、pdns_server プロセスの仮想メモリサイズが 300M ほどの状態でパフォーマンスを測定してみた。
$ queryperf -s 192.168.50.43 -d ./mizzy/queryperf.dat -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 192.168.50.43)
[Timeout] Query timed out: msg id 53362
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 0 times
Queries sent: 92879 queries
Queries completed: 92878 queries
Queries lost: 1 queries
Queries delayed(?): 0 queries
RTT max: 0.428813 sec
RTT min: 0.000076 sec
RTT average: 0.002126 sec
RTT std deviation: 0.025852 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 27 12:28:24 2007
Finished at: Thu Sep 27 12:28:35 2007
Ran for: 10.894836 seconds
Queries per second: 8524.956227 qps
当然だけどパフォーマンスは上がってる。
大量更新テスト
以下の内容を実行するテスト用スクリプトを作成。
- queryperf 用データファイルからレコードを1件読み取る
- 対象レコードを DNS 参照してキャッシュに載せる。
- 対象レコードの変更を MySQL に対して行う。
- 対象レコードを DNS 参照する。この時点ではキャッシュのクリアを行っていないため、変更前の値が返ってくることを確認する。
- ssh 経由で「pdns_control purge レコード名」を実行して、対象レコードのキャッシュをクリア、
- 対象レコードを DNS 参照する。キャッシュがクリアされているはずなので、変更後の値が返ってくることを確認する。
- 最初に戻って繰り返す。
これを queryperf で参照系の負荷をかけながら行う。
スクリプトの内容は以下の通り。
use strict;
use warnings;
use DBI;
use Net::DNS;
use Test::More qw( no_plan );
my $file = 'queryperf.dat';
my $limit = 1000;
my $dsn = 'DBI:mysql:pdns:192.168.50.44';
my $user = 'pdns';
my $password = 'pdns';
my $dbh = DBI->connect($dsn, $user, $password);
my %method_hash = (
A => 'address',
MX => 'exchange',
CNAME => 'cname',
);
my $count = 0;
my $resolver = Net::DNS::Resolver->new( nameservers => [ '192.168.50.43' ] );
srand time;
open my $fh, '<', $file or die $!;
while ( <$fh> ) {
my ( $domain, $type ) = ( $_ =~ /^([^\s]+)\s+(A|MX|CNAME)/ );
$type ||= 'A';
my $res = $resolver->query($domain, $type);
my $method = $method_hash{$type};
my $answer = ($res->answer)[0]->$method;
my $sth = $dbh->prepare('UPDATE records set content = ? WHERE name = ? AND type = ?');
my $update = generate_random_value($domain, $type);
$sth->execute($update, $domain, $type);
$res = $resolver->query($domain, $type);
is( ($res->answer)[0]->$method, $answer);
system "ssh 192.168.50.43 sudo pdns_control purge $domain";
$res = $resolver->query($domain, $type);
is( ($res->answer)[0]->$method, $update);
last if $count > $limit;
$count++;
}
close $fh;
exit;
sub generate_random_value {
my $domain = shift;
my $type = shift;
if ( $type eq 'A' ) {
my $a1 = int rand 255 + 1;
my $a2 = int rand 255 + 1;
my $a3 = int rand 255 + 1;
my $a4 = int rand 255 + 1;
return "$a1.$a2.$a3.$a4";
}
else {
return crypt( ( rand 100000 ), 'AA' ) . ".$domain";
}
}
queryperf で参照負荷をかけながら1000 回ループを繰り返してみたところ、キャッシュのクリアができずに古いレコードが返ってくる、というケースは 0 件だった。ただし、レコード変更後に、キャッシュをクリアする前に新しいレコードが返ってくる、というケースが 20 件あった。おそらく負荷等の問題でうまくキャッシュに載らなかったためと思われるが、この場合でも新しいレコードが取得できていたので、特に問題はないと判断。
というわけで、レコードの更新とキャッシュのクリアはまったく問題なし。(後日10,000回ループを繰り返したが、こちらも問題なかった。)
BIND + DLZ と PowerDNS のパフォーマンス比較
とある IRC チャネルで DNS ソフトウェアの話になって、当然 BIND や djbdns があがってくるわけなんですが、うち PowerDNS つかってて、ベンチマークとった資料とかあるよ、と言ったら、あんま事例ないと思うのでブログで公開するとうれしい人が多いかも、と Ficia を アツく語る人 から言われたので公開します。2年ちょいぐらい前につくった資料で、細かいこと忘れちゃってますし、社内向けに書いたものを公開するので、マズいところは省いたりしてます。
まずは VM 環境で、BIND + DLZ と PowerDNS(どちらもバックエンドに MySQL を使用)のパフォーマンス比較した資料を公開します。
BIND + DLZ のパフォーマンス
/etc/named.conf
dlz "Mysql zone" {
database "mysql
{host=localhost dbname=dns_data ssl=false}
{select zone from dns_records where zone = '%zone%'}
{select ttl, type, mx_priority, case when lower(type)='txt' then concat('\"', data, '\"')
else data end from dns_records where zone = '%zone%' and host = '%record%'
and not (type = 'SOA' or type = 'NS')}
{select ttl, type, mx_priority, data, resp_person, serial, refresh, retry, expire, minimum
from dns_records where zone = '%zone%' and (type = 'SOA' or type='NS')}
{select ttl, type, host, mx_priority, data, resp_person, serial, refresh, retry, expire,
minimum from dns_records where zone = '%zone%' and not (type = 'SOA' or type = 'NS')}
{select zone from xfr_table where zone = '%zone%' and client = '%client%'}
{update data_count set count = count + 1 where zone ='%zone%'}";
};
MySQLに登録された DNS レコード
mysql> select * from dns_records;
+-------------+------+------+--------------+-------+-------------+---------+-------+---------+---------+----------+-------------------+------------+
| zone | host | type | data | ttl | mx_priority | refresh | retry | expire | minimum | serial | resp_person | primary_ns |
+-------------+------+------+--------------+-------+-------------+---------+-------+---------+---------+----------+-------------------+------------+
| example.org | @ | SOA | localhost. | 86400 | 10 | 3600 | 200 | 3600000 | 3600 | 20070919 | test.example.org. | NULL |
| example.org | www | A | 192.168.32.1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| example.org | abc | A | 192.168.32.2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| example.org | test | A | 192.168.32.3 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+-------------+------+------+--------------+-------+-------------+---------+-------+---------+---------+----------+-------------------+------------+
dns_records テーブルのインデックスの状態
mysql> show index from dns_records;
+-------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| dns_records | 1 | host_index | 1 | host | A | NULL | 20 | NULL | YES | BTREE | |
| dns_records | 1 | zone_index | 1 | zone | A | NULL | 30 | NULL | YES | BTREE | |
| dns_records | 1 | type_index | 1 | type | A | NULL | 8 | NULL | YES | BTREE | |
+-------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
queryperf 用ファイル
test.example.org A
queryperf の実行結果
# queryperf -d ~/dlz_test.dat -s 127.0.0.1 -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 127.0.0.1)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 974 times
Queries sent: 975 queries
Queries completed: 975 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 2.775003 sec
RTT min: 0.043778 sec
RTT average: 0.253777 sec
RTT std deviation: 0.335064 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 20 19:38:22 2007
Finished at: Thu Sep 20 19:38:35 2007
Ran for: 12.619786 seconds
Queries per second: 77.259630 qps
PowerDNS のパフォーマンス
MySQL に登録された DNS レコード
mysql> select * from records;
+----+-----------+--------------------+------+-------------------------+-------+------+-------------+
| id | domain_id | name | type | content | ttl | prio | change_date |
+----+-----------+--------------------+------+-------------------------+-------+------+-------------+
| 1 | 1 | test.com | SOA | localhost ahu@ds9a.nl 1 | 86400 | NULL | NULL |
| 2 | 1 | test.com | NS | dns-us1.powerdns.net | 86400 | NULL | NULL |
| 3 | 1 | test.com | NS | dns-eu1.powerdns.net | 86400 | NULL | NULL |
| 4 | 1 | www.test.com | A | 199.198.197.196 | 120 | NULL | NULL |
| 5 | 1 | mail.test.com | A | 195.194.193.192 | 120 | NULL | NULL |
| 6 | 1 | localhost.test.com | A | 127.0.0.1 | 120 | NULL | NULL |
| 7 | 1 | test.com | MX | mail.test.com | 120 | 25 | NULL |
+----+-----------+--------------------+------+-------------------------+-------+------+-------------+
records テーブルのインデックスの状態
mysql> show index from records;
+---------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| records | 0 | PRIMARY | 1 | id | A | 7 | NULL | NULL | | BTREE | |
| records | 1 | rec_name_index | 1 | name | A | 7 | NULL | NULL | YES | BTREE | |
| records | 1 | nametype_index | 1 | name | A | 7 | NULL | NULL | YES | BTREE | |
| records | 1 | nametype_index | 2 | type | A | 7 | NULL | NULL | YES | BTREE | |
| records | 1 | domain_id | 1 | domain_id | A | 2 | NULL | NULL | YES | BTREE | |
+---------+------------+----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
queryperf 用設定ファイルの内容
www.test.com A
queryperf の実行結果
# queryperf -d ~/pdns_test.dat -s 127.0.0.1 -l 10
DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.8.192.3 2005/10/29 00:21:12 jinmei Exp $
[Status] Processing input data
[Status] Sending queries (beginning with 127.0.0.1)
[Status] Testing complete
Statistics:
Parse input file: multiple times
Run time limit: 10 seconds
Ran through file: 42159 times
Queries sent: 42160 queries
Queries completed: 42160 queries
Queries lost: 0 queries
Queries delayed(?): 0 queries
RTT max: 0.013259 sec
RTT min: 0.000331 sec
RTT average: 0.002268 sec
RTT std deviation: 0.001248 sec
RTT out of range: 0 queries
Percentage completed: 100.00%
Percentage lost: 0.00%
Started at: Thu Sep 20 19:36:47 2007
Finished at: Thu Sep 20 19:36:57 2007
Ran for: 10.000367 seconds
Queries per second: 4215.845278 qps
結論
BIND + DLZ: 77.259630 qps、PowerDNS: 4215.845278 qps で PowerDNS の圧勝。これは BIND + DLZ がリクエスト毎に MySQL 問い合わせしてるのに対し、PowerDNS はメモリにキャッシュしていちいち MySQL に問い合わせないから、だろう。
Trac チケットを iCal 形式で出力するスクリプト
ペパボでは Trac を開発以外にも、タスク管理のツールとして使っていて、TracGantt や GanttCalendar なんかで期日を入れたりしてるんですが、ガントチャートやカレンダーがいまいち見やすくないため、期日を入れようというモチベーションが沸きにくいよね、みたいな話が今日のミーティングで出たりしてました。かといって、他にいいツールも見つからないし、あったとしても移行するのもめんどいし、カレンダーやガントチャートを別ソフトで管理するのも、二重に情報入れなきゃいけなくてめんどい。じゃあ、Trac チケットの情報を iCal 形式ではき出せば、好きなソフトで見られていいんじゃないか、ってことで、スクリプト書いてみた。(ロードマップを iCal 形式で吐き出す機能は Trac にあるけど、欲しいのと違った。)
http://gist.github.com/282756
iCal で吐き出す部分は Plagger::Plugin::Publish::iCal がとても参考になった。
Updated on 2010/01/22 07:51
グーペでは開発者募集してます
インフォーメーションがアレだったり、チュートリアルブログがアレだったり する ペパボ のサービス グーペ では 開発者を募集してます。
以下の応募条件をしっかりと守ってご応募ください。
※応募フォーム『自己PR』の最後に、自分が過去にやらかした経験を、さも他人事のように教えてください。
例:昔の彼女の誕生日に趣味の悪い紫色のオルゴールを送り、翌日交換日記経由でフラれたことがある知り合いがいます。あと、噛んでいたガムを妹のズボンのポケットに捨てていて母親に死ぬほど怒られたことがあるって、この間友達が言ってました。
関連サイト
Updated on 2010/01/20 17:50
lsyncd が rsync する対象ディレクトリを調べてみた
inotify + makuosan でいい感じのリアルタイムミラーリング で、lsyncd は結局は rsync を裏で呼び出してるので、差分チェックの呪縛からは逃れられない、的なことを書いてたんですが、ふと、「もしかして、inotify から rsyncを呼び出すときに、同期対象となるファイルは、指定したディレクトリ以下のもの全部ではなく、変更があったファイルがあるディレクト以下のものだけ、なんて動きをしてくれるのかな?」と気になったので、実際に試してみました。結果から先に言うと、想定通りの動きとなってます。これって常識なんですかね?以下、試した時のログ。
ログを確認するために、lsyncd をフォアグランドで起動。
$ ./lsyncd --no-daemon /tmp/lsyncd localhost:/var/tmp/lsyncd
Fri Jan 15 17:46:59 2010: command line options: syncing /tmp/lsyncd/ -> localhost:/var/tmp/lsyncd
Fri Jan 15 17:46:59 2010: Starting up
Fri Jan 15 17:46:59 2010: watching /tmp/lsyncd/
Fri Jan 15 17:47:00 2010: --- Entering normal operation with [1] monitored directories ---
ディレクトリを作成してみる。
$ mkdir /tmp/lsyncd/0
ログから、同期対象となってるのが、/tmp/lsyncd と、今作成した /tmp/lsyncd/0 であることがわかる。
Fri Jan 15 17:47:06 2010: event CREATE:0 triggered.
Fri Jan 15 17:47:06 2010: rsyncing /tmp/lsyncd/ --> localhost:/var/tmp/lsyncd/
Fri Jan 15 17:47:06 2010: rsyncing /tmp/lsyncd/0/ --> localhost:/var/tmp/lsyncd/0/
さらにその下にディレクトリを作成。
$ mkdir /tmp/lsyncd/0/1
同期対象となってるのが、/tmp/lsyncd/0 と、今作成した /tmp/lsyncd/0/1 であることがわかる。
Fri Jan 15 17:47:48 2010: event CREATE:1 triggered.
Fri Jan 15 17:47:48 2010: rsyncing /tmp/lsyncd/0/ --> localhost:/var/tmp/lsyncd/0/
Fri Jan 15 17:47:48 2010: rsyncing /tmp/lsyncd/0/1/ --> localhost:/var/tmp/lsyncd/0/1/
さらにその下にディレクトリを作成。
$ mkdir /tmp/lsyncd/0/1/2
同期対象となってるのが、/tmp/lsyncd/0/1 と、今作成した /tmp/lsyncd/0/1/2 であることがわかる。
Fri Jan 15 17:48:26 2010: event CREATE:2 triggered.
Fri Jan 15 17:48:26 2010: rsyncing /tmp/lsyncd/0/1/ --> localhost:/var/tmp/lsyncd/0/1/
Fri Jan 15 17:48:26 2010: rsyncing /tmp/lsyncd/0/1/2/ --> localhost:/var/tmp/lsyncd/0/1/2/
/tmp/lsyncd/0/1/2 の下にファイルを作ってみる。
$ touch /tmp/lsyncd/0/1/2/3.txt
同期対象が /tmp/lsyncd/0/1/2 だけであることがわかる。(CREATE イベントと CLOSE_WRITE イベントで2回同期してる。)
Fri Jan 15 17:49:07 2010: event CREATE:3.txt triggered.
Fri Jan 15 17:49:07 2010: rsyncing /tmp/lsyncd/0/1/2/ --> localhost:/var/tmp/lsyncd/0/1/2/
Fri Jan 15 17:49:07 2010: event CLOSE_WRITE:3.txt triggered.
Fri Jan 15 17:49:07 2010: rsyncing /tmp/lsyncd/0/1/2/ --> localhost:/var/tmp/lsyncd/0/1/2/
というわけで、やはり rsync による差分チェックはあるものの、対象ディレクトリを絞り込めるので、適切なディレクトリ構造にしていれば、rsync only よりはかなり負荷は抑えられそうな感じですね。
Updated on 2010/01/15 18:12
Dizzy Mizz Lizzy 来日記念 CustomFeed::Script 用スクリプト
Dizzy Mizz Lizzy が再結成ツアーで来日することが決定 したようで、チケット発売情報を漏らさないために、Plagger の CustomFeed::Script 用スクリプトを書きました。
http://gist.github.com/266224
彼らは95年、96年も来日していて、当時自分は学生で札幌在住だったわけですが、運良く2度とも札幌に来てくれ、ライブを見ることができました。(95年は Bad Moon Rising の前座だった。)
4年ぶりの再結成、14年ぶりの来日、ってことで、2度と見られないかもしれないので、5/8, 9 の2日とも行く予定です。
Plack::Middleware::Auth::LDAP 書いてみた
追記
miyagawa さんから助言があり、authenticator 追加するだけでサブクラスが増えると使いにくいというのと、Authen::Simple::LDAP を使えば、LDAP で認証するためにそれほどコード書くこともないので、わざわざモジュール化する必要もない、ということで、github からは削除することにしました。
また、Plack::Middleware::Auth::Basic の authenticator に Authen::Simple オブジェクトがそのまま渡せるように miyagawa さんが修正してくださいました。
http://github.com/miyagawa/Plack/commit/9f1ad6a3c2f33cd8f37c6cfcbb0993c55c84bbb9
これで Plack::Middleware::Auth::Basic そのままで、以下のような感じで LDAP で認証できます。
use Authen::Simple::LDAP;
enable "Auth::Basic", authenticator => Authen::Simple::LDAP->new(...);
miyagawa さん、ありがとうございました。
最近公私ともに、いちからウェブアプリ(ウェブ API 除く)書いてなくて、久々にウェブアプリを書こうかな−、と思いながらも、フレームワークに何を使おうか迷っていて、Ark Advent Calendar 2009 を読んだり、Amon をウォッチしたりして、この年末を過ごしています。
で、いずれのフレームワーク使うにしても、Plack はキーになりそうだな、ってことで、LDAP で認証するための Plack::Middleware を書いてみました。
http://github.com/mizzy/p5-plack-middleware-auth-ldap
Plack::Middleware::Auth::Basic を継承し、authorizer を追加する形で実装しています。
ネームスペースは Plack::Middleware::Auth::Basic::LDAP の方がいいのかな、とか、ダイジェスト認証対応しようと思ったら、別モジュールにした方がいいのか、合わせてひとつのモジュールにした方がいいのか、その場合のネームスペースはどうすればいいのか、など、色々固まってない点があるので、まだ CPAN にはアップしない予定です。が、とりあえず自分で使う分には問題なく動いてるっぽいです。
Updated on 2009/12/31 11:22
techlifeライトニングトークでのPuppet発表資料
クックパッドさん主催のtechlife ライトにングトーク で発表した資料をひとまず slideshare にアップしました。動画が後日クックパッドさんから公開されると思います。気になる方は#tllt をチェックしてください。
「Puppet Best Pracices?」と題して、実際に実践していることからいくつかピックアップして話してみました。? がついてる通り、ベストかどうかはわからないのですが、自分で実践しているネタを出すことで、より良い意見をもらえて、ベストに少しでも近づけていけるかな、と思い、こういったお題で話してみました。
とはいうものの、話す時間の関係でボリューム不足ではあるので、スライド内容を更に肉付けする形で、最近更新をさぼっているパペウィキ の方に書いていこうかな、と思ってます。
Updated on 2009/12/04 07:43