unoh.github.com

「ちわさん、奥さんが来ましたよ」

Fri Jun 11 01:46:16 -0700 2010

「え!?妻が会社に!?」と一瞬戸惑いましたが奥一穂さんでした。
別に妻が会社に来てもやましいことなど何もありませんが、こんちには、ちわです。こんにちわ。

以前の記事でもご紹介した通り弊社が提供しているまちつく!というサービスでは Q4M 0.9.0 を利用して地図の画像生成と Amazon S3 への転送を行っています。
その Q4M に障害が発生し弊社ではどうも解決できそうにないので Q4M の作者の奥一穂さんに相談させてもらいました。
その際は、デッドロックのバグを踏んでいる可能性があるので Q4M を 0.9.1 以上のものしてみてはどうかと返答を頂きました。
弊社では 64bit 環境であった為、0.9.2 は除外され、0.9.3 は新しすぎるので 0.9.1 を採用することにし、バージョンアップ後に障害もなく安定稼働を続けています。

そんな経緯もありまして、先日弊社に奥一穂さんが来社されることになり Q4M について10ページ程のスライドで Q4M の現状とこれからを紹介して頂いたり、弊社からいくつか質問をさせて頂く機会がありましたので今回は弊社からの質問とその回答をご紹介したいと思います。

queue_end() を呼ぶ頻度とデッドロックについて
ウ:(Q4M 0.9.0 の環境で)障害が起きたサービスと一度も障害が起きていないサービスがあります。障害の起きたサービスでは queue_wait() のループ内で毎回 queue_end() を呼んでいますが、他方では queue_wait() のループの外で queue_end() を呼んでいます。障害の起きたサービスでは頻繁に queue_end() を呼んでいることになりますが、queue_end() を頻繁に呼ぶことがデッドロックを誘発する原因になりうるのでしょうか?
奥(敬称略):まずデッドロックが発生するのは確率的な問題です。
queue_end() を頻繁に呼ぶことがデッドロックの発生率を高める主な要因にはならないと思います。

キューのリトライについて
ウ:キューのリトライの常套手段としてはどのようなものがありますか?
奥:例えば、優先度が高・中・低のテーブルを用意して高で失敗したキューをリトライ用として中のテーブルに入れます。
高が空になった時点でリトライ用の中に入っているキューを処理させる等でしょうか。

ウ:リトライを時間で制御したい場合はどのようにすればよいですか?例えば、キューの処理に失敗したらX秒後に処理するとか。
奥:リトライ用のキューに入れた時間とそのキューを取り出した時点での時刻を比較する。リトライ用のキューを取り出した時点でX秒経っていなかったら任意の時間 sleep する。
というのはどうでしょうか。

Conditional Subscription について
ウ:Conditional Subscription というのがありm
奥:あっ、Conditional Subscription 使ってますか?
ウ:使ってますね。使わないですか?
奥:私自身はあまり使っていないですね。
単純に queue_wait('table') するなら先頭からレコードを取り出せばよいですが、Conditional Subscription を使用すると条件に合致するレコードを走査する必要があるので溜まっているレコードが多ければそれだけコストがかかります。

アプリケーションとのアトミックな処理について
ウ:アプリケーションである処理の成功時に Q4M へ INSERT する、というロジックがあったとして、そのある処理は成功したけど Q4M への INSERT には失敗したという状況がありますが、このような場合はどうすればよいでしょうか?
奥:そうですね、Q4M ではなくて InnoDB でなんちゃってメッセージキューを実装するという解決方法はありますね。現状だとどうしようもないですね。Q4M でもトランザクションを扱えるようにしたいとは思っています。

処理したキューの統計情報について
ウ:例えば、一日に処理したキューの数を知りたいと思ったら SHOW ENGINE QUEUE STATUS; の数字を見ればよいのですか?
奥:そうですね。
ちょっとパースしづらいとは思いますが、その数字を見てください。

Parallel::Prefork について
ウ:Parallel::Prefork で fork している子プロセスが queue_wait() を呼んでタイムアウトになればその子プロセスは死にますが、現在のところ queue_wait() がタイムアウトする状況は把握していません。そうなると子プロセスはいつまでたっても死んでくれないという実装をしてしまったのですが Parallel::Prefork に Apache で言うところの MaxRequestsPerChild のようなものは実装される予定はありますか?
奥:ないですね。ImageMagick 等で画像を作っているのであればメモリリークも心配ですよね。必要であれば worker で実装してみてください。
ウ:はい、実装させて頂きます。

YAPC Asia 2010 について
ウ:YAPC Asia 2010 にスピーカーで参加する予定はありますか?
奥:今のところないです。

まとめ
「奥さんがウノウに来てくれるらしい」という話から実際に来社されるまでの時間が短く、奥さんへの質問の準備が足りなかったことが悔やまれますが以上が今回質問させて頂いた内容とその回答です。
どのような背景でどのように Q4M を使用するかは様々だとは思いますが、開発者の奥さんが Conditional Subscription をあまり使用していないというのは少々驚きました。まちつく!では Conditional Subscription は使用していませんが他プロジェクトでは使用しているようです。
同じ社内でも Q4M の使い方が違うので他社の方がどのように Q4M を使用しているかは気になるところです。

奥さんへ
お忙しい中来社して頂き、またウノウラボへの掲載を快諾していただきありがとうございました。

ウノウでは積極的にエンジニアを募集していますが、弊社にて勉強会を開いて頂けるエンジニアも募集したいと思っています。Twitter の弊社社長のリストのメンバーに向けて「勉強会がしたい」等つぶやいて頂ければ誰かしらが反応するとおもいます。日時の調整等がうまくいけば今回のように勉強会が実現するかもしれません。