2012年11月05日

Isucon用Webサーバーrecaro

はてなブックマークに登録

11/3に開催された #isucon2 に、隣の席の @pandax381 と一緒に、チーム双龍として参加してきました。 結果は惨敗だったのですが、そのレポートを書く前に、 #isucon2 で使う予定だった秘密兵器 recaro について紹介します。

recaro とは

recaro はカーネル空間で動く httpd + memcached サーバーです。

httpd サーバーは @pandax381 が作成した tkhttpd で、 memcached は kmemcached というプロジェクトが 未完成のまま放置されていたのを見つけて、私がデバッグ&高性能化したものです。 (KLab/kmemcached)

通常のnginx+memcachedだと

ネットワーク <- TCP/IP ]-> nginx <-[ TCP/IP ]-> Memcached  ([] はシステムコール)
という構成になるところが、 recaro だとWebサーバーがMemcachedのストレージから 直接値を読み出せるので、
ネットワーク <- TCP/IP -> Webサーバー / memcachedストレージ
という構成になり、 TCP/IP プロトコルスタックをまるまる1回スキップできる上に システムコールも0回にすることができます。

isucon1 では最終的にフロントのWebサーバーで直接静的ファイルやキャッシュを返し、 アプリ側には極力リクエストを飛ばさない構成が強かったのをふまえ、nginxやApacheに 圧勝できる最凶のWebサーバーとして用意しました。

isucon2 では isucon1 ほど簡単にキャッシュ配信競争にならないと予測はしていたのですが、 自分たちで作ったサーバーなら隅々まで理解しているので、当日自分たちで専用の機能を カスタムで作成できると踏んでいました。

インストール

Debian系なら apt-get install build-essentials linux-headers を、 RedHat系なら yum install gcc make kernel-headers-`uname -r` で必要なファイルをインストールしておきます。

git clone git://github.com/KLab/recaro.git
cd recaro
make
sudo insmode recaro.ko

0.0.0.0:11211 で memcached が、 0.0.0.0:80 で httpd が動き始めます。

$ python mcset.py
$ curl http://127.0.0.1/foo
fizzbuzz

となれば成功です。

静的コンテンツ配信

memcached に、 key として path を、 value として mimetype<CR><LF>content という形式のデータを 格納すると、それを配信します。

例えば、 mcset.py/foo というキーに対して text/plain<CR><LF>fizzbuzz という値を設定していますが、この場合 http://127.0.0.1/foo にアクセスすると fizzbuzz が返ってきます。

SSI機能

mimetype に text/html を設定した場合、SSI機能が有効になります。 コンテンツ中に <!--# include hoge --> と書くと、 Memcached から hoge というキーの 値を取得して置換します。

mcset.py/bar を参考にしてください。

リバースプロクシ

リクエストメソッドがGETじゃなかった場合や、GETのURLがMemcachedに存在しなかった場合、 http://127.0.0.1:8080/ にリバースプロクシします。

リバースプロクシ先の設定やロードバランシングは当日の状況を見て実装する予定でした。

ベンチマーク

Amazon EC2 の c1.medium インスタンスに nginx と recaro を設置し、同じ zone にある c1.xlarge インスタンスから ab をかけてみます。

nginx は 1.3.8 に lua-nginx-module を加えてビルドしたもので、設定は以下のとおりです。

worker_processes  2;  # c1.medium は2コア.
events {
    worker_connections  1024;
}
http {
    server {
        listen       8000;
        server_name  localhost;
        location / {
            content_by_lua "ngx.say('fizzbuzz')";
        }
    }
}

ab -k -c100 -n100000 を3回実行た結果が次のようになりました。

nginx       26889.80    25937.49    25834.43
recaro      44733.20    44230.13    44171.76
recaro(SSI) 42610.56    43106.59    42471.77

(補足: XenのDomU ではなく物理マシンであれば、5年前のデスクトップPCでも10万req/secを超えます)

nginx は外部の memcached にアクセスしたらこれよりずっとスコアが 落ちるはずなので、 isucon1 の様に一部動的な要素を含むHTMLの配信競争で、帯域が問題に ならないのであれば圧勝できるはずでした。 (続く)


@methane
klab_gijutsu2 at 22:15│Comments(0)TrackBack(0)

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント