Browse Month: March 2010

pbzip2 を使う

Parallel BZIP2 (PBZIP2) という並列処理版の bzip2 があります。今まで Apache のアクセスログは、bzip2 で圧縮していましたが、pbzip2 を試してみることにしました。

CentOS の場合、pbzip2 バージョン 1.0.5(最新版は 1.1.0) が EPEL から提供されているので、yum 一発でインストールすることができます。pbzip2 は、SRPM があるので、手軽に最新版も試すこともできます。

$ sudo yum install -y pbzip2

圧縮時間の測定のために 50MB ほどのアクセスログを bzip2 と pbzip2、それぞれで圧縮してみました。

この測定したサーバは、Xeon L5530 で HT 有効のサーバです。

まずは、bzip2 から。

$ time bzip2 -kv –best access_log

6.144:1,  1.302 bits/byte, 83.72% saved, 56862316 in, 9255173 out.
bzip2 -kv –best access_log  16.29s user 0.08s system 99% cpu 16.370 total

次に、pbzip2。

$ pbzip2 -kv -p8 access_log

pbzip2 -kv -p8 access_log  19.31s user 0.15s system 772% cpu 2.521 total

処理時間と比較すると、次のような結果でした。ついでに、16 コアでも試してみました。

  • bzip2: 約 16 秒
  • pbzip2(-p8): 約 2.5 秒
  • pbzip2(-p16): 約 2.1 秒

圧縮後のサイトは、どちらも 8.9MB とほぼ同じでしたが、バイト数は次のような結果でした。

  • bzip2: 9,255,173
  • pbzip2: 9,262,212

pbzip2 の方は仕組み上、多少圧縮サイズが小さいという結果になりましたが、圧縮時間が大幅に減少しました。圧縮サイズはそれほど変わらないので、複数コアのあるサーバでアクセスログを圧縮する場合は pbzip2 を使っていくことにしました。

なお、解凍は bzip2 形式なので、pbzip2 で圧縮したファイルも bzip2 -dc で解凍することができます(当たり前ですが…)。

ウェブサーバ上の過去のアクセスログは、ディスクを圧迫するためウェブサーバ上で圧縮するのが普通だと思いますが、複数コアの CPU があるサーバなら pbzip2 を使うことで圧縮時間を大幅に短縮できます。短縮できた CPU 時間をウェブサーバ本来の処理にまわすことができるはずなので、ウェブサーバのリソースを有効に扱うことに結びつくと思います。

さらに詳しい pbzip2 のベンチマーク結果は、本家サイトに情報があるので、興味のある人は参考にするといいと思います。

家庭用の NAS を導入した

家には、Mac mini と小型サーバの2台があります。それぞれ、次のような感じの用途になっています。

  • Mac mini: 家での作業用 PC、音楽を聞いたり、写真を見たり、映画を見たり、個人プロジェクトの開発用
  • 小型サーバ: VMWare ESXi で、FreeBSD と CentOS と Windows XP が動いている、FreeBSD はメールサーバや wiki など、CentOS と Windows XP は技術的な実験用

で、音楽や写真データなどは、今までずっとバックアップをとっていなかったけれども、だんだんとデータ容量も増えてきてバックアップをとることにしました。

家庭用 NAS を導入するとものが増えるので躊躇っていたけれども、データが消えたときのことを考えると不安だったので、思い切って家庭用 NAS を導入することにした。Mac mini だけなら、Time Capsule でもよかったけれども FreeBSD にも大切なデータが入っているので、他の家庭用の NAS を検討してみました。具体的には、ハードディスク|HD-HTGL/R5シリーズなどを考えたけれど、かなり大きくて僕が求めているのはもっとコンパクトなものがほしいと思っていました。

そこで、偶然立ち読みした DOS/V POWER REPORT マガジンThecus Technologyというおもに NAS を開発している会社を知りました。この会社のホームページをみてみると、N2200 という非常にコンパクトな家庭用 NAS を見つけました。N2200 のおもな特徴は、次のとおりです。さらに詳しい特徴は、UAC 株式会社にも情報があります。

  • ハードディスク x 2、RAID 0/1、JBOD 対応
  • ハードディスクレスのタイプなので、ハードディスクは自由に選択可能
  • サポートするハードディスク容量は、2TB x 2 まで対応している
  • 内部が Linux なので、SMB、CIFS、HTTP、HTTPS、FTP、NFS V3、AFP 3 をサポート
  • ブラウザから、NAS の設定を変更することが可能

