ノード、エッジ、方向
グラフ上のウォークとしてのリクエスト
リクエストが触れるすべてのコンポーネントはノードです:クライアント、DNSリゾルバ、CDNエッジ、リバースプロキシ、バックエンドレプリカ、データベース、キャッシュ。
2つのノード間のすべての接続は有向エッジです:リクエストは前方に流れ、レスポンスは後方に戻ります。前方のエッジは、オープンされたTCP接続とその上に構築されたプロトコルを表します。
単一のリクエストはこのグラフを通るパスです。システムがリクエストに応答するために実行する総作業量は、各ノードでの作業量の合計と、各エッジのレイテンシの合計に等しくなります。
なぜ重要か? グラフを描画すると、コードからは見えないプロパティが明確に浮かび上がります:
- ホップ数: パス内のエッジの数です。各ホップはレイテンシ(ネットワークの往復 + ノード処理)を追加します。ホップが少ないほど、レイテンシの下限値は低くなります。
- 入次数(インディグリー): ノードに向かうエッジの数です。入次数が高いということは、そのノードが多くのソースからリクエストを受け取り、スケーリングまたは自己防御を行う必要があることを意味します。
- 出次数(アウトディグリー): ノードから出るエッジの数です。出次数が高いということは、そのノードが多くの下流に依存しており、障害が発生する経路が多いことを意味します。
- カット頂点: 削除するとグラフが分断される単一のノードです。ピアのないリバースプロキシはカット頂点であり、これを削除するとそのオリジンへのすべてのアクセスが失われます。
トラフィックが集中する場所
ファンイン = 集中
ノードの入次数とは、そのノードに向かうエッジの数を指します。リクエストグラフにおいて、入次数はリクエストを送信する上流ソースの数を表します。
Fan-in パターン: 多数のクライアント -> 1つのCDN; 多数のCDNエッジ -> 少数のオリジンプロキシ; 多数のプロキシ -> より少数のバックエンドレプリカ; 多数のバックエンド -> 単一のデータベース。
集中が重要なのは、最大入次数ノードが最大の集約負荷を見るためである。 チェーンの末端にあるDBは、システム全体のすべてのアクティブなリクエストからのクエリを見る可能性がある。たとえ個々のユーザーが多くの負荷を発生させていなくても。
Fan-Out = 依存関係
ノードの出次数 = そのノードから出るエッジの数。高出次数は、多くの下流依存関係があることを意味する。
データベース、2つのキャッシュ、3つの外部API、およびキューを呼び出すバックエンドは、出次数が7である。その成功確率は、各下流の成功確率の積にほぼ等しくなる(成功したレスポンスのためにすべてが必須である場合)。
0.999 ^ 7 ≈ 0.993: 99.9%の信頼性を持つ7つの下流を持つバックエンドは、自身にバグがなくても、自身で達成できる信頼性は約99.3%に留まる。
出次数を削減する方法: 下流の結果をキャッシュする、非クリティカルな下流をオプションにする(グレースフルデグラデーション)、並列化できるものを並列化する。
非対称性
ファンインは負荷を集中させ、ファンアウトはリスクを増幅させます。適切に設計されたグラフは、最も影響の大きいノードにおいて、両方を最小限に抑えます。
データベース(最もファンインが高い): 負荷を軽減するために、アグレッシブにキャッシュを使用します。読み取りレプリカを使用して、ファンインを複数のノードに分散します。
オーケストレーターサービス(最もファンアウトが高い): 依存先ごとにサーキットブレーカー、グレースフルデグラデーション、バルクヘッドを実装します。
ノードの挿入が柔軟性を生む
間接性 = 中間ノードの追加
プロキシがない場合、グラフは client -> backend となります。クライアントはバックエンドのアドレスを知る必要があります。バックエンドを移動するには、クライアントを更新する必要があります(DNS や設定経由)。これは密結合です。
プロキシがある場合、グラフは client -> proxy -> backend となります。クライアントはプロキシのみを知っています。バックエンドを移動するには、クライアントではなくプロキシのアップストリーム設定を更新すればよいです。
グラフ操作: 既存のエッジに沿ってノードを挿入する。新しいエッジ client -> proxy は安定しており、新しいエッジ proxy -> backend は今後はチームが管理することになります。
幾何学的な読み方: 間接性は、上流の変更と下流の変更を切り離す層を追加します。各層のエッジは独立して再配線(リワイヤリング)できます。
間接性のコスト
各レイヤーが追加するのは以下の要素です:
- 1回のホップ分のレイテンシ(クライアントからプロキシへのエッジ)
- パス上の切断点(カット頂点)が1つ増える(プロキシ自体)
- 設定ミスが発生しうる箇所が1つ増える
その利点(配線の変更、スケーリング、シールド、TLSの終端、負荷分散)は、非自明なシステムであれば通常、コストを上回ります。しかし限界はあります:間接性のレイヤーを1つ追加するごとに、ホップが1つ増え、SPOF(単一障害点)の候補も1つ増えます。
民間の格言:あらゆる問題は、間接性のレイヤーを1つ追加することで解決できる(間接性のレイヤーが多すぎるという問題を除いて)。
アーキテクチャをグラフとして読み解く
統合
これにより、システムアーキテクチャをグラフとして読み取れるようになりました。ホップ数を数え、カット頂点を特定し、ファンインの集中度を測定し、ファンアウトから可用性の上限を計算し、間接化のトレードオフを評価できます。
これら4つをすべて適用してください。
新しいサービスに以下のアーキテクチャがあります: clients -> CDN -> reverse proxy (2 replicas) -> backend tier (8 replicas) -> { DB primary, cache cluster (3 nodes), external API }。
補足ノート
補足ノート
この幾何学に関するレッスンは、プロキシとオリジンのメインレッスンを、有向グラフの分析として再構築しています。
このコースの次の補足レッスンである geometry_of_stateless_horizontal_scaling では、メインのスケーリングレッスンからのレプリカ計算を取り上げ、キューイング曲線、リトルの法則、および80%利用率の膝点を幾何学的に導出します。
お疲れさまでした。