3133 文字
16 分
高度なバックエンド エンジニアリング - 分散システムから回復力のあるアーキテクチャまで

1.0 はじめに: 避けられない分配の法則#

このシリーズのバージョン 1.0 は基礎を築き、バックエンド エンジニアリングの役割、ツール、初期のアーキテクチャ パターンを定義しました。 モノリスとマイクロサービス、SQL と NoSQL、REST と GraphQL について調査しました。 その知識は、機能的なアプリケーションを構築するために必要な基盤を表します。 ただし、このボリュームでは、これらのアプリケーションを拡張すると何が起こるかについて説明します。 単一のサーバーがフリートになると、単一のデータベースがクラスターになり、インプロセス呼び出しがネットワーク ホップになります。 これは 分散システムの領域であり、より厳しい別のルール セットによって管理されます。

単一マシン システムから分散システムへの移行は、複雑さが直線的に増加するわけではありません。 それはパラダイムシフトです。 単一マシンに当てはまる仮定。 信頼性の高いネットワーキング、ゼロ遅延、瞬時の操作。 粉々になっている。 高度なバックエンド エンジニアの主な目標は、基盤となる環境の本質的な信頼性の低さにもかかわらず、正しく確実に機能するシステムを構築することです。

1.1 分散コンピューティングの 8 つの誤謬#

1990 年代に、Sun Microsystems の L. Peter Deutsch らは誤謬のリストを作成しました。 分散アプリケーションを初めて使用するプログラマが行う仮定は常に危険にさらされます。

CAUTION

{title=“Eight Fallacies of Distributed Computing”}

  1. ネットワークは信頼できます。 (信頼できません。)
  2. レイテンシーはゼロです。 (実際にはゼロではありません。)
  3. 帯域幅は無限です。 (実際はそうではありません)。
  4. ネットワークは安全です。 (安全ではありません。)
  5. トポロジは変わりません。 (変わります。)
  6. 管理者は 1 名です。 (多数あります。)
  7. 輸送コストはゼロです。 (実際にはそうではありません。)
  8. ネットワークは均一です (実際は均一ではありません)。 :::本書で説明するすべてのパターン、プロトコル、アーキテクチャは、ある意味、これらの誤った考えの影響を軽減するための戦略です。

1.2 高度なバックエンド エンジニアリングのロードマップ#

基礎を構築して、最新のシステム アーキテクチャを定義する高度なトピックを探求します。

  • セクション 2: 高度なデータ管理と一貫性
  • セクション 3: 回復力のあるシステム設計パターン
  • セクション 4: 高度な非同期通信
  • セクション 5: 大規模なパフォーマンス エンジニアリング
  • セクション 6: 高度な API とセキュリティ アーキテクチャ

2.0 高度なデータ管理と一貫性#

1 つのデータベースを備えた単一サーバー アプリケーションでは、データの一貫性は主に ACID トランザクションによって解決されます。 分散システムでは、一貫性が最も難しい課題の 1 つになります。

2.1 一貫性スペクトルと PACELC 定理#

CAP 定理はネットワーク分割時の動作を説明しますが、PACELC 定理 はより完全な全体像を提供します。

NOTE

{title=“PACELC Theorem”} 「パーティション (P) がある場合、分散システムは可用性 (A) と一貫性 (C) のどちらかを選択する必要があります。そうでない場合 (E)、システムが正常に実行されている場合は、待ち時間 (L) と一貫性 (C) のどちらかを選択する必要があります。」 :::このため、アーキテクチャ上の微妙な議論が必要になります。 システムは、障害時の可用性のために一貫性を犠牲にしても、通常の動作時には遅延よりも一貫性を優先する場合があります。

2.2 分散トランザクション: Saga パターン#

2 フェーズ コミットは同期的であり、マイクロサービスには適していません。 Saga パターン は、ローカル トランザクションと補償アクションを通じてサービス間のデータの一貫性を管理します。

TIP

{title=“Saga Pattern Example: E-commerce Order”}

  1. Order Service: PENDING 状態の注文を作成し、ORDER_CREATED イベントを発行します
  2. Payment Service: 支払いを処理し、成功すると PAYMENT_PROCESSED を発行します。
  3. 「在庫サービス」: 在庫を更新し、成功時に「INVENTORY_UPDATED」を公開します。
  4. 「Order Service」: 注文を「CONFIRMED」に更新します。

障害の処理: 在庫に問題が発生した場合、支払いサービスは返金で補い、注文サービスはキャンセルされます。 :::実装スタイル:

NOTE

{title=“Saga Implementation Approaches”}

  • コレオグラフィー: サービスは中央コーディネーターなしでイベントをパブリッシュ/サブスクライブします
  • オーケストレーション: 中央オーケストレーターが佐賀の状態と補償トランザクションを管理します

2.3 イベントソーシングと CQRS#

これらのパターンは、拡張性と監査可能なシステムを構築します。

  • イベント ソーシング: 現在の状態の代わりに不変イベントを保存します。 現在の状態は、イベントを再生することによって取得されます。
NOTE

{title=“Event Sourcing Example”}

