コンテンツにスキップ

Feature 40: 地理的分散ノード管理システム

Author: Masahiro Aoki

実装日: 2026年2月20日
バージョン: 1.0.0
ステータス: ✅ 実装済み

概要

EvoSpikeNet の地理的分散ノード管理システム(Feature 40)は、世界中に分散したノードをリージョン単位で管理し、障害時の自動フェイルオーバーとリージョン間レイテンシー最適化を提供します。

現状: 基本機能とAPIは動作しているものの、 一部モジュールが「🟡 部分実装」扱いとなっています。 ユニット・統合・性能テストは完備されており、 ドキュメントリンクの整備と追加テストによる完全判定を進めています。


アーキテクチャ

┌─────────────────────────────────────────────────────────┐
│                    GeoNodeManager                        │
│                                                         │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐ │
│  │  GeoRegion  │  │   GeoNode   │  │  LatencyMatrix  │ │
│  │  (5 default)│  │  (per node) │  │ (N×N regions)   │ │
│  └─────────────┘  └─────────────┘  └─────────────────┘ │
│                                                         │
│  ┌──────────────────────────────────────────────────┐  │
│  │  Background Health Poller (30s interval)          │  │
│  │  → RegionStatus update → Failover trigger         │  │
│  └──────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

デフォルト登録リージョン

GeoNodeManager は起動時に以下の5リージョンを自動登録します。

リージョンID 表示名 緯度 経度 優先度
ap-northeast-1 Asia Pacific (Tokyo) 35.68 139.69 1
us-east-1 US East (N. Virginia) 39.04 -77.49 2
us-west-2 US West (Oregon) 45.52 -122.68 3
eu-west-1 Europe (Ireland) 53.33 -6.25 4
ap-southeast-1 Asia Pacific (Singapore) 1.35 103.82 5

レイテンシー計算

リージョン間レイテンシーは Haversine 式による実際の地球上の距離から推定します。

