2009年8月8日土曜日

勉強会「MySQL Hackingの手引き」を終えて

 昨日は、グリー勉強会にて「MySQLハッキングの手引き」というテーマで発表をしました。資料とデモに使用したソースコードやビルドスクリプト等はこちらに公開しています(サンプルプログラムのコンパイルにはソースからビルドしたMySQL5.1以降が必要)。声をかけてくださったグリーの一井さんや、会場準備など諸手続きを行なってくださったグリーのスタッフの方々、参加された皆さまありがとうございました。

●参加者数の意外な多さ
 無料の勉強会とはいえ、このようなマニアックなテーマで、60名定員のところに150名を超える応募が来たというのは驚きました。相当数の方が抽選落ちしてしまったのは残念でしたが、評判が良ければ似たようなテーマでのセミナーをまたどこかで行ないたいと考えています。
 自分はMySQLのコンサルティングという、MySQLの使い手としての専門職(パフォーマンスチューニングとか運用管理とか)に従事しています。過去に発信した記事/書籍やセミナー等はほぼ例外なく使い手としての知識と経験をベースにしています。ただ、たまにですが客先等で挙がった要望リストをもとにパッチを作ってコントリビュートしたり、コンサルティング案件としてMySQL本体を拡張(あるいは拡張したコードをレビューしたり)といった開発系の仕事をすることがあります。そうした開発系の話をしたいと思っていたところに、いい機会で声をかけてもらった、というのが経緯です。こうしたテーマでのプレゼンはほとんど経験がないので、デモとスライドは手探り状態で準備したところがありました。60分予定のところが90分かかるなど時間管理もなってない状況でしたが、フィードバックを得て今後の改善につなげていきたいと思います。懇親会での反応を見ると、興味を持っている方が少なからずいるのだろうと感じました。また初対面の方が多く刺激的でした。
 使う側の立場でMySQLを見ると、簡単に使える方が良いに決まっています。ハッキングなどという手間のかかることはやらないに越したことはありません。しかし今回のデモを通じて、「個人的な興味」という枠を超えて、普通に効果的な場面が出てくる可能性があることも感じていただけたのではないかと思います。MySQLはプラグイン化の流れを推し進めており、本体の拡張に比べるとずっと手軽にプラグインを作ることができます。今回来ていた方の中にはC/C++を非常に得意としている方も少なからずいたので、kazuhookuさんのQ4M斯波さんのSpiderのようなゼロからストレージエンジンを作る、とはいわないまでも、実用的なUDFなどは結構出てくるかもしれないな、と期待しています。


●KVSとしてのRDBMSの可能性
 今回の勉強会で、1つの可能性として「Key Value StoreのAPIのような感覚でダイレクトにテーブルにアクセスする」という形を提示しました。1年ほど前にkazuhookuさんがポストした「MySQL (InnoDB) に直接アクセスしてタイムライン処理を高速化する話」をより簡易化したものです。一般化すると、1回のHTTPリクエストの処理にあたり、多数回の(効率の良い)SELECT文を実行しなければ結果を返すことができない、というタイプの処理を、高速化するための実装、ということになるでしょうか。この手の処理は、ストアドプロシージャを使うと、ネットワークアクセス回数を減らせるため高速化が可能です。しかしMySQLはオープンソースな上に、汎用的なストレージエンジンAPIが存在するため、C/C++でストレージエンジンAPIを直接呼び出すようなコードを書いて、それをUDFなどのプラグインから呼ぶ、といったことができます。本来、ストレージエンジンAPIは、それを実装する側(Q4M/Spiderのように、APIを実装する側)のために用意されているのですが、APIを呼ぶロジックの初期化/解放ロジックをきちんと書けば、呼ぶ側のコードを書くことも不可能ではありません。デモで示したパフォーマンス測定の数字を掲載しておきます(レコードはすべてInnoDBバッファプールにキャッシュされている状態。再現手順は資料の方に含まれています)。CPUネックの処理で、Intel Xeon X5560 Nehalem 2.80GHz*16コアのマシンでの結果です。

SQL文:
$ super-smack smack1.smack 20 1
Query Barrel Report for client c1
connect: max=15ms min=3ms avg= 5ms from 20 clients
q_per_s
113701.80
100回で1リクエスト→1137リクエスト/秒

ストアド:
$ super-smack smack1.smack 20 1
Query Barrel Report for client c1
connect: max=9ms min=3ms avg= 4ms from 20 clients
q_per_s
1771.54
1回で1リクエスト→1772リクエスト/秒

