うめすこんぶ

日々のプログラミングで残しておきたいメモ.何かの役に立てれば幸いです.

これからインフラを高速化したければ読んでおきたい「大規模サービス技術入門」

はてなの伊藤直也さんが書いた本ということで有名な本。

一言で言うと、はてなぐらいの大規模なWebサービスに必要なパフォーマンスを担保するための技術の解説。 最初から最後まで、如何にパフォーマンスを上げるか、という論点が多く、速度上げるの好きな自分としてはかなり満足行く内容だった。

印象に残った点

はてなの規模は? (2009当時)

月間1500万UU 数十億アクセス/月

はてなブックマークだと、レコード件数が1000万から5000万 ブックマークのentryテーブルは1500万レコード、3GB

インデックスを付けないと、idで絞り込んでアクセスした結果が200秒まっても返ってこないレベル。 このぐらいの件数だとそんなに掛かるのか。。

規模が日本のWebの中ではトップレベルだと思う。データ量もGB単位が当然のようになる。 ホスト台数も仮想化ホストでいえば1000台をこえる。

時代背景

このころだとまだAWSの文字がでてこない。HTTPリクエストをApacheのmod_rewrite使うなど。

DBのパフォーマンス改善(局所化を考慮する)

高速化のためアクセスパターンの振り分けは大事だ。

キャッシュに乗ったデータになるべくアクセスするように、アクセスするテーブルごとにDBサーバの担当を振り分ける。 そうするとあるDBサーバに関しては類似したアクセスが来るようになるので、キャッシュヒットしやすい。

また、テーブル内でも局所化を考慮してカラムを分けている。 例えば、bookmarkテーブルは必須のbookmarkやuid(ユーザーID)などのカラムとis_privateなどあまり使わないカラムを別テーブルに分けている。テーブルをコンパクトにすることで、レコードがメモリに乗りやすくなる。

DBのインデックスについて

MysqlのインデックスはB木が使われている。このB木のノードをちょうどLinuxページサイズである4KBほどになるように調整する。 すると、各ノードはディスクに1回アクセスするだけで得られる。ディスクにアクセスする回数が短いほどI/O処理は高速化する。 二分木と比べると、1度のI/Oで一気に複数の値を読み出せるB木は、ディスクと相性がいい。

Mysqlのexplainをよくつかって、ちゃんとインデックスが効いているか、処理は重くないかチェックする。

サーバー単位でのHTTP振り分け(やっぱりキャッシュ大事!)

通常のサービス用APPサーバとボットやフィード用サーバを分けている。ボットやフィードの場合、アクセスが局所的でなく、 全体を舐めるような形になる。キャッシュに乗りにくいアクセスパターンだ。もしボットなどのアクセスを通常サービス用のサーバに一緒くたにすると、 キャッシュが効きにくくなる。

そこで、ボット用のアクセスをボットを担当するサーバに振り分けて、サービス用サーバのキャッシュを汚さないようにする。 特にはてなブックマークの場合、内部リンクがかなり多いので、ボットの巡回するページ数が多く、ボットアクセスが多くなる。

また、通常サーバ、ボット用サーバ意外に画像APIサーバも用意している。

サーバーの分散処理

DBサーバーはマスタ+スレーブ構成にする。スレーブは参照系のクエリを担当し、マスタは更新系を担当する。 はてなは参照系が大部分なので、参照系のスレーブを複数台構成してアクセスを分散させることで、性能がスケールできる。

更新系のクエリの場合、マスタで処理してからマスタの更新をスレーブに反映させる。スレーブはその名の通り、マスタに追従する役目を持っているわけだ。

大体のWebアプリケーションは90%が参照系クエリなので、更新系のサーバーが1台でも問題ない。

ただし、あまりに更新が多い場合は、別手段としてKVSにするのもあり。例えば、mixiの足跡など、ページビューのたびに更新が発生するものは更新クエリが多い。

はてなではTokyo Tyrantを使っている。

KVSって何がオトクなのか。これは自分の意見だが、RDBと比べるとイメージとしては機能が単純な分高速。RDBはロックやロールバック用のwriteaheadのログ書き込み、トランザクション処理など高機能で色々やってくれる分処理に時間がかかる。これらの処理をなくしてショートカットした更新処理を行うのがKVSだと考える。

また、テーブル分割する実装も面白い。テーブルを分割してサイズを小さくすることで、サーバー内でもディスクのアクセス分散がしやすくなるし、異なるサーバーで分散させることもできる。

分散によるデメリット

デメリットについてもしっかり説明があった。

テーブルを分割して複数台のサーバーにそれぞれのテーブルを置くパターンも有る。例えば2台のサーバーにテーブルを置くとする。一見効率的に見えるが、この場合、必要なサーバー台数は2台ではなく4台になる。なぜなら、各サーバーごとに冗長化が必要だからだ。

そのため、安易にテーブルを分散しようとすると、余計なコストがかかるので、コストをしっかり考える。また、メモリ増設で対応できるなら、そちらを優先する。

まとめ

パフォーマンスを上げるために実際に行っている実践的なテクニックばかりで、非常にためになった。サービス規模が大きくなって来るとこの知見がきっと活かされるんじゃないかと期待。

[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ)

[Web開発者のための]大規模サービス技術入門 ―データ構造、メモリ、OS、DB、サーバ/インフラ (WEB+DB PRESS plusシリーズ)

「好奇心を“天職"に変える空想教室」を読んだ

好奇心を“天職

好奇心を“天職"に変える空想教室

TEDにて発表もされた、町工場の社長でありながら、ロケットを作っている植松努さんの著作。

今後の日本は、かつてない人口減少社会に突入します。ということは、いままでの常識が通用しないということ。また、日本の単位時間あたりのGDPは、フランスの半分しかありません。こんな日本で将来大丈夫なのでしょうか。

ですが、植松さんは、GDPが半分しかないなら、逆に改善の余地がたくさんある、と言っています。改善するためには、みんなの能力向上が必要で、能力向上は、失敗を避けずチャレンジすることで培われます。できるかどうかわからないけど、実現したいこととは、言い換えれば「夢を実現する」ということ。今後の世界では、結局なにが正しいか読めないからこそ、夢をもってチャレンジしていくことが大事です。

また、ロボットに雇用が奪われる未来だからこそ、ロボットに負けないように考える力が人間に必要です。考える力はどうしたらつくのかというと、やったことないことをやってみること、また、諦めず工夫する経験です。言い換えれば、これも夢へチャレンジですね。

夢をもった人が少ないと言われる昨今ですが、そんなことはありません。だれでも子供の頃は、やったことないことをどんどんやったし、諦めず工夫していました。でも、まわりの大人がだめとか、どうせ無理とか、心を殺すことばを使って今って、子供の心がだんだんなくなってくるとのこと。

大人として、我々は子供の夢を失わせないことも大事ですが、他人の否定に揺らがず、本当に自分のやりたいことを追求していく心を保つことが大事だと、改めて知らされました。

植松さんは、子供の頃から夢をもって活動されてきた方。今は、ロケットを飛ばすことと、住宅コストや食のコスト、教育コストを減らした社会システムを作ったりと、さまざまなチャレンジを実施しています。また、植松さんの町工場では、なんと、世界に3つしかない、無重力空間発生装置まであります。やりたいことを、失敗にめげずチャレンジして勝ち得てきた植松さんの半生に、大きな勇気をもらいました。