システム設計面接の傾向と対策 (Zhiyong Tan)
書籍情報
- 著者:Zhiyong Tan(著), 水野貴明(訳), 吉岡弘隆(監訳)
- 発行日:2025-02-01
- ISBN:9784798072791
- URL:https://www.shuwasystem.co.jp/book/9784798072791.html
書籍目次
- 日本語版のためのまえがき
- 監訳者まえがき
- 訳者まえがき
- Part 1
- Chapter 1 システム設計に関する概念を俯瞰する
- 1.1 トレードオフについての議論
- 1.2 あなたは本書を読むべきでしょうか?
- 1.3 本書の概要
- 1.4 前奏曲: システムのさまざまなサービスにおける、スケーリングについての簡単な議論
- 1.4.1 始まり: アプリケーションの小規模な初期デプロイメント
- 1.4.2 GeoDNSでのスケーリング
- 1.4.3 キャッシングサービスの追加
- 1.4.4 コンテンツ配信ネットワーク
- 1.4.5 水平スケーラビリティとクラスタ管理、継続的インテグレーション、継続的デプロイメントについての簡単な議論
- 1.4.6 機能的分割と横断的な関心の集約
- 1.4.7 バッチあるいはストリーミングによる抽出、変換、書き出し(ETL)の処理
- 1.4.8 その他の一般的なサービス
- 1.4.9 クラウド vs ベアメタル
- 1.4.10 サーバレス: Function as a Service (FaaS)
- 1.4.11 結論: バックエンドサービスのスケーリング
- まとめ
- Chapter 2 典型的なシステム設計面接の流れ
- 2.1 要件を明確にし、トレードオフについて議論する
- 2.2 API仕様の草案を作成する
- 2.2.1 一般的なAPIエンドポイント
- 2.3 ユーザーとデータ間の接続と処理
- 2.4 データモデルを設計する
- 2.4.1 複数のサービスがデータベースを共有することの欠点の例
- 2.4.2 ユーザー更新の競合を防ぐために利用可能な技術
- 2.5 ロギング、モニタリング、アラート
- 2.5.1 モニタリングの重要性
- 2.5.2 オブザーバビリティ
- 2.5.3 アラートへの対応
- 2.5.4 アプリケーションレベルのロギングツール
- 2.5.5 ストリーミングあるいはバッチ処理によるデータ品質の監査
- 2.5.6 データ異常を検出するための異常検知
- 2.5.7 検知されないエラーと監査
- 2.5.8 オブザーバビリティに関する参考情報
- 2.6 検索バー
- 2.6.1 導入
- 2.6.2 Elasticsearchを用いた検索バーの実装
- 2.6.3 Elasticsearchインデックスと取り込み
- 2.6.4 SQLの代わりにElasticsearchを利用する
- 2.6.5 サービスでの検索の実装
- 2.6.6 検索に関する読み物
- 2.7 その他の議論
- 2.7.1 アプリケーションの運用と拡張
- 2.7.2 ほかのタイプのユーザーのサポート
- 2.7.3 代替となるアーキテクチャの決定
- 2.7.4 ユーザビリティとフィードバック
- 2.7.5 エッジケースと新しい制約
- 2.7.6 クラウドネイティブの概念
- 2.8 面接後の振り返りと評価
- 2.8.1 面接後できるだけ早く振り返りを書く
- 2.8.2 自己評価を書く
- 2.8.3 言及しなかった詳細な事項
- 2.8.4 面接のフィードバック
- 2.9 会社を面接する
- まとめ
- Chapter 3 非機能要件
- 3.1 スケーラビリティ
- 3.1.1 ステートレスサービスとステートフルサービス
- 3.1.2 基本的なロードバランサーの概念
- 3.2 可用性
- 3.3 フォールトトレランス
- 3.3.1 レプリケーションと冗長性
- 3.3.2 前方誤り訂正と誤り訂正符号
- 3.3.3 サーキットブレーカー
- 3.3.4 指数バックオフとリトライ
- 3.3.5 ほかのサービスのレスポンスのキャッシング
- 3.3.6 チェックポインティング
- 3.3.7 デッドレターキュー
- 3.3.8 ロギングと定期的な監査
- 3.3.9 バルクヘッドパターン
- 3.3.10 フォールバックパターン
- 3.4 パフォーマンス/レイテンシとスループット
- 3.5 整合性
- 3.5.1 フルメッシュ
- 3.5.2 コーディネーションサービス
- 3.5.3 分散キャッシュ
- 3.5.4 ゴシッププロトコル
- 3.5.5 ランダムリーダー選択
- 3.6 精度
- 3.7 複雑性と保守性
- 3.7.1 継続的デプロイメント(CD)
- 3.8 コスト
- 3.9 セキュリティ
- 3.10 プライバシー
- 3.10.1 外部サービス vs 内部サービス
- 3.11 クラウドネイティブ
- 3.12 さらなる参考情報
- まとめ
- 3.1 スケーラビリティ
- Chapter 4 データベースのスケーリング
- 4.1 ストレージサービスに関する簡単な前置き
- 4.2 データベースを使用する場合と避ける場合
- 4.3 レプリケーション
- 4.3.1 レプリカの分散
- 4.3.2 シングルリーダーレプリケーション
- 4.3.3 マルチリーダーレプリケーション
- 4.3.4 リーダーレスレプリケーション
- 4.3.5 HDFSレプリケーション
- 4.3.6 さらなる参考文献
- 4.4 シャーディングされたデータベースによるストレージ容量のスケーリング
- 4.4.1 シャーディングされたRDBMS
- 4.5 イベントの集約
- 4.5.1 単一層集約
- 4.5.2 多層集約
- 4.5.3 パーティショニング
- 4.5.4 イベントの種類が非常に多い場合
- 4.5.5 レプリケーションとフォールトトレランス
- 4.6 バッチおよびストリーミングETL
- 4.6.1 簡単なバッチETLパイプライン
- 4.6.2 メッセージング用語
- 4.6.3 KafkaとRabbitMQ
- 4.6.4 Lambdaアーキテクチャ
- 4.7 非正規化
- 4.8 キャッシング
- 4.8.1 読み取り戦略
- 4.8.2 書き込み戦略
- 4.9 別サービスとしてのキャッシング
- 4.10 異なる種類のデータのキャッシュの例とその手法
- 4.11 キャッシュの無効化
- 4.11.1 ブラウザキャッシュの無効化
- 4.11.2 キャッシングサービスでのキャッシュ無効化
- 4.12 キャッシュウォーミング
- 4.13 さらなる参考文献
- 4.13.1 キャッシングの参考文献
- まとめ
- Chapter 5 分散トランザクション
- 5.1 イベント駆動アーキテクチャ(EDA)
- 5.2 イベントソーシング
- 5.3 変更データキャプチャ(CDC)
- 5.4 イベントソーシングとCDCの比較
- 5.5 トランザクションスーパーバイザー
- 5.6 Saga
- 5.6.1 コレオグラフィ
- 5.6.2 オーケストレーション
- 5.6.3 比較
- 5.7 その他のトランザクションタイプ
- 5.8 さらなる参考文献
- まとめ
- Chapter 6 機能的分割のための共通サービス
- 6.1 サービスのさまざまな共通機能
- 6.1.1 セキュリティ
- 6.1.2 エラーチェック
- 6.1.3 パフォーマンスと可用性
- 6.1.4 ロギングと分析
- 6.2 サービスメッシュ/サイドカーパターン
- 6.3 メタデータサービス
- 6.4 サービスディスカバリ
- 6.5 機能的分割とさまざまなフレームワーク
- 6.5.1 アプリの基本的なシステム設計
- 6.5.2 Webサーバアプリケーションの目的
- 6.5.3 Webとモバイルのフレームワーク
- 6.6 ライブラリ vs サービス
- 6.6.1 言語に依存するか、テクノロジーに依存しないか
- 6.6.2 レイテンシの予測可能性
- 6.6.3 動作の予測可能性と再現性
- 6.6.4 ライブラリのスケーリングに関する考慮事項
- 6.6.5 その他の考慮事項
- 6.7 一般的なAPIパラダイム
- 6.7.1 OSI(Open Systems Interconnection)参照モデル
- 6.7.2 REST
- 6.7.3 RPC(Remote Procedure Call)
- 6.7.4 GraphQL
- 6.7.5 WebSocket
- 6.7.6 比較
- まとめ
- 6.1 サービスのさまざまな共通機能
- Chapter 1 システム設計に関する概念を俯瞰する
- Part 2
- Chapter 7 Craigslistの設計
- 7.1 ユーザーストーリーと要件
- 7.2 API
- 7.3 SQLデータベーススキーマ
- 7.4 初期の高レベルアーキテクチャ
- 7.5 モノリス型アーキテクチャ
- 7.6 SQLデータベースとオブジェクトストアの使用
- 7.7 移行は厄介な作業である
- 7.8 投稿の書き込みと読み取り
- 7.9 機能的パーティショニング
- 7.10 キャッシング
- 7.11 CDN
- 7.12 SQLクラスタによる読み取りのスケーリング
- 7.13 書き込みスループットのスケーリング
- 7.13.1 Kafkaのようなメッセージブローカーを使用する
- 7.14 電子メールサービス
- 7.15 検索
- 7.16 古い投稿の削除
- 7.17 モニタリングとアラート
- 7.18 これまでのアーキテクチャ議論のまとめ
- 7.19 その他の可能な議論トピック
- 7.19.1 投稿の報告
- 7.19.2 グレースフルデグラデーション(優雅な機能低下)
- 7.19.3 複雑さ
- 7.19.4 アイテムカテゴリ/タグ
- 7.19.5 分析とレコメンデーション
- 7.19.6 A/Bテスト
- 7.19.7 サブスクリプションと保存された検索
- 7.19.8 検索サービスへの重複リクエストを許可する
- 7.19.9 検索サービスへの重複リクエストを避ける
- 7.19.10 レートリミットの導入
- 7.19.11 大量の投稿
- 7.19.12 地域の規制
- まとめ
- Chapter 8 レートリミットサービスの設計
- 8.1 レートリミットサービスの代替案とそれが実現不可能な理由
- 8.2 レートリミットを行わない場合
- 8.3 機能要件
- 8.4 非機能要件
- 8.4.1 スケーラビリティ
- 8.4.2 パフォーマンス
- 8.4.3 複雑さ
- 8.4.4 セキュリティとプライバシー
- 8.4.5 可用性と耐障害性
- 8.4.6 精度
- 8.4.7 整合性
- 8.5 ユーザーストーリーと必要なサービスコンポーネントの議論
- 8.6 高レベルアーキテクチャ
- 8.7 ステートフルアプローチ/シャーディング
- 8.8 全てのカウントを各ホストに保存する
- 8.8.1 高レベルアーキテクチャ
- 8.8.2 カウントの同期
- 8.9 レートリミットアルゴリズム
- 8.9.1 トークンバケット
- 8.9.2 リーキーバケット
- 8.9.3 固定ウィンドウカウンター
- 8.9.4 スライディングウィンドウログ
- 8.9.5 スライディングウィンドウカウンター
- 8.10 サイドカーパターンの採用
- 8.11 ロギング、モニタリング、アラート
- 8.12 クライアントライブラリで機能を提供する
- 8.13 さらなる参考文献
- まとめ
- Chapter 9 通知/アラートサービスの設計
- 9.1 機能要件
- 9.1.1 通知サービスはアップタイムモニタリングには適さない
- 9.1.2 ユーザーとデータ
- 9.1.3 受信者チャンネル
- 9.1.4 テンプレート
- 9.1.5 トリガー条件
- 9.1.6 購読者、送信者グループ、受信者グループの管理
- 9.1.7 ユーザー機能
- 9.1.8 分析
- 9.2 非機能要件
- 9.3 初期の高レベルアーキテクチャ
- 9.4 オブジェクトストア: 通知の設定と送信
- 9.5 通知テンプレート
- 9.5.1 通知テンプレートサービス
- 9.5.2 追加機能
- 9.6 スケジュールされた通知
- 9.7 通知アドレス指定グループ
- 9.8 購読解除リクエストの処理
- 9.9 配信失敗の処理
- 9.10 重複した通知に関するクライアント側の考慮事項
- 9.11 優先度
- 9.12 検索
- 9.13 モニタリングとアラート
- 9.14 通知/アラートサービスの可用性モニタリングとアラート
- 9.15 その他の議論可能なトピック
- 9.16 最終ノート
- まとめ
- 9.1 機能要件
- Chapter 10 データベースバッチ監査サービスの設計
- 10.1 なぜ監査が必要なのか?
- 10.2 SQLクエリの結果に対する条件文による検証の定義
- 10.3 シンプルなSQLバッチ監査サービス
- 10.3.1 監査スクリプト
- 10.3.2 監査サービス
- 10.4 要件
- 10.5 高レベルアーキテクチャ
- 10.5.1 バッチ監査ジョブの実行
- 10.5.2 アラートの処理
- 10.6 データベースクエリの制約
- 10.6.1 クエリ実行時間の制限
- 10.6.2 送信前のクエリ文字列のチェック
- 10.6.3 ユーザーは早めにトレーニングを受けるべきである
- 10.7 同時に大量なクエリが実行されることを防止する
- 10.8 データベーススキーマメタデータのほかのユーザー
- 10.9 データパイプラインの監査
- 10.10 ロギング、モニタリング、アラート
- 10.11 その他の可能な監査タイプ
- 10.11.1 データセンター間の整合性監査
- 10.11.2 上流と下流のデータの比較
- 10.12 その他の議論可能なトピック
- 10.13 参考文献
- まとめ
- Chapter 11 オートコンプリート/タイプアヘッド
- 11.1 オートコンプリートの用途
- 11.2 検索とオートコンプリート
- 11.3 機能要件
- 11.3.1 オートコンプリートサービスの範囲
- 11.3.2 いくつかのUXの詳細
- 11.3.3 検索履歴の考慮
- 11.3.4 コンテンツモデレーションと公平性
- 11.4 非機能要件
- 11.5 高レベルアーキテクチャの計画
- 11.6 重み付けトライアプローチと初期の高レベルアーキテクチャ
- 11.7 実装の詳細
- 11.7.1 各ステップは独立したタスクであるべき
- 11.7.2 ElasticsearchからHDFSに関連ログを取得する
- 11.7.3 検索文字列を単語に分割し、ほかの単純な操作を行う
- 11.7.4 不適切な単語をフィルタリングする
- 11.7.5 ファジーマッチングとスペル修正
- 11.7.6 単語のカウント
- 11.7.7 適切な単語のフィルタリング
- 11.7.8 頻出の新しい未知の単語の管理
- 11.7.9 重み付けトライの生成と配布
- 11.8 サンプリングアプローチ
- 11.9 ストレージ要件の処理
- 11.10 単語ではなくフレーズの処理
- 11.10.1 オートコンプリート候補の最大長
- 11.10.2 不適切な候補のフィルタリング
- 11.11 ロギング、モニタリング、アラート
- 11.12 その他の考慮事項とさらなる議論
- まとめ
- Chapter 12 Flickrの設計
- 12.1 ユーザーストーリーと機能要件
- 12.2 非機能要件
- 12.3 高レベルアーキテクチャ
- 12.4 SQLスキーマ
- 12.5 CDN上のディレクトリとファイルの整理
- 12.6 写真のアップロード
- 12.6.1 クライアントでのサムネイル生成
- 12.6.2 バックエンドでのサムネイル生成
- 12.6.3 サーバサイドとクライアントサイドの両方の生成の実装
- 12.7 画像とデータのダウンロード
- 12.7.1 リストページの整合性の取れた読み込み
- 12.8 モニタリングとアラート
- 12.9 その他のサービス
- 12.9.1 プレミアム機能
- 12.9.2 支払いと税金サービス
- 12.9.3 検閲/コンテンツモデレーション
- 12.9.4 広告
- 12.9.5 パーソナライゼーション
- 12.10 その他の可能な議論トピック
- まとめ
- Chapter 13 コンテンツ配信ネットワークの設計
- 13.1 CDNの利点と欠点
- 13.1.1 CDNを使用する利点
- 13.1.2 CDNを使用する欠点
- 13.1.3 CDNを使用して画像を提供する際の予期せぬ問題の例
- 13.2 要件
- 13.3 CDNの認証と認可
- 13.3.1 CDNにおける認証と認可のステップ
- 13.3.2 キーローテーション
- 13.4 高レベルアーキテクチャ
- 13.5 ストレージサービス
- 13.5.1 クラスタ内
- 13.5.2 クラスタ外
- 13.5.3 評価
- 13.6 一般的な操作
- 13.6.1 読み取り/ダウンロード
- 13.6.2 書き込み: ディレクトリ作成、ファイルアップロード、ファイル削除
- 13.7 キャッシュの無効化
- 13.8 ロギング、モニタリング、アラート
- 13.9 メディアファイルのダウンロードに関して議論できる事柄
- まとめ
- 13.1 CDNの利点と欠点
- Chapter 14 テキストメッセージングアプリの設計
- 14.1 要件
- 14.2 設計の第一歩
- 14.3 初期の高レベル設計
- 14.4 接続サービス
- 14.4.1 接続の作成
- 14.4.2 送信者のブロック
- 14.5 送信者サービス
- 14.5.1 メッセージの送信
- 14.5.2 その他の議論
- 14.6 メッセージサービス
- 14.7 メッセージ送信サービス
- 14.7.1 導入
- 14.7.2 高レベルアーキテクチャ
- 14.7.3 メッセージ送信の手順
- 14.7.4 いくつかの質問
- 14.7.5 可用性の向上
- 14.8 検索
- 14.9 ロギング、モニタリング、アラート
- 14.10 その他の議論になる可能性のあるトピック
- まとめ
- Chapter 15 Airbnbの設計
- 15.1 要件
- 15.2 設計に関する決定事項
- 15.2.1 レプリケーション
- 15.2.2 部屋が借りられる状態かを保持するためのデータモデル
- 15.2.3 重複予約の処理
- 15.2.4 検索結果にランダム性を導入する
- 15.2.5 予約フロー中の部屋のロック
- 15.3 高レベルアーキテクチャ
- 15.4 機能的パーティショニング
- 15.5 リスティングの作成または更新
- 15.6 承認サービス
- 15.7 予約サービス
- 15.8 予約可能確認サービス
- 15.9 ロギング、監視、アラート
- 15.10 その他の議論可能なトピック
- 15.10.1 規制との付き合い方
- まとめ
- Chapter 16 ニュースフィードの設計
- 16.1 機能要件
- 16.2 高レベルアーキテクチャ
- 16.3 フィードを事前に準備する
- 16.4 検証とコンテンツモデレーション
- 16.4.1 ユーザーのデバイス上の記事の変更
- 16.4.2 記事のタグ付け
- 16.4.3 モデレーションサービス
- 16.5 ロギング、モニタリング、アラート
- 16.5.1 テキストだけでなく画像も提供する
- 16.5.2 高レベルアーキテクチャ
- 16.6 その他の議論可能なトピック
- まとめ
- Chapter 17 Amazonの売上トップ10の商品のダッシュボードの設計
- 17.1 要件
- 17.2 まず初めに考えること
- 17.3 初期の高レベルアーキテクチャ
- 17.4 集計サービス
- 17.4.1 商品IDによる集計
- 17.4.2 ホストIDと商品IDのマッチング
- 17.4.3 タイムスタンプの保存
- 17.4.4 ホスト上の集計プロセス
- 17.5 バッチパイプライン
- 17.6 ストリーミングパイプライン
- 17.6.1 単一ホストでのハッシュテーブルとmax-heap
- 17.6.2 複数のホストへの水平スケーリングと多層集計
- 17.7 近似
- 17.7.1 Count-Min Sketch
- 17.8 Lambdaアーキテクチャを使用したダッシュボード
- 17.9 Kappaアーキテクチャアプローチ
- 17.9.1 LambdaアーキテクチャとKappaアーキテクチャの比較
- 17.9.2 ダッシュボードのKappaアーキテクチャ
- 17.10 ロギング、モニタリング、アラート
- 17.11 その他の議論可能なトピック
- 17.12 参考文献
- まとめ
- Chapter 7 Craigslistの設計
- Appendix
- Appendix A モノリスとマイクロサービス
- A.1 モノリスの利点
- A.2 モノリスの欠点
- A.3 マイクロサービスの利点
- A.3.1 製品要件/ビジネス機能のアジャイルかつ迅速な開発とスケーリング
- A.3.2 モジュール性と置換可能性
- A.3.3 障害の分離と耐障害性
- A.3.4 所有権と組織構造
- A.4 サービスの欠点
- A.4.1 コンポーネントの重複
- A.4.2 追加コンポーネントの開発と維持のコスト
- A.4.3 分散トランザクション
- A.4.4 参照整合性
- A.4.5 複数のサービスにまたがる機能開発とデプロイメントの調整
- A.4.6 インターフェイス
- A.5 参考文献
- Appendix B OAuth 2.0認可とOpenID Connect認証
- B.1 認可と認証
- B.2 前置き: シンプルなログイン、cookieベースの認証
- B.3 シングルサインオン
- B.4 シンプルなログインの欠点
- B.4.1 複雑さと保守性の欠如
- B.4.2 部分的な認可がない
- B.5 OAuth 2.0フロー
- B.5.1 OAuth 2.0の用語
- B.5.2 初期のクライアントセットアップ
- B.5.3 バックチャンネルとフロントチャンネル
- B.6 その他のOAuth 2.0フロー
- B.7 OpenID Connect認証
- Appendix C C4モデル
- Appendix D 2フェーズコミット(2PC)
- Appendix A モノリスとマイクロサービス