techlifeライトニングトーク at クックパッド
2009年10月24日
techlifeライトニングトークは、実践的な技術交流のためのイベントです。
毎回テーマを決めて、それについてプレゼンをして頂きます。
・1人5分、参加者全員発表
・LTの内容は動画で公開予定
・あなたのtechlife(技術のある楽しい生活)に役立った内容のみ発表可能
・申し込み人数が10名を超える場合は、抽選とさせて頂きます。
techlifeライトニングトークは、平日19時から!
11/20 分散処理
12/3 Puppet
12/11 Hive
-申込方法
下記項目をご記載の上、
までメールをお送りください。
〆切は開催2日前。ご参加頂く方には、詳細のメールを差し上げます。
—————————————————
■タイトル(例えば分散処理の会なら)
「分散処理参加希望」
■本文
・お名前
・ご年齢
・ライトニングトークのおおまかな内容
—————————————————
twitterはじめました!ライトニングトークのテーマ募集中☆
@techlifecookpad
AWKのススメ
2009年10月23日
はじめまして。インフラチームの菅原といいます。
今年の7月に入社してから、コンソールとにらめっこする毎日を過ごしています。クックパッドのようにアクセスの多いサイトのサーバを扱うことが今まで無かったので、いろいろと勉強になることが多いです。
さて、インフラチームではサーバの状況をモニタリングして、サーバに問題がないかを常に把握するようにしています。そのため日常的にtailでログを追いかけているのですが、そんなときはAWKが非常に便利なことに気付き、最近はかなりAWKにハマっています。
今回は絶賛マイブーム中のAWKの活用例をご紹介したいと思います。
なぜAWKなのか?
残念ながらAWKの知名度はあまり高くないようで、社内でも「なぜRubyでやらないのか?」と聞かれることがありました。僕も入社するまではcutの代わりぐらいにしか使っていなかったのですが、あるときログ出力の整形に使って以来、AWKのおもしろさにすっかりハマってしまいました。
AWKの魅力はいろいろとあるのですが、ひとつあげるとすれば「ワンライナーの書きやすさ」です。もちろんRubyでもPerlでもワンライナーは書けるのですが、AWKはさらにワンライナーが書きやすい言語です。
仕事での活用例
普段、僕が仕事で使っているAWKスクリプトをいくつかご紹介します。AWKの文法についてはGNU Awk User’s Guideなどを参照してください。
Railsの500msec以上かかっている処理を追いかける
後からRailsのログを集計してもよいのですが、その場で状況を知りたいときは tail -f と AWK の組み合わせが強力です。次の簡単なAWKスクリプトは、遅くなっている処理をさくっと把握したいときに使っています。
$ tail -f log/production.log | ¥
awk '/^Completed/{if($3 > 0.5) print }'
Completed in 0.56046 (1 reqs/sec) | Rendering: 0.23351 (41%) ...
Completed in 0.59227 (1 reqs/sec) | Rendering: 0.00010 (0%) ...
Completed in 1.90438 (0 reqs/sec) | Rendering: 1.87990 (98%) ...
...
Apacheの平均応答時間を追いかける
アクセスが多くなると tail -f でaccess_logを追いかけようとしても、流れが速すぎて状況を把握できません。そこでAWKで100リクエストごとの平均応答時間を計算して、現在の応答時間がどのくらいなのかを把握しています。
$ tail -f access_log | awk '
{i++; t+=$4}
i > 100 {
print strftime("%H:%M:%S"), "|", t / i / 1000, "ms"
i=t=0
}'
18:58:34 | 97.1538 ms
18:58:38 | 80.6553 ms
18:58:42 | 75.4794 ms
ちなみにクックパッドのaccess_logは以下のようなフォーマットで出力されます。
# ステータス, 時間, 処理時間(マイクロ秒), リクエストuri, パラメータ...
LogFormat "%>s\t%{%Y-%m-%d %H:%M:%S}t\t%D\t%U\t%q..."
上記のスクリプトを少し修正して、単位時間あたりのリクエスト数を出力するようにすると、サービスへどのくらいアクセスがあるのかを把握できるようになります。
[...]$ tail -f access_log | awk '
BEGIN{st=systime()}
{i++}
i > 200 {
et=systime()
printf("%s | %.1f req/sec\n",
strftime("%H:%M:%S"), i / (et - st))
i=0; st=et
}'
19:10:45 | 16.8 req/sec
19:10:55 | 20.1 req/sec
19:11:06 | 18.3 req/sec
slow-query.logを追いかける
mysqldumpslowというスロークエリログ用のツールがありますが、その場で状況を知りたいときには tail -f で追いかけるのが手軽です。しかし、そのままでは少々見にくいので、次のようなAWKスクリプトで整形します。
[...]$ tail -f slow-query.log | awk '
/^# Time/ {
q=substr(q,0,64)
printf("%s %s %-17s %2d %s\n", d, t, h, s, q)
d=$3; t=$4
}
/User/ {h=$5}
/Query_time/ {s=$3}
/^[^ ]/ {q=$0}'
091010 17:46:45 [192.168.xxx.xxx] 2 SELECT foo, bar, zoo FROM...
091010 17:55:29 [192.168.xxx.xxx] 3 SELECT foo FROM...
091010 17:56:08 [192.168.xxx.xxx] 3 SELECT foo FROM...
ANSIエスケープシーケンスを使えば、10秒以上かかったクエリだけ赤く表示することもできます。
awk '
/^# Time/ {
if (s > 9) {
printf("33[0;31m")
} else {
q=substr(q,0,64)
}
printf("%s %s %-17s %2d %s\n", d, t, h, s, q)
printf("33[0m")
d=$3; t=$4
}
/User/ {h=$5}
/Query_time/ {s=$3}
/^[^ ]/ {q=$0}'
まとめ
今回は、仕事で使っているAWKスクリプトをいくつかご紹介させていただきました。僕もまだAWK初心者なのでお世辞にも洗練されたコードとはいえませんが、それでも非常に役に立っています。
ちなみに、AWKのワンライナーには何か癖になるものがあり、最近はワンライナーばかり書いているので、historyがスクリプトの保存先と化しつつあります。
みなさんもAWKで一行野郎を使いこなしましょう!
おまけ
GNU Awkはソケットが使えるので、カレントディレクトリをDocumentRootとするWebサーバを、ワンライナーで書いてみました。
awk 'BEGIN{s="/inet/tcp/80/0/0";"pwd" |& getline;r=$0;while((s |& getline) >; 0){gsub(/[\r\n]/,"");if($0 ~ /^\s*$/){c="cat " r path;printf "HTTP/1.0 200 OK\r\n\r\n" |& s;while((c |& getline) > 0){print |& s}close(c);close(s)}else if($0 ~ /HTTP/){print;path=$2}}}'
きちんと改行をいれるとこんな感じになります。
awk '
BEGIN {
s = "/inet/tcp/80/0/0"
"pwd" |& getline
r = $0
while ((s |& getline) > 0) {
gsub(/[\r\n]/, "")
if ($0 ~ /^\s*$/) {
c = "cat " r path
printf "HTTP/1.0 200 OK\r\n\r\n" |& s
while ((c |& getline) > 0) {
print |& s
}
close(c)
close(s)
} else if ($0 ~ /HTTP/){
print
path = $2
}
}
}'
AWKを使ったことがなくても、わかりやすいコードではないでしょうか?
GNU Awkのネットワーク機能はとても面白いです。AWKを始めた人には、ネットワーク機能のマニュアルを一読することをお薦めします。
クックパッドとHadoop
2009年9月16日
はじめまして。今年の5月に入社した勝間@さがすチームです。
入社してからは、なかなか大変なことも多いですが、最近はお酒好きが集まって月曜から飲み合う 「勝間会」なるものも発足して、仕事面でも仕事以外の面でも密度の高い毎日を過ごしています!
さて、僕は「さがす」チーム所属ということで、普段はレシピを「さがす」ユーザの満足度を上げるために、 クックパッドの検索まわりについて、いろいろな開発を行っています。 一方で、ユーザの「さがす欲求」について深く知るために、大規模なデータ解析を行い、欲求の分析を行う機会も増えてきました。
ところが、クックパッドのログは膨大な数があるので、一口のデータ解析と言っても通常のバッチ処理だと間に合わないため、 分散処理環境の必要性が高まってきました。 そこで、まずは手軽に試せる分散処理の王道ということで、最近ではHadoopを使ったデータ解析環境を整備しています。
そんな中、ちょうどtech lunchで発表の順番が僕に回ってきたので、いい機会なので 「そもそもHadoopって何?」ということや「Map & Reduceを行っているとき、各プロセスは何をしているの?」な話をデモを含めながら発表してみました。 今回は、そのときの内容の資料と質疑応答の内容を共有したいと思います。
発表資料はこのようなものを利用しました。
その後は、このような質疑応答が行われました。
HDFSのNameNodeがボトルネックにはなりえないのか?
NameNodeは障害が起こると、HDFSのクラスタ全体が利用不能になるので、SPOFという観点で考えると、構成上どうしてもボトルネックになり得ます。
ただし、NameNodeが扱うメタデータを保護できれば、NameNodeに障害が起きても復旧できるため、次のような方法が提唱されています。
- メタデータについては、RAIDを組んで多重にディスクに書き込む。
- または、NFSマウントされた領域にメタデータを書き込む。
- SecondaryNameNodeはNameNodeのメタデータのバックアップを定期的にとっているため、NameNodeとSecondaryNameNodeを物理的に別ノードに分けて運用する。
また、NagiosやGangliaでモニタリングを行うことも可能で、ここから障害を検知することも可能です。
Hadoop MapReduceの処理コードはmasterにだけ置いておけば配布されるのか?
処理コードはMap&Reduce実行時にmasterからslaveに配布することができます。もちろんあらかじめrsyncなどで配布しておく方法も取ることが出来ます。
HDFSの安定性は?
レプリケーションの数を増やすことで安定稼働されます。 バックアップ失敗を想定して、レプリケーション数は3以上が推奨されています。また、HDFSに対してファイルシステムチェックを行うことも可能です。
Hadoop MapReduceとHDFSを分けた方がリソースを効率的に使えるのでは?
そういう発想もありかと思いますが、Hadoop開発陣の方針として、基本的には標準的な設定の使用を推奨しているようです。
標準的な設定は、YahooやFacebookなど大規模に利用されているケースをベースにして設定されたものなので、これに習うのが結果的に一番安定して動作するのでしょう。
Taskを割り振るのに優先度が付けられるのか?
複数Jobを与えるときに、優先度を付けることができます。
UU測定のサンプルコードで、複数プロセス存在するはずのReduceがハッシュマップのようなオブジェクトをどうして持てるの?
ハッシュマップのようなキーごとに処理を行うオブジェクトを持つためには、Reducerはキーごとに同じノードが処理を行っている必要があります。このとき、Mapの出力を同じキーごとに同じグループに属するように分割できれば、Reduceは分割可能となります。
ここでの、「Mapの出力を、ソートし、Reduceに渡す」フェーズは「Shuffle」、「Reduceへの入力をキーに基づいてグループ化してまとめる」フェーズを「Sort」フェーズと呼びます。 HadoopではShuffleやSortは完全に隠蔽されているので開発者がこれらのコードを書くケースはありません。
つまり、今回のようなMapの出力がkeyごとに分割されている場合は、Shuffle, SortによってMapの出力を分割、グループ化してReduceが処理できるようになるのでうまく扱うことができます。
HDFSを画像サーバなどに利用できるのか?
HDFSからのレスポンスは特に速いわけではなく、転送速度がボトルネックになるので、画像サーバには向いていません。HDFSは、データの行き来がそれほど起こらない、ログデータのようなものの保存が最も適していると思います。 画像サーバを分散ストレージで検討する場合は、他のプロダクトを利用したほうがよさそうです。
HadoopはHDFSに特化してるのか?
Hadoopを利用する場合は、必ずしもHDFSしか使えないわけではないです。他にもAmazon S3, CloudStoreなんかの選択肢があります。実際は、HDFSが一番ポピュラーで標準的に利用されているので、今回はこれを試してみました。
Hiveたのしそうですね
試してみましたが、なかなかたのしいです。 RDBと親和性高く、Joinなんかもできるのは魅力的なので、導入を検討しています。
クックパッドではHadoopはどのように使われるの?
直近では、様々な条件下でのログ解析や、バックエンドのDB更新などに利用される予定です。
まとめ
クックパッドにおいてデータ解析の需要が高まってきたことで、Hadoopへの取り組みをまとめてみました。今後、本格導入していく際にはまた改めてエントリを上げたいと思います。
また、このような分散環境におけるデータ解析についてご興味ある方を、クックパッドでは募集しています!
クックパッドのバッチシステム
2009年8月18日
こんにちはみなさん、とんかつってうまいですし目黒のとんきは哲学ですよね、8/1付けで商品部エンジニアになったnegipoです。すてきな上司とかわいい同僚に囲まれてとても幸せです!
さて、今回はクックパッドのバックエンドで動いているバッチシステムの紹介スライドを共有します。
大事なことは全部かいてあるので読んで下さい。
けっこう大胆な修正が入っていますが、なんとか趣旨をよみとってもらえるとうれしいです。
という訳で、クックパッドでは2週間に1度みんなでお昼ごはんを食べながら一人のエンジニアが何かをしゃべる、”tech lunch”というものを開始しました。技術部はもちろん、商品部や編集部のディレクターなど多岐にわたる人たちがクックパッドがどうやって動いているか、将来どうなっていくのかという話にふむふむと頷いています。
今後このtech lunchで共有された技術的な内容は、順次この開発者ブログに掲載していく予定です。皆様のお役に立つ情報がどんどん集まればよいなと思います。
今後ともクックパッド開発者ブログをよろしくお願いします。
こんにちは、高田悟史です。クラウドとかスケールとかそういうインフラよりのセッションを選んで参加しています。
今回は、Ilya Grigorik氏によるセッションArt of the Ruby Proxy for Scale, Performance, and Monitoringのレポートです。
スライドは下記のアドレスで参照できます。
http://www.slideshare.net/igrigorik/ruby-proxies-for-scale-
performance-and-monitoring-gogaruco-igvitacom-1396734
本セッションは、プロキシラブという同氏によるプロキシのすすめともいうべき発表でした。静的ページのキャッシュという本来の機能だけではなく、ロードバランサーとして使うということはありますが、もう少し踏み込んだ使い方をしてみようというお話です。
例えば、一つのリクエストをproductionとstagingの両方にプロキシして(もちろん返すのはproductionのレスポンスだけ)、stagingのベンチマークをしたりだとか、ログを採集してリアルタイムに監視したり、あるいはデータそのものをダイナミックに書き換えたり、などになります。採集したログを元に、パフォーマンステストを行うためにautoperfというツールも紹介されていました。
そして、ポイントは、このようなことが、同氏作のEM-Proxyというライブラリを使うことで簡単に実装可能だということでした。このライブラリはRuby製なので、やはりパフォーマンスが気になるところですが、EventMachineを使ってイベント駆動になっているので、ほとんど影響はないとのことでした。
同氏のブログエントリRuby Proxies for Scale and Monitoringも参考にして下さい。
プロキシをミドルウェアとして機能を持たせるというのはおもしろいし、それを慣れ親しんだRubyで実装できるというのはかなり魅力的だと思います。ただ、やっぱりパフォーマンスに関しては実際に試してみないと気になります。プロキシに持たせる機能のアイデアとパフォーマンス等のデメリット(メンテナンスコストが上がるなど)の天秤だとは思いますが、今後は、発生した問題の解決策として「プロキシサーバーに実装してしまおう」という選択肢が増えたのは良いですね。