購入は、Amazon からもできるけれど、UAC ダイレクトから購入してみました。ハードディスクは、2TB のハードディスクの価格がかなり下がっていたので、WESTERN DIGITAL のものと、HGST のものを一台ずつ購入しました。なんとなく、同じハードディスクだと何かあったときにめんどうなので、わざと別々のメーカーのもにしました。実際に購入してみると、予想どおりかなりコンパクトでいい感じです。

DSC_0017.JPG

セットアップ方法は、ハードディスクをトレイに接続して、Windows の専用クライアントから IP アドレスやディスクのフォーマットをするだけと、とてもセットアップは簡単でした。IP アドレスさえ設定してしまえば、あとはブラウザから操作できるので、Mac からも操作することができます。ブラウザの管理画面は、次のような感じです。ファームウェアの更新もブラウザからできるので、とても便利です。

実際に使っていた感想は、次のとおりです。

  • セットアップが非常に簡単
  • RAID1 で使っているけれど、片側のハードディスクをはずしても動き続けて、ハードディスクを再度取り付けると自動ビルドが始まる(ハードディスクがはずれると、かなり大きいビーという音がする)
  • とても静か、ハードディスクにコピーしているときだけハードディスクの音が聞こえるけれど、ファンの音はまったく気にならないほど静音設計になっている
  • 内部のファイルシステムは、XFS になっている

実際のバックアップ方法は、それぞれ次のような感じで行っています。

Mac mini からは、このあたりの情報から調査した結果、最終的には TimeMachine でバックアップしています。ただし、公式にはサードパーティ静の NAS に対応していないので、iTimeMachine というアプリケーションで設定しています。もちろん、Terminal から設定できるので、次のコマンドを入力してもいいと思います。

$ defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1

そして、ここを参考にして NAS 上に TimeMachine のバックアップをとれるように設定しています。

FreeBSD からは amd 経由で NFS でマウントして rsync でバックアップしています。将来的には、ZFS にファイルシステムを変更して、さらに手軽にバックアップする予定です。

気になる価格の方は、N2200 と 2TB のハードディスクを 2 台あわせて約 5 万円弱くらいです。価格的には、Time Capsule 2 TB モデルと同じくらいです。ただし、RAID1 なので Time Capsule よりはコストパフォーマンスがよいといえるかもしれません。そのかわり、セットアップはめんどうですが。

これでようやく、音楽や写真などの大事なデータをバックアップして生活することができるようになりました。

Thecus 2ベイ NASキット DLNA対応 N2200
Thecus (2009-10-09)
売り上げランキング: 62581

Apache で特定の URL のみ Basic 認証を外す方法

Apacheのベーシック認証の応用をみて、試してみた。

例えば、次のような設定を書いたとする。

<VirtualHost * *:443>
ServerName test.localhost
DocumentRoot /var/www/html

<Directory /var/www/html>
Allow from All
</Directory>

<Location />
AuthType Basic
AuthName “test”
AuthUserFile /var/www/.htpasswd
Require valid-user
</Location>

<Location /test>
Order allow,deny
Allow from all
Satisfy Any
</Location>
</VirtualHost>

このような VirtualHost を設定しておくと、http://test.localhost 以下の /test 以外は Basic 認証がかかった状態になる。たまに、こういった設定も必要なときがあるので、これは便利。

参考資料

DNS の逆引きを忘れていた

昨日のお昼頃、急にサーバ内部ネットワークの SSH / MySQL 接続が異様に遅くなる現象が発生してしまいました。

最初は、スイッチやネットワーク系統の問題だと思っていたのですが、どうやら内部にたてている DNS で逆引き設定を忘れていて、その上位の DNS サーバで急に逆引きができなくなったことが起因していました。

お恥ずかしい限りですが、内部の DNS で逆引き設定を忘れていました。

SSH で逆引きしないように設定するには、FAQ に書かれているとおり sshd_config に UseDNS no と設定すれば 逆引きしない設定することができます。

同様に MySQL で逆引きしないように設定するには、mysqld の起動オプションに --skip-name-resolve とつけて起動すれば設定することができます。

どちらもこの設定をしてしまうと、接続設定にホスト名を指定することができなくなってしまうため、不便です。

てっとりばやく解決するには、それぞれのサーバに /etc/hosts を記述すれば可能なのですが、すべてのサーバを /etc/hosts を puppet  で管理するのはなかなかめんどうです。puppet には host リソースがあって、手軽に /etc/hosts を扱えるのですが、前に s[1-255].server.example.jp という設定をマニフェストに記述してみたら、s1 から順番に並んでいないとても汚くなってしまったので微妙です。それに各サーバごとの役割は、現実的にかなり頻繁に変わるので、そのたびにすべてのサーバの /etc/hosts を変更するのは管理コストがかなりかかります。個人的には、かなり非現実的です。

