マルチサーバーアーキテクチャ: 関心の分離

この記事では、我々のインフラストラクチャが関心の分離を通じてスケーラビリティ、信頼性、パフォーマンスを実現するために、どのように専門化されたサーバーを使用しているかを説明します。

問題点: モノリシックサーバーの限界

すべてを1台のサーバーで実行すると、以下の問題が発生します:

  • リソース競合: Webサーバーが検索サービスとCPU/メモリを奪い合う

  • スケーリングの困難: コンポーネントを独立してスケールできない

  • 単一障害点: 1台のサーバー停止 = システム全体が停止

  • コスト効率の悪さ: ワークロードごとにインスタンスタイプを最適化できない

  • デプロイリスク: 1つのコンポーネントのデプロイが他全てに影響する

複数のサーバーにわたる関心の分離が必要です。

解決策: 専門化されたサーバーロール

我々は、各々がそのワークロードに最適化された専門サーバーを実行しています:

graph TB
    subgraph prod[本番ERPサーバー]
        erp[内部管理システム
人事、財務、製造
24/7稼働
共有ストレージ & メール] end subgraph web[公開ウェブサイトサーバー] www[公開ウェブサイト
製品カタログ、ブログ
24/7稼働
CDN配信] end subgraph dev[開発/ステージングサーバー] devenv[開発 & ステージング環境
メールキャンペーン
夜間/週末は停止] end subgraph search[検索サービスサーバー] searchsvc[ベクトル検索
フィルター抽出
関連検索
24/7稼働] end subgraph cache[キャッシュサーバー - Valkey] valkey[RediSearchインデックス
クエリ埋め込み
オートコンプリート
24/7稼働] end www --> searchsvc searchsvc --> valkey

なぜサーバーを分離するのか?

1. リソース分離

各サーバーは1種類のワークロードを実行します:

Webサーバー: HTTPリクエスト処理に最適化

  • 高いネットワーク帯域幅

  • 中程度のCPU

  • 中程度のメモリ

  • キャッシュ用の高速ディスク

検索サービス: ベクトル演算に最適化

  • 高いCPU (コサイン類似度計算)

  • 高いメモリ (埋め込みキャッシュ)

  • 低いディスクI/O

キャッシュサーバー: メモリアクセスに最適化

  • 非常に高いメモリ

  • 低いCPU

  • 高速ネットワーク

利点: ワークロード間でのリソース競合が発生しない。

2. 独立したスケーリング

各コンポーネントを独立してスケールできます:

  • トラフィックが多い? ロードバランサーの背後にWebサーバーを追加。

  • 検索が遅い? 検索サーバーのCPUをアップグレードまたはレプリカを追加。

  • キャッシュミスが多い? キャッシュサーバーのメモリを増加。

  • 利点: 必要なものだけをスケールし、すべてをスケールする必要がない。

3. 障害分離

障害は局所化されます:

検索サービスが停止? ウェブサイトはキャッシュされた結果を提供し続ける。

キャッシュサーバーが停止? 検索サービスはキャッシュなしで計算を実行 (遅くなるが機能する)。

Webサーバーが停止? 内部ERPは影響を受けない。

利点: 部分的な障害がシステム全体に連鎖しない。

4. 安全なデプロイ

環境を経由してデプロイします:

開発環境 → デバッグツールで変更をテスト

ステージング環境 → 本番に近い環境でテスト

本番環境 → 確信を持ってデプロイ

利点: ユーザーに影響を与える前に問題を発見。

5. コスト最適化

サーバーごとにコストを最適化します:

  • 開発サーバー: 夜間/週末は停止 (50%のコスト削減)

  • IPv6専用サーバー: エラスティックIPコストなし (インスタンスあたり$5/月の節約)

  • 適切なサイズのインスタンス: ワークロードごとに必要なリソースのみを支払い

  • 利点: パフォーマンスを犠牲にすることなく、インフラコストを削減。

サーバー間のデータフロー

データがどのように流れるかを理解することは、分離が重要である理由を説明するのに役立ちます:

ユーザーリクエストのフロー

商品ページリクエスト:

sequenceDiagram
    participant User
    participant CDN
    participant Web as Web Server
    participant Search as Search Service
    participant Cache as Cache Server
    
    User->>CDN: 商品ページをリクエスト
    CDN->>CDN: キャッシュを確認
    alt キャッシュヒット
        CDN->>User: キャッシュされたページを提供
    else キャッシュミス
        CDN->>Web: リクエストを転送
        Web->>Search: 関連商品を取得
        Search->>Cache: 埋め込みをクエリ
        Cache->>Search: 結果を返却
        Search->>Web: 関連商品
        Web->>CDN: レンダリングされたページ
        CDN->>CDN: レスポンスをキャッシュ
        CDN->>User: ページを提供
    end

検索クエリのフロー:

sequenceDiagram
    participant User
    participant Web as Web Server
    participant Search as Search Service
    participant Cache as Cache Server
    
    User->>Web: 検索クエリを送信
    Web->>Search: クエリを転送
    Search->>Search: フィルターを抽出
    Search->>Search: 埋め込みを計算
    Search->>Cache: ベクトル検索
    Cache->>Search: ランク付けされた結果
    Search->>Web: 商品マッチ
    Web->>User: 結果をレンダリング