// 残高を保存する代わりに: 80
// イベントシーケンスを保存:
[
{"タイプ": "アカウント作成", "初期残高": 0},
{"タイプ": "DepositMade", "金額": 100},
{"タイプ": "出金", "金額": 20}
// 現在の残高 = リプレイイベント
「」
:::* **CQRS (コマンド クエリ責任分離):** 書き込みモデルを読み取りモデルから分離します。
:::tip
{title="CQRS Benefits"}
* 書き込みと読み取りに最適化されたさまざまなモデル
* コマンド側とクエリ側の独立したスケーリング
* 個別のコンテキストによるより優れたドメイン モデリング

2.4 バックエンドエンジニアのためのデータベース内部#

ストレージ エンジンとレプリケーション戦略を理解することは、パフォーマンスと信頼性にとって非常に重要です。

NOTE

{title=“MySQL Storage Engines”}

  • InnoDB: OLTP ワークロード向けのトランザクション、ACID 準拠、行レベルのロック
  • MyISAM: 高速読み取り、テーブルレベルのロック、トランザクションなし (新しいアプリでは非推奨) :::レプリケーション戦略:
TIP

{title=“Replication Models”}

  • リーダー/フォロワー: リーダーへのすべての書き込み、レプリカからの読み取り (最も一般的)
  • マルチリーダー: 複数のノードが書き込みを受け入れるため、レプリケートの競合を解決する必要があります
  • リーダーレス (Cassandra スタイル): 複数のノードに同時に書き込み、クォーラム読み取り :::トランザクション分離レベル (SQL):
NOTE

{title=“SQL Isolation Levels”}

  1. コミットされていない読み取り: コミットされていない変更 (ダーティ リード) を読み取ることができます。
  2. コミットされた読み取り: コミットされた変更のみを読み取ります (反復不可能な読み取りも可能)
  3. 反復読み取り: トランザクション内で一貫した行値 (ファントム読み取り可能)
  4. シリアル化可能: 完全なシリアル実行 (最高の一貫性、最低のパフォーマンス)

3.0 回復力のあるシステム設計パターン#

回復力とは、障害から回復して機能を継続する能力です。 障害を完全に防ぐのではなく、障害を適切に処理します。

3.1 サーキットブレーカーのパターン (詳細)#

サーキット ブレーカーは障害を監視し、分散システムでの連鎖的な障害を防ぎます。

NOTE

{title=“Circuit Breaker States”}

  • 休業中: 通常動作、リクエストのフロースルー、障害の監視
  • オープン: ダウンストリームの問題ではフェイルファスト、再試行する前にタイムアウト
  • ハーフオープン: 単一のプローブ リクエストでダウンストリーム リカバリをテストする

3.2 バルクヘッド パターン#

アプリケーション コンポーネントをプールに分離して、単一の障害がシステム全体に影響を与えるのを防ぎます。

TIP

{title=“Bulkhead Implementation”} ダウンストリーム サービスごとに個別のスレッド/接続プールを使用します。 サービス A が遅い場合でもサービス B のプールには影響せず、完全なシステム障害が防止されます。

3.3 再試行とタイムアウトのパターン#

分散システムでの一時的な障害を処理するために不可欠です。

CAUTION

{title=“Retry Best Practices”}

  • タイムアウト: 積極的なタイムアウトによりリソースの枯渇を防止します
  • 指数バックオフ: 再試行間隔を長くします (1 秒、2 秒、4 秒、8 秒)
  • ジッター: 雷のような群れの問題を防ぐためにランダム性を追加します。

3.4 レート制限と負荷制限#

サービスを過負荷から保護し、適切な機能低下を実装します。

NOTE

{title=“Rate Limiting Strategies”}

  • トークン バケット: トークンはリクエストに対して蓄積され、使用時に削除されます。
  • リーキーバケット: リクエストは固定レートで処理され、超過分は破棄されます
  • 負荷制限: 極度の負荷下で優先度の低いリクエストを拒否します。

4.0 高度な非同期通信#

非同期パターンは、回復力のある疎結合分散システムの基礎です。

4.1 メッセージ ブローカーとイベント ログ#

メッセージングに対するさまざまなアプローチには、明確なトレードオフがあります。

TIP

{title=“Message Broker Characteristics”}

  • RabbitMQ: スマート ルーティング、ワーク キューイング、メッセージ ブローカー モデル
  • Apache Kafka: イベント ストリーミング、永続ログ、複数のコンシューマ

4.2 冪等なコンシューマ#

メッセージング システムで「少なくとも 1 回」配信を処理する場合に重要です。

NOTE

{title=“Idempotency Strategy”}

関数 processMessage(メッセージ) {
if (processedMessages.contains(message.id)) {
戻る; // 重複をスキップ
}
// 処理メッセージ
プロセスビジネスロジック(メッセージ);
// 処理済みとして追跡 (ビジネス ロジックを使用したアトミック)
処理済みメッセージ.add(メッセージ.id);
}
「」

4.3 トランザクション送信ボックスのパターン#

イベント駆動型システムでのアトミックなデータベース更新とイベント発行を解決します。

TIP

{title=“Transactional Outbox Flow”}

  1. ビジネスエンティティを更新し、単一のローカルトランザクションで送信トレイにイベントを挿入します
  2. メッセージリレーはイベントを非同期的に発行し、送信済みとしてマークします
  3. 分散トランザクションなしでアトミック性を保証 4.「少なくとも 1 回」配信セマンティクスを提供します

5.0 大規模なパフォーマンス エンジニアリング#

ボトルネックを特定して排除するための体系的な規律。

5.1 キャッシュ パターン (詳細)#

基本的なキャッシュアサイドを超えた高度なキャッシュ戦略。

NOTE

{title=“Caching Pattern Comparison”}

  • キャッシュアサイド: アプリコードはキャッシュ、遅延読み込みを管理します
  • リードスルー: キャッシュは DB からのデータロードを処理します
  • ライトスルー: キャッシュ更新により DB が同期的に更新されます
  • ライトバック: キャッシュ更新は非同期的に DB にフラッシュされます :::雷の群れの緩和:
CAUTION

{title=“Thundering Herd Problem”} キャッシュされたアイテムの有効期限が切れると、何千ものリクエストが同時にキャッシュをミスし、DB を圧倒します。 解決策: ロックベースの再フェッチ。最初のリクエストのみがデータをロードし、他のリクエストは待機します。

5.2 同時実行性と並列性#

パフォーマンスの最適化のための基本的な概念。

TIP

{title=“Workload Matching”}

  • I/O バインドされたワークロード: 非同期モデル (Node.js、asyncio) は多くの同時リクエストを処理します
  • CPU バウンドのワークロード: 並列処理 (Go、Java) は複数のコアを活用します

5.3 プロファイリングとパフォーマンスのチューニング#

測定できないものを最適化することはできません。

NOTE

{title=“Performance Profiling”} プロファイラーを使用して、以下を特定するフレーム グラフを生成します。

  • コード実行パス内の CPU ホットスポット
  • メモリ割り当てパターンとリーク
  • I/O ボトルネックと待ち時間

6.0 高度な API およびセキュリティ アーキテクチャ#

分散環境の複雑さを管理するためのインフラストラクチャ レベルのソリューション。

6.1 API ゲートウェイ パターン#

クライアントとサービス間の通信を管理する単一のエントリ ポイント。

TIP

{title=“API Gateway Responsibilities”}

  • ルーティング: リクエストを適切なマイクロサービスに直接送信します
  • 認証/認可: エッジで資格情報を確認します。
  • レート制限: 使用ポリシーとスロットリングを強制します。
  • リクエスト変換: ダウンストリーム サービスのリクエストを適応させます。
  • 可観測性: 一元的なロギングとモニタリング

6.2 サービスメッシュ#

安全、高速、信頼性の高いサービス間通信のためのインフラストラクチャ層。

NOTE

{title=“Service Mesh Components”}

  • サイドカー プロキシ: (Envoy) はサービスごとにすべてのインバウンド/アウトバウンド トラフィックを処理します
  • コントロール プレーン: (Istio、Linkerd) はすべてのサイドカー プロキシを構成します
  • 機能: mTLS、トラフィック管理、分散トレース、可観測性

6.3 ゼロトラストセキュリティ#

分散システム向けの「決して信頼せず、常に検証する」セキュリティ モデル。

CAUTION

{title=“Zero Trust Principles”}

  • アイデンティティベースの認証: 送信元に関係なくすべてのリクエストを検証します
  • 最低特権アクセス: 必要な最小限の権限を付与します。
  • 侵害を想定: 内部侵害を想定した設計

6.4 JWT (詳細): リスクと緩和策#

JWT の脆弱性と安全な実装を理解します。

CAUTION

{title=“JWT Security Issues”}

  • アルゴリズム混乱攻撃: サーバーを騙して弱いアルゴリズムを導入する
  • 緩和策: 強力なアルゴリズム (RS256) のみを受け入れるようにライブラリを構成します。
  • トークンの失効: ステートレス トークンは無効化できません
  • 緩和策: 失効拒否リストを高速キャッシュに維持する

7.0 結論: 原則的なエンジニア#

バージョン 2.0 は分散システム エンジニアリングに移行しました。 回復力とスケーラブルなバックエンド システムを構築するには、遅延と一貫性、可用性と正確性、速度と安全性といった基本的なトレードオフを深く理解する必要があります。

高度なバックエンド エンジニアは、障害に備えて設計し、ネットワークの敵対性を想定し、サーガ、イベント ソーシング、サーキット ブレーカー、サービス メッシュなどのパターンを適用します。 究極のスキルは、複雑さについて推論することです。 障害点、ボトルネック、脆弱性を特定して、適切な緩和戦略を適用します。

高度なバックエンド エンジニアリング - 分散システムから回復力のあるアーキテクチャまで
https://banije.vercel.app/ja/posts/deep_dive_into_backend_development_v2/
作者
ibra-kdbra
公開日
2025-05-12
ライセンス
CC BY-NC-SA 4.0