\[d = 2r \cdot \arcsin\left(\sqrt{\sin^2\left(\frac{\phi_2 - \phi_1}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2\left(\frac{\lambda_2 - \lambda_1}{2}\right)}\right)\]
latency_ms = distance_km / 200.0 * 1000 + jitter_ms

東京 → バージニア: 約 145ms(地球一周の約 1/3)
東京 → シンガポール: 約 32ms


コアコンポーネント

GeoRegion

<!-- from evospikenet.geo_node_manager import GeoRegion, RegionStatus -->

region = GeoRegion(
    region_id="ap-northeast-1",
    display_name="Asia Pacific (Tokyo)",
    provider="aws",
    latitude=35.6762,
    longitude=139.6503,
    priority=1,
)
print(region.status)  # RegionStatus.ONLINE

RegionStatus:

説明
online 正常稼働中
offline オフライン
degraded 性能低下中
maintenance メンテナンス中
unknown 状態不明

GeoNode

<!-- TODO: update or remove - import failmport GeoNode, NodeGeoStatus -->

node = GeoNode(
    node_id="prod-gpu-node-01",
    region_id="ap-northeast-1",
    endpoint="10.0.1.100:8000",
    node_type="gpu",   # general / gpu / scheduler / storage
)

GeoNodeManager

<!-- モジュール 'evospikenet' が見つかりませんパッケージ内の移動/名前変更を確認してください -->
<!-_node_manager.add_region(region)
geo_node_manager.get_region("ap-northeast-1")
geo_node_manager.remove_region("ap-northeast-1")
regions = geo_node_manager.list_regions()

# ノード操作
geo_node_manager.register_node(node)
geo_node_manager.deregister_node("prod-gpu-node-01")
nodes = geo_node_manager.list_nodes(region_id="ap-northeast-1")

# アクティブリージョン
active = geo_node_manager.get_active_region()
geo_node_manager.set_active_region("us-east-1")

# フェイルオーバー
event = geo_node_manager.trigger_failover(
    from_region="ap-northeast-1",
    to_region="us-east-1",
    reason="region_health_check_failed",
    triggered_by="health_monitor",
)

# レイテンシー行列
matrix = geo_node_manager.get_latency_matrix()
# matrix["ap-northeast-1"]["us-east-1"] == 145.3

# レプリケーショングループ
source, targets, latencies = geo_node_manager.get_replication_group("ap-northeast-1")

REST API

GET /api/geo/status

レスポンス例:

{
  "active_region": "ap-northeast-1",
  "total_regions": 5,
  "total_nodes": 12,
  "online_regions": 5,
  "regions": {
    "ap-northeast-1": {
      "status": "online",
      "node_count": 4,
      "priority": 1
    }
  }
}

GET /api/geo/regions

全リージョン一覧を返します。

POST /api/geo/regions

新しいリージョンを登録します。

リクエストボディ:

{
  "region_id": "ap-northeast-3",
  "display_name": "Asia Pacific (Osaka)",
  "provider": "aws",
  "location": { "lat": 34.69, "lon": 135.50 },
  "priority": 6
}

GET /api/geo/regions/{region_id}

DELETE /api/geo/regions/{region_id}

GET /api/geo/nodes

クエリパラメータ: region_id, status

POST /api/geo/nodes

リクエストボディ:

{
  "node_id": "prod-gpu-node-01",
  "region_id": "ap-northeast-1",
  "endpoint": "10.0.1.100:8000",
  "node_type": "gpu"
}

DELETE /api/geo/nodes/{node_id}

POST /api/geo/failover

手動フェイルオーバーを実行します。

リクエストボディ:

{
  "from_region": "ap-northeast-1",
  "to_region": "us-east-1",
  "reason": "region_unavailable",
  "triggered_by": "operator"
}

レスポンス:

{
  "status": "failover_executed",
  "event": {
    "event_id": "550e8400-...",
    "from_region": "ap-northeast-1",
    "to_region": "us-east-1",
    "timestamp": "2026-02-20T10:30:00Z",
    "reason": "region_unavailable",
    "triggered_by": "operator",
    "success": true
  }
}

GET /api/geo/failover/history

クエリパラメータ: limit (デフォルト: 20)

GET /api/geo/latency-matrix

レスポンス例:

{
  "matrix": {
    "ap-northeast-1": {
      "us-east-1": 145.3,
      "us-west-2": 110.2,
      "eu-west-1": 230.1,
      "ap-southeast-1": 32.4
    },
    "us-east-1": {
      "ap-northeast-1": 145.3,
      ...
    }
  }
}

GET /api/geo/active-region

PUT /api/geo/active-region

リクエストボディ:

{ "region_id": "us-east-1" }

GET /api/geo/replication-group/{region_id}

レスポンス例:

{
  "source_region": "ap-northeast-1",
  "replication_targets": ["ap-southeast-1", "us-west-2"],
  "latencies_ms": {
    "ap-southeast-1": 32.4,
    "us-west-2": 110.2
  }
}


フェイルオーバーフロー

1. ヘルスチェック (30秒間隔)
        │
        ▼ 失敗を検出
2. RegionStatus → OFFLINE
        │
        ▼
3. target_region 選定
   (status==ONLINE かつ 最高優先度)
        │
        ▼
4. active_region 切り替え
        │
        ▼
5. FailoverEvent 記録
        │
        ▼
6. アクティブリージョンのノードが新リクエストを処理

設定

config/settings.yaml:

geo_node_manager:
  enabled: true
  health_check_interval_seconds: 30
  state_file: "data/geo/geo_state.json"
  default_regions:
    - id: "ap-northeast-1"
      priority: 1
  auto_failover: true
  replication_group_size: 2   # レプリケーション先リージョン数

性能指標

メトリクス 目標値 テスト参照
レイテンシー行列 (10 リージョン) < 50ms test_latency_matrix_10_regions
レイテンシー行列 (50 リージョン) < 500ms test_latency_matrix_50_regions
自動フェイルオーバー完了時間 < 30秒 システムテスト

テスト

# ユニットテスト
pytest tests/unit/test_geo_node_manager.py -v

# 結合テスト
pytest tests/integration/test_features_36_39_40_integration.py::TestGeoNodeEndpoints -v

# システムテスト(マルチリージョンライフサイクル)
pytest tests/system/test_features_36_39_40_system.py::TestMultiRegionNodeLifecycle -v

# 性能テスト
pytest tests/performance/test_features_36_39_40_performance.py::TestGeoNodeManagerPerformance -v

関連ドキュメント