利点: 各サーバーは最適化された処理を実行する。

サーバーごとのストレージ戦略

異なるサーバーは異なるストレージ戦略を使用します:

Webサーバー

S3バックアップ静的ファイル: S3から提供される画像、CSS、JS

  • 高可用性

  • ローカルディスク使用なし

  • CDNに適している

ローカルキャッシュ: Nginxがレンダリングされたページをキャッシュ

  • 繰り返しアクセスが高速

  • 自動的な無効化

検索サービス

NumPy配列: バイナリ配列として保存される商品埋め込み

  • 高速なベクトル演算

  • 効率化のためのメモリマップ

  • 65K商品 × 768次元 = ~190 MB

JSONファイル: フィルターマッピング、フレーズテーブル

  • 人間が読みやすい

  • 更新が容易

  • 小さいサイズ (<10 MB)

キャッシュサーバー

Valkey (Redis): クエリ埋め込み、人気クエリ、オートコンプリート

  • 速度のためのインメモリ

  • ベクトルインデックス用のRediSearch

  • 耐久性のための永続化

なぜ異なるストレージか?

  • NumPy: ベクトル演算に最適化 (コサイン類似度)

  • JSON: 人間による編集に最適化 (フィルタールール)

  • Valkey: キーバリュー参照に最適化 (クエリキャッシュ)

CDNアーキテクチャ

公開ウェブサイトはコンテンツデリバリーネットワーク(CDN)の背後に配置されています:

キャッシュされるもの

静的アセット (長いTTL):

  • 画像、CSS、JavaScript

  • フォント、アイコン

  • 1年間キャッシュ

商品ページ (中程度のTTL):

  • 商品説明

  • 仕様

  • 1時間キャッシュ

クエリページ (短いTTL):

  • 検索結果

  • フィルターの組み合わせ

  • 5分間キャッシュ

キャッシュされないもの:

  • ユーザー固有のコンテンツ

  • APIエンドポイント

  • 動的検索

CDNが重要な理由

  • グローバルな遅延: エッジロケーションがユーザーに近い場所でコンテンツを提供

  • オリジン保護: CDNがトラフィックスパイクを吸収し、オリジンサーバーを保護

  • DDoS緩和: CDNがオリジンに到達する前に悪意のあるトラフィックをフィルタリング

  • コスト削減: オリジンへのリクエストが少ない = コンピュートコストの削減

デプロイパイプライン

問題を早期に発見するために、環境を経由してデプロイします:

開発環境

目的: デバッグツールによる迅速な反復開発 特徴:

  • コード変更時の自動リロード

  • 詳細なエラーページ

  • デバッグツールバー

  • キャッシュなし

利点: 開発者のための高速なフィードバックループ。

ステージング環境

目的: 本番環境に近いテスト 特徴:

  • 本番環境と同じ設定

  • 同じサーバーセットアップ (Gunicorn, Nginx)

  • 同じキャッシュ動作

  • 本番データから分離

利点: デプロイ前に本番固有の問題を発見。

本番環境

目的: 実際のユーザーにサービス提供 特徴:

  • パフォーマンスに最適化

  • フルキャッシュ有効

  • 監視とアラート

  • クラッシュ時の自動再起動

利点: 安定した信頼性の高いサービス。

参考文献

技術的概念

AWSサービス

  • CloudFront - AWS CDNドキュメント

  • S3 - AWSオブジェクトストレージドキュメント

  • DynamoDB - AWS NoSQLデータベースドキュメント

関連記事

まとめ

我々のマルチサーバーアーキテクチャは、専門化されたサーバー間で関心を分離します:

本番ERPサーバー:

  • 内部管理システム

  • 24/7稼働

  • 共有ストレージとメール

公開ウェブサイトサーバー:

  • 顧客向けウェブサイト

  • 24/7稼働

  • S3バックアップ静的ファイルを備えたCDN配信

開発/ステージングサーバー:

  • 安全なテスト環境

  • メールキャンペーン処理

  • コスト最適化 (夜間/週末は停止)

検索サービスサーバー:

  • ベクトル類似度検索

  • フィルター抽出

  • NumPyバックアップ埋め込み

キャッシュサーバー (Valkey):

  • クエリ埋め込みキャッシュ

  • RediSearchベクトルインデックス

  • 人気クエリランキング

主な利点:

  • リソース分離: ワークロード間での競合なし

  • 独立したスケーリング: 必要なものだけをスケール

  • 障害分離: 障害が連鎖しない

  • 安全なデプロイ: 本番環境投入前にテスト

  • コスト最適化: 適切なサイズのインスタンス、電源スケジュール

  • パフォーマンス: CDNキャッシュ、専門化されたストレージ戦略

このアーキテクチャにより、高い可用性、低遅延、管理可能なコストを維持しながら、数百万のリクエストを処理することが可能になります。


← ドキュメントインデックスに戻る