大阪南港ATCで開催された「関西オープンソース2008」の2日目(11月8日)午前中のセッションで、株式会社はてなCTOの伊藤直也氏が「はてな流大規模データ処理」と題した発表を行った。このカンファレンスの目玉企画であり、立ち見が出るほど盛況を博したこのセッションでは、大量のデータを扱うWebサービスがどのように設計・運用されているかについて、伊藤氏自身が開発に携わってきた「はてなブックマーク」を題材に、現実的な手法が語られた。
大規模なデータとスケーリング
はてなブックマークでは、GB単位の大量のデータを扱っている。
レコ―ド数 | データサイズ | |
---|---|---|
エントリー | 1,073万 | 2.5GB |
ブックマーク | 3,134万 | 4GB |
タグ | 4,743万 | 3.4GB |
全文検索用HTML | ―― | 100GB超(zlibで圧縮した状態) |
大規模データのI/Oでは、メモリ(キャッシュ)とハードディスクの速度差を意識しなくてはならない。hdperm
コマンドで計測すると、データの転送速度では、メモリはディスクの100倍以上高速。シークの差で言えばディスクがms単位、メモリがns単位で、その差は数十万倍にもなるという。つまり、メモリの中で処理ができなくなりディスクにデータを読みに行った時点で、負けなのだ。
% sudo /sbin/hdparm -tT /dev/sda /dev/sda: Timing cached reads: 15012 MB in 1.99 seconds = 7525.03 MB/sec Timing buffered disk reads: 176 MB in 3.02 seconds = 58.37 MB/sec
上がキャッシュリード(メモリにあるOSのページキャッシュからの読み込み)で、1秒に8GBくらいを読み込んでいる。下がディスクのシーケンシャルリードで、60~70MB/sの速度しか出ない。
開発機で快適に動作しているサービスが、オープンした瞬間に何の変哲もないSQLが詰まって落ちることがある。これは、開発環境ではアクセスするデータがせいぜい決まってるので大抵キャッシュに乗っているが、本番環境に持っていくと、ユーザーがアクセスするデータの範囲が急に広くなるので、どうしてもディスクにデータを読みに行ってしまい、SQLが返ってこなくなるためだ。
大規模データをI/Oするコツは、「いかにメモリだけで済ませるか」。OSのキャッシュの仕組みを理解すること、局所性を活かすようにシステムを設計し、分散を考慮してRDBを運営することが重要だと伊藤氏は語る。
さらに、RDBだけに頼るのではなく、大規模データを扱う自前のアプリケーションを用意することも重要だ。データ量の増加に強いアルゴリズムやデータ構造を利用し、情報圧縮技術や情報検索技術を活用する。最近では、はてなでも検索技術を掘り下げているという。