Tallman

技術とか読書とかいろいろ

大規模サービス技術入門を読みました。ついでにRubyでVB Codeを実装してみた

大規模技術サービス入門という本を読みました。扱うデータの総量が大規模になってきたときに想定される問題、その問題に対処する具体的な方法がふんだんに書かれています。
株式会社はてなさんでやっている(いた?)インターンシップの内容がベースになっています。そのため、ある程度複雑な考え方や用語等も説明やイメージを織り交ぜて記載されています。

重要だと思った点は以下の3つです。

  • メモリ、OS、IOの動作といった低レイヤの知識
  • DBやアプリケーションのサーバーの構成
  • 計算量を減らすにはアルゴリズムの知識が必要

メモリ、OS、IOの動作といった低レイヤの知識は重要

まず本書の最初には、OS、メモリ、仮想メモリLinuxのページキャッシュ、そしてそれらにおける具体的な速度について丁寧な解説がありました。
「メモリ内で計算できないこと」が、いかにパフォーマンスに影響するかが具体的にイメージできるように解説されていました。
ディスクI/Oが多くなると重くなる。メモリの消費は少ないのがベターです。
ちょうど基本情報を受ける前に読んでいたので余計刺さりました。

DBやアプリケーションのサーバーの構成

スケールが難しいDBサーバーをスケールさせるための構成。その他にもボットのための専用サーバーを用意したり、冗長性のためのDBサーバーのマルチマスタ等具体的な構成が数多く紹介されています。
また、手法に対してメリットだけでなくデメリットも紹介されていました。例えばDBのパーティショニングを使えばDBの分散やキャッシュの効率は高まりますが、その分運用は複雑になります。メモリを増やすで対応できないかを検討する必要もありますし、運用を別の技術で解決できないかを考える必要もあります。(今はクラウドが主流だとは思うので別の知識も必要そうですが)

計算量を減らすにはアルゴリズムの知識が必要

二分木探索、n-gramインデックスの具体的な利用方法が紹介されていました。
また、メモリにキャッシュしやすくするための圧縮や計算量が大きくなりがちな全文検索については詳細に解説されています。 実際にPerlで書かれたサンプルコードとともにVBCodeや転地インデックスといって手法をコードに落としこんでいるところまで書いてあります。
自分も圧縮のときに紹介されていたVBCodeについてRubyで実装してみました。自分のコードで圧縮されたファイルっていいですね。

github.com IOクラスとかシリアライザとかまだまだ勉強不足ですね。

まとめ

大規模サービスについて想定される問題についての現実的な解決策が惜しげもなく公開されている良書でした。 一番なるほどと思った部分を引用します。

結局、原因がわかればその原因に対する対応方法は自明なのです。この自明になった対応方法を実践することが、チューニングにほかなりません。

サービスが大きくなってきたときにボトルネックになっているのはなんなのか、メモリにキャシュしきれてないのか、アルゴリズムが悪くディスクI/Oが多発しているせいなのか、はたまた外部のボット等全く違う要素なのか、正確に判断することが重要です。
そのためにはアプリケーションがどのように動いているか?という基本的かつ全般的なコンピューターやインフラの知識が必要だと感じました。
低レイヤやインフラだけでなく、ボットやリクエストの多いAPIに対して専用のサーバーを用意するといった、局所性を理解した構成のためには、サービスの理解も重要です。サービスを提供するって大変ですね。