LESSON 25分

ストーリー

高橋アーキテクト
『SNSを作ってくれ』と言われたら、どこから始める?
高橋アーキテクト
えっと…データベースの設計から…?
高橋アーキテクト
それでは失敗する。最初にやるべきは、顧客が本当に何を求めているかを明確にすることだ。要件分析なしにアーキテクチャを決めるのは、地図なしで航海するようなものだ

要件分析のフレームワーク

Step-by-Stepアプローチ

// 要件分析の5段階プロセス
enum RequirementPhase {
  CLARIFY = "1. 要件の明確化",
  SCOPE = "2. スコープの決定",
  ESTIMATE = "3. 規模の見積もり",
  IDENTIFY_NFR = "4. 非機能要件の特定",
  PRIORITIZE = "5. 優先順位付け",
}

// Phase 1: 要件を明確化する質問リスト
const CLARIFICATION_QUESTIONS = {
  users: [
    "ユーザーは誰か?",
    "同時接続ユーザー数は?",
    "地理的な分布は?",
  ],
  features: [
    "最も重要な機能は何か?",
    "MVPに含める機能は?",
    "将来的に必要な機能は?",
  ],
  constraints: [
    "予算の制約は?",
    "技術的な制約は?",
    "規制要件は?",
  ],
  data: [
    "扱うデータの種類と量は?",
    "データの保持期間は?",
    "データの一貫性要件は?",
  ],
};

規模の見積もり(Back-of-the-Envelope Estimation)

// 概算見積もりの例: SNSサービス
class ScaleEstimation {
  // DAU(Daily Active Users)から始める
  readonly dau = 10_000_000; // 1000万DAU

  // 読み書き比率
  readonly readWriteRatio = 10; // 読み10 : 書き1

  // 1ユーザーあたりの1日の操作
  readonly writesPerUser = 2;  // 投稿
  readonly readsPerUser = 20;  // 閲覧

  estimate() {
    const totalWritesPerDay = this.dau * this.writesPerUser;
    const totalReadsPerDay = this.dau * this.readsPerUser;

    // QPS(Queries Per Second)
    const writeQPS = Math.ceil(totalWritesPerDay / 86400); // ~231 QPS
    const readQPS = Math.ceil(totalReadsPerDay / 86400);   // ~2315 QPS
    const peakWriteQPS = writeQPS * 3;  // ピーク時は3倍
    const peakReadQPS = readQPS * 3;

    // ストレージ見積もり
    const avgPostSize = 1024; // 1KB per post
    const dailyStorage = totalWritesPerDay * avgPostSize; // ~19GB/day
    const yearlyStorage = dailyStorage * 365; // ~7TB/year

    return {
      writeQPS, readQPS,
      peakWriteQPS, peakReadQPS,
      dailyStorage, yearlyStorage,
    };
  }
}

要件からアーキテクチャへの変換

アーキテクチャドライバー

要件の中で、アーキテクチャの選択に最も影響を与えるものをアーキテクチャドライバーと呼びます。

interface ArchitectureDriver {
  requirement: string;
  impact: 'high' | 'medium' | 'low';
  architecturalDecision: string;
}

// 例: SNSのアーキテクチャドライバー
const SNS_DRIVERS: ArchitectureDriver[] = [
  {
    requirement: "1000万DAUをサポート",
    impact: "high",
    architecturalDecision: "水平スケーリング可能なマイクロサービス構成",
  },
  {
    requirement: "フィードのリアルタイム更新",
    impact: "high",
    architecturalDecision: "Fan-outパターン + WebSocket",
  },
  {
    requirement: "画像・動画のアップロード",
    impact: "medium",
    architecturalDecision: "オブジェクトストレージ + CDN",
  },
  {
    requirement: "グローバル展開",
    impact: "medium",
    architecturalDecision: "マルチリージョンデプロイ",
  },
];

設計判断の記録(ADR)

// Architecture Decision Record
interface ADR {
  id: string;
  title: string;
  status: 'proposed' | 'accepted' | 'deprecated' | 'superseded';
  context: string;       // なぜこの判断が必要か
  decision: string;      // 何を選んだか
  consequences: string;  // 結果としてどうなるか
  alternatives: string[]; // 他の選択肢は何だったか
}

const exampleADR: ADR = {
  id: "ADR-001",
  title: "フィード配信にFan-out on Writeパターンを採用",
  status: "accepted",
  context: "フォロワーへのフィード配信の遅延を最小化したい",
  decision: "投稿時にフォロワー全員のフィードキャッシュに書き込む",
  consequences: "書き込みコストは増えるが、読み取りが高速になる",
  alternatives: [
    "Fan-out on Read: 読み取り時にフォロー先の投稿を集約",
    "ハイブリッド: フォロワー数で戦略を切り替え",
  ],
};

実践:要件から設計への変換プロセス

ビジネス要件
  ↓ 明確化 & 質問
機能要件 + 非機能要件
  ↓ 規模見積もり
アーキテクチャドライバー特定
  ↓ パターン選択
ハイレベルアーキテクチャ
  ↓ 詳細設計
コンポーネント設計 + API設計 + データモデル
  ↓ 検証
ADR作成 + レビュー + PoC

まとめ

ポイント内容
要件分析が最初コードやDBの前に「何を」「どれくらい」を明確にする
規模見積もりDAUからQPS、ストレージを概算する
アーキテクチャドライバー設計を決定づける重要な要件を特定する
ADR設計判断とその理由を記録する

チェックリスト

  • 要件分析の5段階プロセスを理解した
  • Back-of-the-Envelope Estimationの手法を把握した
  • アーキテクチャドライバーの概念を理解した
  • ADRの書き方を把握した

次のステップへ

次は「非機能要件の定量化」を学びます。可用性99.99%やp99レイテンシ200ms未満といった指標を、具体的にどう定義し測定するのかを掘り下げます。


推定読了時間: 25分