やはり、内部 DNS で逆引き設定をするのが一番いいと思います。今のところ、内部 DNS には bind を使っています。bind には、GENERATE という独自の構文があって、これを使うと次のように簡単に逆引き設定をすることができます。

$TTL    86400
@               IN SOA  @       root (
                                       123             ; serial (d. adams)
                                       3H              ; refresh
                                       15M             ; retry
                                       1W              ; expiry
                                       1D )            ; minimum
               IN NS           ns1.example.jp.
$GENERATE   1-256   $.0.0.10.in-addr.arpa.  PTR     s$.example.jp.

あとは、/etc/named.conf に、次のように zone 設定を記述すれば逆引き設定をすることが可能です。

zone "0.0.10.in-addr.arpa" IN {
               type master;
               file "0.0.10.in-addr.arpa";
               allow-update { none; };
               notify no;
};

設定したら、正しく逆引きができるこを、次のような感じで確認します。

$ dig @localhost -x 10.0.0.1

今回は、どうやら回線プロバイダから提供されている上位の DNS で逆引き設定ができなくなったようですが、なぜこの時間に起きたのか詳しい原因はよく分かっていません。

内部 DNS をたてている場合、逆引きの設定は忘れやすいので注意したいです。

今のところ、内部 DNS には bind を使っていますが、UnboundPowerDNS に置き換える予定です。

rsyslog 4.6.1 stable

rsyslog 4.6.1 stable がリリースされました。おもにバグフィックスリリースです。

rsyslog 4.6.1 の前のバージョンであるバージョン 4.5.6 では、僕がパッチを送ったデータを圧縮したときのメモリリークが修正されています。おそらく rsyslog を使っている人で圧縮を有効にしている人は少ないと思いますが、もし使っている人は激しくメモリリークするので、最新版の 4.6.1 にアップグレードしましょう。

bugfix: memory leak when sending messages in zip-compressed format
Thanks to Naoya Nakazawa for analyzing this issue and providing a patch.

こんな感じで rsyslog の CHANGELOG に自分の名前が掲載されているなんて感無量です。

現在、rsyslog バージョン 4.4.2 を本番サーバで使っているのバージョンアップする予定です。

あと、rsyslog を使っていますが、たとえばかなりの容量の Apache のアクセスログを rsyslog へ送っているとき、まれに rsyslog が落ちてしまう問題が一回発生したのですが、再現していません。再現したら、解析して、またパッチを送ってみようと思います。

rsyslog は、現在でもかなり活発に開発が進められているので、今後も進化を続けると思います。

# 今後は、rsyslog バージョン 5.x 系の開発に注力するようです。

MySQL の公式 RPM を使おう

今まで、前に紹介した方法で、自分で MySQL の RPM をビルドしていたのですが、次の点が不満でした。

  • コンパイルにかなりの時間がかかる
  • コンパイル後の、テストが必ず失敗する(SSL まわりのエラーなので、テストは必ずしないように変更していた)
  • なぜか、InnoDB plugin が無効になってしまって、InnoDB plugin を普通に試せない

ということで、QA もちゃんとされている MySQL の公式 RPM に切替えてみることにしました。

まず、現在の MySQL 5.1 の最新バージョンは 5.1.44 です。MySQL の公式サイトでは RHEL5 用の x86_64 の RPM が用意されています。
RHEL5 x86_64 用の RPM は、次のものをダウンロードすることができます。

  • MySQL-client-community-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-community-5.1.44-1.rhel5.src.rpm
  • MySQL-community-debuginfo-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-devel-community-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-embedded-community-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-server-community-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-shared-community-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-shared-compat-5.1.44-1.rhel5.x86_64.rpm
  • MySQL-test-community-5.1.44-1.rhel5.x86_64.rpm

次のそれぞれの RPM に、どんなものが含まれているか調査してみました。

MySQL-client-community-5.1.44-1.rhel5.x86_64.rpm
/usr/bin/mysql など、MySQL クライアントようのコマンドが含まれています。

MySQL-community-5.1.44-1.rhel5.src.rpm
SRPM です。mysql-5.1.44.rhel5.spec と mysql-5.1.44.tar.gz が含まれています。

MySQL-community-debuginfo-5.1.44-1.rhel5.x86_64.rpm
MySQL のデバッグシンボル情報です。

MySQL-devel-community-5.1.44-1.rhel5.x86_64.rpm
mysql_config コマンドと MySQL のヘッダーファイルが含まれています。

MySQL-embedded-community-5.1.44-1.rhel5.x86_64.rpm
MySQL の組み込む用途に使われる /usr/lib64/mysql/libmysqld.a が含まれています。

