
2026/09/22 19:54
Show HN:対話型アーキテクチャ図付きのシステム設計アトラス
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
現代のデジタルサービスのスケールアップには、強力なハードウェアだけでなく、一貫性、可用性、パフォーマンスといった特定の制約に最適化された慎重に選択されたアーキテクチャパターンの採用が求められます。主要システムを例にとると、Twitter や Instagram は Cassandra を用いて効率的なファンアウト書き込みを実現し、Slack などのチャットアプリケーションはリアルタイムのステート管理のために Redis と WebSockets を活用しています。URL ショーテンナーでの深刻なリードスキャンや分散キャッシュにおけるホットキースタンプードに対処するためには、単純な modulo 演算ではなく、シャーディングと一貫したハッシングがアーキテクトによって採用されます。信頼性は多様なパターンを通じて確保されます:Saga パターンは不安定なサードパーティチャンネルをまたぐトランザクションを調整し(通知システムにとって重要)、決済処理では冪等性および ACID 一貫性を保証します。Circuit Breaker はデータ損失を防ぎ、Outbox パターン は非同期の請求処理を処理します。これからの将来、最適化は CRDTs および OTM という専門的な技術によって続き、これらは競合のない協調編集(例:Google ドキュメント)に用いられます。また、Elasticsearch は数十億ドキュメントの検索のための集約・分散検索を行い、Flink は正確に 1 回のクリック集計を通じて正確な請求を保証するために利用されます。究極的に言えば、業界はこれらの専門的なパターンへとシフトしています——座席予約のためのアデミッションコントロールからビデオストリーミングのためのオブジェクトストレージチャンキングまで——複雑なグローバルレートリミットとホットスポットを管理しながら、大規模でも途切れないユーザー体験を確保することを目指しています。
本文
システム設計頻出シナリオ 15 選:必須の知識とアーキテクチャ
システム設計において最も頻繁に問われるトピックを、核心となる最初の 5 つを含む計 15 つのシナリオで整理しました。それぞれの課題、解決策、推奨データベース・技術スタックを解説します。
📌 シナリオ 01: Twitter / Instagram Feed (タイムライン配信)
「有名人問題」:中央サーバーに全データを集約するとスケーリングが不可能です。ファンアウトコストは双極分布するため、中位ユーザー向けだけの設計では失敗します。
課題
- 大規模リーチ: 1 つの投稿を 1 億人のフォロワーへ配信する仕組みの構築。
- スケーラビリティ: 中央集権的な構造では書き込み・読み込みのボトルネックが発生する。
解決策
- Fan-out (ファンアウト): 投稿時(書き込み側)に即時処理し、事前通知を避けるアーキテクチャ。
- 例: トプ層ユーザーは後で取得するが、一般ユーザーは投稿時にフォロワーへコピーする。
- Caching (キャッシュリング): スローな DB 読み取りを避け、ホットデータを高速ストレージに保持。
おすすめデータベース:Cassandra
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 多数のノードで重負荷書き込みに対応するためのワイドカラム型データベース。 |
| Core Features | • Very fast writes (LSM tree) • Masterless, no single point of failure • Linear scaling by adding nodes • Tunable consistency per query • Multi-datacenter replication |
| When to Use | Write-heavy time series and activity feeds Always-on, multi-region data Access patterns known upfront by key |
📌 シナリオ 02: Chat / Slack (リアルタイム通信)
5,000 万同時ソケットと、順序付きメッセージ配信、会話中のオフライン対応が要件です。「Alice のメッセージを誰に届けるか」や「ユーザーがオフライン時の処理」も設計必須ポイントです。
課題
- リアルタイム性: ハプニング時にクライアントへ更新をプッシュする必要性。
- 状態管理: ソケットの保持と、ロードバランシングにおけるステートフルな挙動。
解決策
- WebSockets: ブラウザとサーバー間の永続的双方向接続を利用。
- Full-duplex over one TCP connection
- Server push, no polling (ポーリング非同期)
- Low per-message overhead
- ステートレス化: 接続状態の保持を減らし、リソース効率を高める工夫が必要。
おすすめデータベース:Cassandra
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 多数のノードで重負荷書き込みに対応するためのワイドカラム型データベース。 |
| Core Features | • Very fast writes (LSM tree) • Masterless, no single point of failure • Linear scaling by adding nodes • Tunable consistency per query • Multi-datacenter replication |
| When to Use | Write-heavy time series and activity feeds Always-on, multi-region data Access patterns known upfront by key |
📌 シナリオ 03: URL Shortener (URL 短縮)
1 日 1 億件のリンク生成と、読み込みの skewed(偏り)が発生します。単なる鍵生成ではなく、**「推定問題(Estimation)」と「キャッシュの問題」**として捉える必要があります。
課題
- 大容量書き込み: 高速で安定したキー生成が必要。
- 高頻度読み込み: アクセス偏りの大きい URL を高速に取得する。
解決策
- Estimation: トラフィック、ストレージ、容量のための概算計算(Bitwise masking など)。
- Caching (Redis): 高速な読み書きとメモリ内データストアとして利用。
- Sub-millisecond reads and writes
- Rich types: sorted sets, hashes, streams
- TTL expiry per key
- Atomic ops and Lua scripts
- Sharding: 単一ノードの容量制限を回避するため、データを分割する。
おすすめデータベース:Redis
| カテゴリ | コンテンツ |
|---|---|
| 概要 | キャッシュ、カウンター、キュー、Pub/Sub 向けに最適化されたメモリ内データストア。 |
| Core Features | • Sub-millisecond reads and writes • Rich types: sorted sets, hashes, streams • TTL expiry per key • Atomic ops and Lua scripts • Optional persistence and replicas |
| When to Use | Caching hot reads in front of a database Counters, rate limits, leaderboards Sessions and short-lived data with TTL |
📌 シナリオ 04: Distributed Rate Limiter (分散レートリミッター)
ステートレスな API サーバーにおいて、グローバルなリクエスト制限(例:1 秒間 100 万)を強制します。Redis への同期的ラウンドトリップを避けつつ、リミッター自身のダウン時にも動作を維持する設計が求められます。
課題
- 分散一貫性: 複数サーバーで正確なカウントを確保する。
- フォールトトレランス: リミッター自体が故障した際のフェイルオーバー。
解決策
- Rate limiting: クライアントあたりの時間窓ごとのリクエスト数を制限(Token Bucket / Leaky Bucket)。
- Concurrency: 多数のリクエストが同時にアクセスする際のデータ整合性の保証。
- Reliability: システムの一部故障でも動作を維持する仕組みの構築。
おすすめデータベース:Redis
| カテゴリ | コンテンツ |
|---|---|
| 概要 | キャッシュ、カウンター、キュー、Pub/Sub 向けに最適化されたメモリ内データストア。 |
| Core Features | • Sub-millisecond reads and writes • Rich types: sorted sets, hashes, streams • TTL expiry per key • Atomic ops and Lua scripts • Optional persistence and replicas |
| When to Use | Caching hot reads in front of a database Counters, rate limits, leaderboards Sessions and short-lived data with TTL |
📌 シナリオ 05: Notification System (通知システム)
多数のプロデューサーからイベントが発生し、複数のチャネル(アプリ内、メール、プッシュ)で配信されます。「何もしない」状態でも重複が出ず、不安定なプロバイダ一つでシステム全体がダウンしないことが要件です。
課題
- 非同期処理: プロデューサーとコンシューマーの速度差を吸収する。
- 冗長性と一貫性: メッセージの失われることなしに配信する保証。
- 障害対応: 依存サービスのダウン時にシステム全体が止まらない。
解決策
- Event-driven: サービス同士を直接呼び合えず、発行されたイベントに対して反応するアーキテクチャ。
- Kafka: サービス間のストリーミングイベント処理用。
- Replayability: consumers rewind offsets
- Durable, replicated partitions
- Fault tolerant: leader failover
- High throughput, scales by partitions
- Idempotency: リクエストを繰り返しても、一度実行したと同じ効果が得られること(重複処理の防止)。
- Circuit breaker: 失敗している依存呼び出しへの送信を一時的に停止し、回復を待つ仕組み。
おすすめパターン:Kafka / Event Bus
| カテゴリ | コンテンツ |
|---|---|
| 概要 | サービス間のストリーミングイベント処理用の分散パーティショニング・コミットログ。 |
| Core Features | • Replayability: consumers rewind offsets • Durable, replicated partitions • Fault tolerant: leader failover • High throughput, scales by partitions • Ordering within a partition |
| When to Use | Streaming events between many services Replaying history to rebuild or backfill High-volume logs, metrics, clickstreams |
📌 シナリオ 06: Search and Typeahead (検索・予測入力)
10 億ドキュメントと 1 秒間 10 万クエリを処理します。**「検索は Scatter-Gather(分散収集)」**であるため、遅延は最も遅いシャードによって決まります。また、インデックスとデータ間のラグについても設計が必要です。
課題
- 高負荷読み込み: インデックス更新時のパフォーマンス維持。
- 関連性の計算: テキスト検索におけるランキングの精度。
- リアルタイム性: 新しいドキュメントを検索結果に即座に反映させる。
解決策
- Search Engine: 逆インデックスを基盤とした分散検索エンジンを使用。
- Full-text search with relevance ranking
- Near real-time indexing
- Sharded and replicated
- Aggregations and faceting
- Fuzzy matching and autocomplete
おすすめデータベース:ElasticSearch
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 逆インデックスを基盤とした分散検索エンジン。 |
| Core Features | • Full-text search with relevance ranking • Near real-time indexing • Sharded and replicated • Aggregations and faceting • Fuzzy matching and autocomplete |
| When to Use | Full-text search and typeahead Searching and analyzing logs Filtering and faceting across many fields |
📌 シナリオ 07: Uber / Delivery Tracking (配送追跡)
50 万ドライバーが 4 秒ごとに位置情報を投稿し、リアルタイムでマッチングします。125 万のロケーション書き込みを処理するとともに、「同じドライバーを複数人へ割り当てる」競合問題を解決する必要があります。
課題
- ハイスピード書き込み: リアルタイムな位置情報の取り込み。
- リアルタイムマッチング: ユーザーとドライバーの即時ペアリング。
- トランザクション管理: 複数ステップのプロセス(割り当て → 移動 → 完了)での整合性。
解決策
- Geospatial: マップ上の位置による索引付けとクエリ(R-Tree など)。
- Indexing and querying things by location on a map.
- Real-time: ハプニング時にクライアントへ更新をプッシュする(WebSocket など)。
- Saga パターン: 失敗発生時に、補償ステップ(逆操作)によって複数ステップのトランザクションを元に戻す仕組み。
おすすめデータベース:Redis (Geospatial)
| カテゴリ | コンテンツ |
|---|---|
| 概要 | キャッシュ、カウンター、キュー、Pub/Sub 向けに最適化されたメモリ内データストア。 |
| Core Features | • Sub-millisecond reads and writes • Rich types: sorted sets, hashes, streams • TTL expiry per key • Atomic ops and Lua scripts • Optional persistence and replicas |
| When to Use | Caching hot reads in front of a database Counters, rate limits, leaderboards Sessions and short-lived data with TTL |
📌 シナリオ 08: Video Streaming (動画配信)
25 タラビット/秒の転送量に対応し、アップロード・トランスコード・配信を行います。アプリケーションサーバーを介さず、元々はメタデータサービスとトランスコーディングパイプラインが中心です。
課題
- 帯域幅の効率化: 膨大な動画データを効率的に保存・配信する。
- 負荷分散: オリジンサーバーへのアクセス集中を回避する。
- 分割再生: 動画の先頭まで読み込む時間を短縮するストリーミング方式の実装。
解決策
- Object storage: ファイルや BLOB の安くて耐久性の高いストレージ(例:S3)。
- Extreme durability (11 nines)
- Virtually unlimited scale
- Low cost per GB, storage tiers
- Presigned URLs for direct uploads
- CDN (Content Delivery Network): ユーザーに近いエッジサーバーからコンテンツを配信。
- Low latency from nearby edges
- Offloads traffic from the origin
- Caches static files and media
- Absorbs traffic spikes and DDoS
- Chunking: 大規模ファイルを分割してアップロード、重複削除、同期を行う技術。
おすすめパターン:CDN / S3
| カテゴリ | コンテンツ |
|---|---|
| 概要 | ユーザーに近いエッジサーバーからコンテンツを配信するシステム。 |
| Core Features | • Low latency from nearby edges • Offloads traffic from the origin • Caches static files and media • Absorbs traffic spikes and DDoS |
| When to Use | Static assets, images and video Users spread far from your origin Cacheable API responses at the edge |
📌 シナリオ 09: Web Crawler (ウェブクロール)
100 億ページのクロールを、単一のドメインへの負荷をかけずに行います。高速なクロールは容易ですが、**「素直さと配慮(Politeness)」**と、見てきたものの保存ができない規模での重複除去が課題です。
課題
- ドメイン負荷回避: クロール先サーバーのレートリミット遵守。
- 膨大なデデピュケーション: メモリ不足になり得る大量の URL 重複チェック。
- 分散管理: クローラー間のタスク配分と進捗共有。
解決策
- Bloom filter: 「確実にいない」か「いる可能性が高い」としか答えられないコンパクトな集合チェック(重複除去用)。
- Rate limiting: クライアントあたりの時間窓ごとのリクエスト数を制限する。
- Consistent hashing: ノードに追加しても鍵が移動するノード数を最小限にするハッシュ方式。
おすすめパターン:Bloom Filter / Queueing
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 集合チェックや分散管理のための軽量なデータ構造とキュー設計。 |
| Core Features | • Space efficient (Bloom filter) • Load balancing via consistent hashing • Rate limiting support |
| When to Use | Large scale deduplication Distributed task scheduling Rate-limited external access |
📌 シナリオ 10: Payment System (決済システム)
不安定な外部プロセッサを介した請求・受入・返金を行います。**「一貫性(Consistency)が可用性より優先される」唯一の設計パターンです。二重課金を防ぐため、「少なくとも一度は実行(At-least-once)」+「冪等性(Idempotency)」**の実装が必須です。
課題
- データの整合性: お金に関するデータは絶対に間引きたくない。
- 外部依存の不安定性: 決済ゲートウェイなどが落ちた際のロールバック処理。
- 二重支払いの防止: 重複リクエストに対して同一結果を返すこと。
解決策
- ACID Compliance: トランザクションデータのデフォルトとなる安全なリレーショナルデータベースを使用。
- Idempotency Key: リクエストを繰り返しても、一度実行したと同じ効果が得られることを保証するキー。
- Saga パターン: 失敗発生時に、補償ステップ(逆操作)によって複数ステップのトランザクションを元に戻す仕組み。
- Outbox Pattern: データベースにイベントを書き込む際に関連データも含めて書き込み、その後パブリッシュするパターン。
おすすめデータベース:Postgres
| カテゴリ | コンテンツ |
|---|---|
| 概要 | トランザショナルデータのデフォルトとなる安全なリレーショナルデータベース。 |
| Core Features | • ACID transactions • Joins, constraints, foreign keys • Strong consistency • Extensions: JSONB, PostGIS, full-text • Read replicas via streaming replication |
| When to Use | Money, orders, anything needing transactions Relational data queried with joins The default until scale forces otherwise |
📌 シナリオ 11: Ticketmaster / Booking (チケット販売)
同じ瞬間に 5 万人が同じ 100 席のチケットを予約しようとするのは、「競合(Contention)」の問題であり、単なるスケーリング問題ではありません。行ロック競合はまずスループットより先に壊れるため、アプリケーション階層前の**アドミッション制御(Admission Control)**で解決します。
課題
- 高頻度同時書き込み: 同一リソースへの多数の同時アクセス。
- 在庫管理: チケット切れを正確かつ迅速に判断する。
- データの整合性: 売り越しや二重予約を防ぐ厳密な制約。
解決策
- Concurrency Control: 多数のリクエストが一度にデータを触れる際の正しさの保証(行ロック、悲观锁など)。
- Admission Control: リクエストが処理される前にリソースが空かどうかをチェックする制御。
- Postgres: トランザショナルデータのデフォルトとなる安全なリレーショナルデータベース(ACID, Joins, Constraints など)。
おすすめデータベース:Postgres
| カテゴリ | コンテンツ |
|---|---|
| 概要 | トランザショナルデータのデフォルトとなる安全なリレーショナルデータベース。 |
| Core Features | • ACID transactions • Joins, constraints, foreign keys • Strong consistency • Extensions: JSONB, PostGIS, full-text • Read replicas via streaming replication |
| When to Use | Money, orders, anything needing transactions Relational data queried with joins The default until scale forces otherwise |
📌 シナリオ 12: Dropbox / File Sync (ファイル同期)
ファイルを再アップロードせずにデバイス間で同期します(例:1 つの段落の変更のみで 2GB ファイルを同期)。「帯域効率化のためのコンテンツ定義チャンキングとデルタ同期」および「オフライン編集後の整合性管理」が課題です。
課題
- 大容量ファイル同期: バンド幅を浪費しない効率的な同期手法。
- バージョン管理: ファイルの履歴保持と、差分のみを送信する効率化。
- コンフリクト解決: オフライン編集などで生じる変更の競合処理。
解決策
- Chunking: 大規模ファイルを分割してアップロード、重複削除、同期を行う技術。
- Deduplication: 重複するアイテムやメッセージを検出・破棄する処理。
- Object storage: ファイルや BLOB の安くて耐久性の高いストレージ(例:S3)。
おすすめパターン:Object Storage / Chunking
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 大容量ファイルの保存と効率的な同期。 |
| Core Features | • User uploads, media and backups • Large files rather than queryable records • Data lakes and long-term archives • Deduplication support |
| When to Use | • User uploads, media and backups • Large files rather than queryable records • Data lakes and long-term archives |
📌 シナリオ 13: Ad Click Aggregation (広告クリック集計)
1 秒間 100 万イベントをダッシュボードと正確な請求数字へ集約します。クリックは到着が遅れ、順序が乱れ、重複する可能性があるため、**「到着時間での集計は容易だが誤り」**であり、広告主はその数字で請求されるため精度が求められます。
課題
- ストリーム処理: 無限のイベントストリーム上でリアルタイムに結果を計算する。
- 正確な集計: 順序が乱れても正しい合計値を出すこと(Exactly-once semantics)。
- 遅延されたデータの処理: アフターカメで届くデータをどう扱うか。
解決策
- Stream processing: Flink 等の Stateful, real-time computations。
- Exactly-once state via checkpoints
- Event-time windows and watermarks
- OLAP: 巨大なデータセットでの集約にチューニングされた分析型データベース。
- Columnar storage and compression
- Fast aggregates over billions of rows
- Materialized views and rollups
おすすめパターン:Kafka (ストリーミング) / OLAP DB
| カテゴリ | コンテンツ |
|---|---|
| 概要 | サービス間のストリーミングイベント処理用の分散パーティショニング・コミットログ。 |
| Core Features | • Replayability: consumers rewind offsets • Durable, replicated partitions • Fault tolerant: leader failover • High throughput, scales by partitions • Ordering within a partition |
| When to Use | Streaming events between many services Replaying history to rebuild or backfill High-volume logs, metrics, clickstreams |
📌 シナリオ 14: Distributed Cache (Redis Cluster)
100 ノードでテラバイトのホットデータを保持し、サブミリ秒読み取りを行います。**「ノード追加時の再バランシング」と「一貫性ハッシュリング」**が重要です。単純な Modulo ハッシュリングではキャッシュの 80% が無効化され、スタンダム(圧縮)がかかります。
課題
- スケーラビリティ: ノード数を増やした際のデータ再配置のコスト削減。
- ホットキー問題: アクセス頻度が高いデータを均等な分散に保つ。
- データ損失防止: ノード障害時のデータの復旧。
解決策
- Consistent hashing: ノードに追加しても鍵が移動するノード数を最小限にするハッシュ方式(Redis Cluster 採用)。
- Caching (Redis): 高速な読み書きとメモリ内データストアとして利用。
- Sub-millisecond reads and writes
- Rich types: sorted sets, hashes, streams
- TTL expiry per key
- Atomic ops and Lua scripts
- Replication: データの耐久性と読み取りスケーリングのために複数のノードにコピーを保持する仕組み。
おすすめデータベース:Redis Cluster
| カテゴリ | コンテンツ |
|---|---|
| 概要 | 分散キャッシュクラスターとしての運用パターン。 |
| Core Features | • Consistent hashing for rebalancing • Sub-millisecond reads and writes • Atomic ops and Lua scripts • Replication for durability |
| When to Use | • Caching hot reads in front of a database • Counters, rate limits, leaderboards • Sessions and short-lived data with TTL |
📌 シナリオ 15: Google Docs (リアルタイムコラボレーション)
複数人が同時にドキュメントを書き込み、遅延もなくエディットが失われない設計です。「収束(Convergence)」と「最後のが勝ち」の禁止が重要なキーワードです。二人のユーザーが同じ文書部分を編集し、協調が必要な場合、『最後の書き込み勝ち』は致命的な失敗になります。
課題
- 同時エディット: 複数のユーザが同時に書き込む際の競合解決。
- 状態の同期: すべてのコピーが同一の状態(Convergence)に収束させること。
- 低レイテンシー: ユーザーへのフィードバックが瞬時であること。
解決策
- CRDT / OT: 並行エディットをマージして、すべてのコピーが同一の状態に収束させる方式。
- Merging concurrent edits so every copy converges to the same state.
- WebSocket: ブラウザとサーバー間の永続的双方向接続によるリアルタイム通信。
- Full-duplex over one TCP connection
- Server push, no polling
- Low per-message overhead
- Stateful: sticky, harder to load-balance
おすすめ技術:CRDT / WebSocket (Real-time Collaboration)
| カテゴリ | コンテンツ |
|---|---|
| 概要 | ブラウザとサーバー間の永続的双方向接続によるリアルタイム通信。 |
| Core Features | • Full-duplex over one TCP connection • Server push, no polling • Low per-message overhead • Stateful: sticky, harder to load-balance |
| When to Use | Chat, live collaboration, multiplayer Live feeds, presence, notifications Server must push without being asked |