まさ@ブログ書き込み中

まさ@ブログ書き込み中

まさの旅、英語、プログラミング、プライベートについて、色々記録しています。

『大規模サービス技術入門』の序盤をまとめる

 

こんにちは、ついにRailsチュートリアルの向こう側に行ってしまったまさです。

 

昨日の夜から『大規模サービス技術入門』を読み始めました。

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

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

 

このブログサービス「はてなブログ」を運営している株式会社はてなインターンシップの内容がさらに濃くなったのが本書らしいです。

 

ISUCONのために勉強をし始めたものの、ISUCONの点数が上がりそうだからとかではなく普通に面白い。

 

何で面白いのか。ISUCONやRailsチュートリアルを通して多少なりとも「エンジニアはただアプリ作れば良い」という風にはもう思わなくなったからです(当たり前なのかもしれませんが、腑に落ちたって感じです)

 

 今回は本書の序盤(第0回〜第5回まで)をまとめていきます。

 

 

大規模なサービスとは

本書のタイトルの一部となっている「大規模サービス」って何なのか?

本書でははてなは大規模、GoogleFacebookは超大規模」と定義しています。

 

2009年当時のはてなのサービスの規模は

  • 登録ユーザー100万人以上、1500万UU(ユニークユーザー)/月
  • 数十億アクセス/月
  • ピーク時の回線トラフィック量は430Mbps
  • ハードウェア(サーバ)は500台以上

だそうな。

 

サーバー台数という観点で言えば百台〜数千台必要であれば、大規模サービスと言えるのでは、と言っています。

 

ちなみにGoogleFacebookは数百万台規模です。

 

 

大規模データ処理の難所

大規模データ処理の難所の第一のポイントは「メモリ内で計算できない」ということです。 

 

コンピュータのメモリに載っていないデータが必要な場合ディスクを読んでいかなければなりませんが、ディスクはメモリと比べて圧倒的に読み込み速度が遅いのです。メモリはディスクの10*5~10*6倍(10万倍~100万倍)以上高速です

 

よって「いかにメモリで済ませることができるか」が大規模なデータを扱うコツです。具体策とその他ポイントは以下の通り。

 

いかにしてメモリで済ませるか

  • ディスクのシーク回数を最小化する
  • 局所性を活かした分散を実現する

その他のポイント

  • データ量の増加に強いアルゴリズムやデータ構造を取り入れる
  • データ圧縮、情報検索技術

 

 

OSのキャッシュと分散

上の「いかにしてメモリで済ませるか」に対応するポイントとして、メモリで済ませることでディスクのシーク(探索)回数を最小化することと局所性を活かした分散を挙げました。

 

これらは具体的にはどういう意味でしょうか?簡潔にまとめてみます。

OSのキャッシュ

本書ではLinuxの例が挙げられていますが、OSにはキャッシュ機構というしくみをもっています。OSはメモリが空いていれば、どんどんディスクをキャッシュしていきます。

つまり、メモリを増やせばI/O(Input/Output)が軽減できるということで、ディスクのシーク回数を最小化することにつながります

 

また、キャッシュは古いものから順に捨てられていきます。よって何かファイルをreadしたらそれが一気にキャッシュされ、メモリが足りない場合は古いキャッシュが捨てられます。

 

しかし、キャッシュを前提にしたI/O軽減策には限界があります。経済的コストとのバランスを考慮しなければならないようです。

 

2009年時点ではメモリの市場価格は2GB単体モジュールで2000円くらいなので、8GB積んでも1万円いきませんが、32GBとか64GBくらいないとキャッシュできないという話になり1枚で4GBのメモリを利用した場合、まったく値段が変わってきます*

*じゃあなぜ1枚4GBのメモリを使う必要があるんだ、とコンピュータに無知なまさは思いましたが、どうやらメモリを積むことができるメモリスロットというものがあり、それには限りがあるらしいです。

 

よって、ある程度を超えたI/O軽減策に関してはソフトウェアで頑張ったほうがいい、という話になってきます。

 

局所性を活かした分散

キャッシュの容量を増やすための次の策は、複数台の(DB)サーバにスケールさせることが挙げられます。

 

といっても単純にサーバの数を増やしただけでは、データを同期してしまえばサーバが一台の時とまったく同じことになるのでアクセスのパターンを考慮してDBへのI/Oを分散させます。

 

例えば、はてなブックマークの例で言えば

  1. entryテーブル
  2. bookmarkテーブル
  3. tagテーブル
  4. keywordテーブル

のうち1・2と3・4で分割し、それぞれ別のサーバで管理するようにしているみたいです。

 

 

その他の対策

次に、その他のポイントについて見ていきましょう。

 

データ量の増加に強いアルゴリズムやデータ構造を取り入れる

先ほど「データ量の増加に強いアルゴリズムやデータ構造を取り入れる」という対策案を挙げました。一見難しそうですが、何のことはありませんでした。これはMySQLのインデックスを利用するという話です。

 

どうやら、MySQLでインデックスを作ると、データ構造のパターンであるB木(ビーツリー)のバリエーションであるB+木によってツリーのデータ構造ができ、それは理論的に比較的早い検索を実現するそうな。

 

情報検索技術

ISUCONではサーバを増やしたりできないそうなので、これはあまり僕には関係のないアイデアなのですが、一応まとめておきます。

 

全文検索や類似文書系探索、データマイニングなどの大規模データを扱うケースでは、RDBMS(Relational Data Base Management System)では対応しきれません。よって、バッチ処理(コンピュータで、データをかなりの分量までためた時点で一遍に行う処理。)RDBMSからデータを抽出し、それで別途インデックスサーバのようなものを作って、そのインデックスサーバにWebアプリケーションからRPCなどでアクセスするといった方法を使うみたいです。

 

これを「用途特化型インデクシング」はてなでは呼んでいるそうです。RDBMSはデータをソートしたり、統計処理ができたり、JOINできたり、汎用的に作られているから今回のケースに対応できないのです。つまり特定の目的だけに使うようにチューニングしたデータ構造を使えば圧倒的に早い探索を実現できます

 

 

本書の序盤のまとめはここまで。

では、また。