MySQL-server-community-5.1.44-1.rhel5.x86_64.rpm
mysql の sysinit スクリプト、my.cnf 設定ファイルなど MySQL サーバに必要なプログラムが含まれています。

MySQL-shared-community-5.1.44-1.rhel5.x86_64.rpm
/usr/lib64/libmysqlclient.so と libmysqlclient_r.so が含まれています。

MySQL-shared-compat-5.1.44-1.rhel5.x86_64.rpm
MySQL-shared-community の複数のバージョンが含まれています。

MySQL-test-community-5.1.44-1.rhel5.x86_64.rpm
mysql_client_test コマンドが含まれています。

次に、CentOS で提供されているパッケージ名と MySQL 公式のパッケージ名の対応は、次のとおりになります。さらに詳しい RPM の説明は、MySQL 公式サイトを参照しましょう。

mysql:               MySQL-client-community + MySQL-shared-community
mysql-bench:   該当なし
mysql-devel:    MySQL-devel-community
mysql-server:  MySQL-server-community
mysql-test:      MySQL-test-community

MySQL 公式の RPM を使うには、既存の CentOS から提供されているパッケージを上書きするようなダミーパッケージを作成したほうが便利だろうと考えました。なぜなら、既存の MySQL 以外のパッケージで、mysql や mysql-devel のパッケージ依存関係が設定されているときにやっかいだからです。具体的には、このような現象が想定されるからです。

一度ダミーパッケージを作って、公式の RPM もローカルの yum リポジトリに入れてインストールとすると、どうも不思議な感じになってしまいました。具体的には、mysql パッケージをインストールすると、なぜか MySQL-server-community パッケージがインストールされてしまいました。

公式の RPM をよく見てみると、なんと Provides が設定されているじゃありませんか!
公式の RPM では、次のようにちゃんと Provides が設定されています。

MySQL-client: mysql-client MySQL-client
MySQL-server-community: msqlormysql mysql-server mysql MySQL MySQL-server
MySQL-test-community: mysql-test MySQL-test
MySQL-devel-community: mysql-devel MySQL-devel
MySQL-shared-community: mysql-shared MySQL-shared
MySQL-embedded-community:  mysql-embedded MySQL-embedded
MySQL-test-community: mysql-test MySQL-test

なので、mysql パッケージ名を指定すると MySQL-server-community パッケージがインストールされるんですね。。。ということで、小文字のパッケージ名でもちゃんとインストールできます。。。ダミーパッケージを作成したのが無駄になってしまいました、お恥ずかしい。。。

一点だけ注意点があって、mysql というパッケージ名は MySQL-server-community で Provides されているので、MySQL サーバが入ってしまうということです。もし、あるパッケージに mysql というパッケージの依存関係があると MySQL-server-community パッケージがインストールされてしまうので注意しましょう。

まとめると、ダミーパッケージは必要なく、MySQL の公式パッケージだけで、次のコマンドで MySQL の最新バージョンを手軽に使うことができます。

$ sudo yum install mysql-client mysql-shared mysql-server

上のコマンドで MySQL をインストールする場合、MySQL の公式 RPM の方がバージョンが新しいので必ず MySQL 5.1.44 がインストールされるはずです。

ですが、正しくバージョンを指定して、MySQL のバージョンをインストールした場合は、次のようにします。

$ sudo yum install mysql-client-5.1.44 mysql-shared-5.1.44 mysql-server-5.1.44

ただし、RPM に登録されるパッケージ名は、MySQL-*** となるので注意しましょう。mysql* という小文字のパッケージでは登録されていないので気をつけてください。

また、mysql の設定ファイル(/etc/my.cnf と /etc/mysqlmanager.passwd)は、インストールされていないので自分で設置しましょう。
デフォルトの /etc/my.cnf は、このあたりの情報をもとにして設定を追加するといいと思います。

ちなみに MySQL の公式 RPM は、cobbler でローカルの yum リポジトリにミラーしていますが、こんな感じで設定してあります。

$ sudo cobbler repo report –name=mysql-MySQL-5.1

repo: mysql-MySQL-5.1
arch: x86_64
breed: rsync
comment:
created: Tue Feb  9 22:34:22 2010
createrepo_flags: -c cache -d
environment: {}
keep updated: True
mirror: rsync://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.1/
mirror locally: True
modified : Tue Feb  9 22:34:22 2010
owners: [‘admin’]
priority: 99
rpm list:
yum options: {}

こうしておけば、MySQL 5.1 系の最新バージョンがでたとき、cobbler reposync すればすぐに最新版の RPM をローカルの yum リポジトリにミラーできるので、とても便利です。

さて、これで MySQL をメジャーアップグレードする準備が整いました。