本記事で取り上げるのは、アレックス・シュウ『システム設計の面接試験』(ソシム)です。
以下は本を読んで自分が考えたことをまとめたものです。本の要約を目的にしたものではありません。
記載に誤りや、権利・内容面で気になる点がありましたら、Xまでお知らせいただけますと幸いです。
はじめに
システム設計の面接対策のためと、普段使っているサービスがどんな仕組みで動いているのか知りたくて、『システム設計の面接試験』を読みました。
読み終えてみると、面接対策にとどまらず、普段の仕事でサーバーの構成を決めるときにも使える、思っていた以上に実践的な一冊でした。
そのため、次のような方に向いていると思います。
- サーバーの構成を決めるとき、何を根拠にすればいいか分からない
- ユーザー数やアクセス数のような要件から、どう構成を決めればいいか分からない
- キャッシュや DB の複製を、どんなときに、何のために使うのかを知りたい
どんな本か
本書は、システム設計の面接で出される問題と、その解き方を解説した本です。
全 16 章のうち、本編の 1〜15 章は、扱う内容で次の 3 つに分けられます。
- 1〜3 章: 設計の進め方と見積もりの基礎(1 台のサーバーから数百万人規模への構成の広げ方、面接を進める 4 つのステップなど)
- 4〜7 章: 大規模なサービスを支える仕組みの設計(レートリミッター、コンシステントハッシュなど)
- 8〜15 章: 4〜7 章の仕組みを組み合わせた、身近なサービスの設計(URL 短縮、YouTube、Google ドライブなど)
最後の 16 章では、企業のエンジニアブログなど、学び続けるための資料が紹介されています。
また、図が多く、構成の全体像をつかみやすいです。
本書では、題材ごとに、その場面に必要な仕組みを選んでいきます。
そのおかげで、キャッシュやキューといった仕組みを、「どんなときに、何のために使うのか」と一緒に知れます。
こうした仕組みを一冊でつかめるのが、この本の良さだと思います。
どれを採用するかについては、多くの章で、方式ごとの長所と短所を並べたうえで、要件に合わせて選んでいます。
自分で作るか既存のものを使うかも同じで、たとえば 4 章のレートリミッターでは、制限する仕組みをどこに置くかについて、次のように書かれています。
絶対的な答えはありません。それは、あなたの会社における現在の技術スタック、エンジニアリング・リソース、優先順位、目標などに依存します。
(アレックス・シュウ『システム設計の面接試験』ソシム、4 章、66 ページ)
そのうえで、自分で作る人手が足りなければ、商用の API ゲートウェイを使うのがよいとも案内しています。
この本を読んでから、自分のシステムに当てはめるときも、どの手段を取るかを考える前に、まず今の構成や人手を整理することを、より意識するようになりました。
なお、障害への備えは、6 章で検知から復旧まで手順を追って詳しく解説されています。
サービスの設計を扱う章の一部でも、障害を扱う節で構成要素ごとの対処を短く並べています。
障害に強い構成をさらに深く学ぶなら、別の本も読むとよさそうです。
以下では、本書で特に印象に残った 2 点を取り上げます。
1. 要件を整理し、数字に落として設計の前提をつくる
読んでみて一番印象に残ったのは、完成した構成図そのものよりも、その構成をどんな順番で決めていくかでした。
本書では、3 章で示す面接の進め方(4 つのステップ)に沿って、4 章と 6〜15 章の問題を解いていきます。
題材は、レートリミッターのような仕組みから YouTube のようなサービスまでさまざまです。
面接の 4 つのステップを、8 章の URL 短縮での進め方と、自分の普段の仕事の進め方に並べると次のようになります。
| 面接のステップ | 8 章 URL 短縮での進め方 | 自分の実務 |
|---|---|---|
| 1. 問題を理解し、設計範囲を明確にする | URL の数・長さ・使える文字などを質問し、読み書きの QPS と保存量を見積もる | PdM と、何をどれくらいの規模で作るかをすり合わせる |
| 2. 高度な設計を提案し、賛同を得る | 短縮とリダイレクトの 2 つの API を決め、301 と 302 のどちらを使うかを選ぶ | 基本設計の段階で構成図をエンジニアに見せ、方向性の合意を取る |
| 3. 設計の深掘り | 短い URL の作り方を 2 つ比べ、読み込みが多いのでキャッシュを置く | 詳細設計まで詰めて、エンジニア同士でレビューする |
| 4. まとめ | 時間があれば、レートリミッターや DB のスケーリングにも触れる | 設計書に、今回スコープ外にしたことや、今後の課題を書いておく |
面接の手順でありながら、自分の普段の仕事の進め方ともよく重なります。
そのため、面接対策として 11 問を解くことが、そのまま実務で設計を進める練習にもなると感じました。
最初に要件を確かめる
本書は、問題を渡されてもすぐに答えを出さず、まず質問して要件をはっきりさせるよう勧めています。
具体的には、3 章ではニュースフィードを例に、次のような面接官とのやり取りの形で質問を重ねていきます。
候補者:これはモバイルアプリですか、それとも Web アプリですか、それとも両方ですか?
面接官:両方です。
候補者:製品において最も重要な機能は何ですか?
面接官:投稿できることと、友だちのニュースフィードが見られることです。
(アレックス・シュウ『システム設計の面接試験』ソシム、3 章、53 ページ)
このやり取りを追うと、要件を確かめるときに何から、どう聞けばよいかが分かります。
特に、3 章の次の一文には強く共感しました。
エンジニアにとって最も重要なスキルの1つは、正しく質問し、適切な仮定を立て、システムを構築するために必要なすべての情報を収集することです。
(アレックス・シュウ『システム設計の面接試験』ソシム、3 章、52 ページ)
おおまかな見積もり
3 章の問答では、このあとトラフィック量まで質問しています。
確かめた要件は、次に数字へ落とします。
本書の 2 章では、ユーザー数から 1 秒あたりの問い合わせ数(QPS)やデータの保存量を概算する方法が紹介されています。
その際は、正確さより過程が大事で、仮定を書き出して単位を付け、桁が合う程度に丸めればよいという考え方です。
たとえば 8 章の URL 短縮では、次の仮定を置きます。
- 1 日に作られる URL: 1 億件
- 読み込みと書き込みの比率: 10 対 1
- 稼働する期間: 10 年
- URL の平均の長さ: 100 バイト
ここから、次のように見積もっています。
- 書き込み: 1 億件 ÷ 24 時間 ÷ 3,600 秒 ≒ 毎秒約 1,160 件
- 読み込み: 1,160 件 × 10 ≒ 毎秒約 11,600 件
- 10 年分の保存量: 1 億件 × 365 日 × 10 年 × 100 バイト ≒ 36.5TB
このように、本書は構成を、感覚ではなく見積もった数字を根拠に決めていきます。
たとえば 8 章では、読み込みが書き込みより多いことを理由に、設計を深掘りする段階でキャッシュを置いています。
こうした見積もりを実際のサービスで使った例としては、年越しのアクセス集中に備え、1 台あたりの上限から台数を出した LINE の記事が参考になると思います。
2. アクセス数だけでは決まらない。使われ方から負荷のかかり方を考える
一方で、同じアクセス数でも、読み込みが中心か書き込みが中心か、一部の利用者に偏るかといった使われ方によって、システムへの負荷のかかり方は変わります。
1 章では、1 台のサーバーから始めて、利用者が増えるたびに仕組みを足していきます。
読み込みは、書き込みよりずっと多いことを前提にしています。
そこで、よく使うデータをキャッシュに置き、DB を複製して読み込みを複数台に分けます。
それに対して、書き込みは、元の DB 1 台にすべて集まります。
書き込みやデータ量が増えて 1 台で受けきれなくなったときの方法の 1 つが、ユーザー ID などを基準にデータを複数の DB に分けて持つ「シャーディング」です。
たとえばユーザー ID を DB の台数で割った余りで振り分ければ、書き込みも保存量も複数台に分散できます。
ただし、この振り分け方では、DB を 1 台足しただけでほとんどのデータの置き場所が変わってしまいます。
1 章では、この問題の解決策として 5 章のコンシステントハッシュを挙げています。
サーバーとデータを同じ円の上に並べ、データは円を時計回りにたどって最初に当たるサーバーに置くので、台数を変えても動くのは隣り合う一部のデータだけで済みます。
コンシステントハッシュは、DB だけでなくキャッシュの振り分けにも使われています。
実際のサービスでの例としては、コンシステントハッシュで振り分けている Redis の台数とコストを見直した ABEMA の記事が参考になると思います。
4 章では、ボットや一部の利用者による過剰なリクエストが、サーバーに負荷をかける場面を扱っています。
そこで、一定時間あたりのリクエスト数を、ユーザー ID や IP アドレスごとに制限するレートリミッターを置きます。
このように、同じ「アクセスが多い」でも、読み込みが多いならキャッシュや DB の複製、書き込みが多いならシャーディング、一部の利用者に偏るならレートリミッターというように、検討する手段が変わります。
まとめ
本書を通して見えてきたのは、構成を決めるまでの次の順番でした。
- 要件を確認する
- 数字に置き換える
- 負荷のかかり方を確認する
- 構成を選ぶ
この順番で考えると、キャッシュや DB の複製も、「よく使われているから」ではなく「この要件と負荷だから」と理由を添えて選べるようになります。
本書では、ほかにも YouTube や Google ドライブなどの題材を、面接の 4 つのステップに沿って解いています。
要件から構成を決めるまでの考え方を、順を追って学べる一冊だと思います。
この記事が、本書を手に取るきっかけとなれば幸いです。