UDF:
$ super-smack smack1.smack 20 1
Query Barrel Report for client c1
connect: max=10ms min=3ms avg= 5ms from 20 clients
q_per_s
14983.40
1回で1リクエスト→14983リクエスト/秒


 ストアドよりも8.5倍も高速化したことに驚いた方も多かったのではないでしょうか。MySQLはRDBMSの中でも十分に速いとされていますが、(CPUネックの状況になれば)KVSに比べると圧倒的に遅くなってしまうことをご存知の方も多いでしょう。これは、MySQLが長いSQL文字列の構文解析はもちろんのこと、毎回の実行計画の作成(MySQLは実行計画のキャッシュ機構が無い)や文字列コピーの多用といった、CPUコストの高い処理を結構行なっているということにも大きな要因があります。こうした処理をことごとくすっ飛ばしてダイレクトにストレージエンジンにアクセスすれば、KVSほどではないにしても十分に高速なスループットを出すことができます。もちろん副作用も多く、あまり想定されていない使われ方なので前例がまるで無い(ドキュメントも無いに等しい)とか、ちょっとバグを残してしまったらmysqldごと落ちてしまうかもしれないとか、バージョン間の互換性が低いとか、実際にやってみると苦労が絶えないだろうと思いますが。。
 「RDBMSはSQLがあるから遅い」のであれば、「内部的にはSQLの実行経路を迂回した高速アクセスをすれば良い」というような裏技的な思考は個人的には好きです。今回のデモのように、クライアントから見てアクセス手段が透過的であれば、背後で何が行なわれていようとクライアント側は普通にSQL文(UDF)を呼べばいいだけなので影響がありません。RDBMSにはB+Treeインデックスがありますから、KVSによっては難しいソート済みの結果を返すことも簡単にできます。データ型の機構が強力な点(値チェックができる等)も魅力になるケースがあるでしょう。SQLを標準インターフェイスとしつつ、ごく一部の「非常に高速に処理する必要のあるクエリ」を処理するために使いやすい高速APIを用意し、しかもアプリケーションからはこれらを特別な意識をせずに使い分けることができる(UDFを明示的に呼ぶ程度でOK)、というアーキテクチャは、次の世代のRDBMSの1形態になりうるだろうと考えています。トップページなど大量のアクセスが来るページにおいて、複雑なクエリを実行しないと結果を返せない項目がある、といったケースでは面白いのではないでしょうか。
 あまり見慣れない手法でもあるので、いろいろな方と意見交換したいと思っています。ごく最近Twitterも始めましたので、気軽にフォローしてくださればと思います。

2 件のコメント:

wbx さんのコメント...

プレゼン聞いていた人です。面白いプレゼンテーションをありがとう。
特にUDF面白かったです。DBはSQLによる柔軟な高速アクセスを提供するもんだろうと思ってましたが、実行計画作成コストの高いSQLは捨てて、直接ストレージエンジンのAPIをたたいてしまえという発想が、さすがオープンソースだなあ、と。ただ、UDFはバージョン相違で動かなくなる可能性ありという運用管理性の悪さと、自作UDF起因でmysqld まるごと落ちる可能性があるあたりが非常に残念。
ところで、UDFってSQL実行計画作成コストをゼロにするようなモノ、ですよね。それ以外のコストも何か無くなるのでしょうか。疑問ですが、別MySQLにRDBMSのように実行計画キャッシュを持たせよう、という動きは無いのですか。Query Cache よりも実行計画キャッシュだと思うのですが。
worklog に replication 関係が多いのは、開発人員が replication に持ってかれているからだったりするのかな。

Yoshinori Matsunobu さんのコメント...

wbxさん、参加&コメントありがとうございます。
oprofile等で見ると、mallocやmemcpyに要した割合の方が高かったので、汎用的なストレージエンジンAPIという設計をした副作用(ストレージエンジンに値を渡すときは参照渡しではなくコピーして渡す、など)も大きいのだろうと考えています。
レプリケーションは、MySQLにおいて絶対的に必要とされる機能で要望も多いので、worklogエントリ数も多くなっています。実行計画のキャッシュ機構は、手間がかかる割に副作用もある(条件値によって適切な実行計画が変わる場合への対処とか、キャッシュ自体がmutexロック競合を生まないようにするとか)のと、現実的にはディスクI/Oネックになることが多いので相対的な効果は薄れることなどから、後手に回っているというのが実情です。

コメントを投稿