Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行...

Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models

アクターモデルにより、分散システムでの開発を行いやすくなります。C#ではMicrosoft Orleans や Dapr などのフレームワークを使うことによりアクターモデルを比較的簡単に開発をすることができます。しかし、Azureへのデプロイなど、難しい点も幾らかあります。この登壇ではアクターモデルでの開発、デプロイでの工夫とともに、『新しいイベントソーシング手法』であるDynamic Consistency Boundary 動的一貫性境界の手法についても簡単に扱います。

The actor model makes it easier to develop distributed systems. In C#, frameworks like Microsoft Orleans and Dapr allow us to develop actor models relatively easily. However, there are still some challenges, such as deployment to Azure. In this presentation, I will cover development and deployment techniques for actor models, and also briefly introduce the "Dynamic Consistency Boundary" - a new event sourcing approach.

Avatar for Tomohisa Takaoka

Tomohisa Takaoka

August 23, 2025
Tweet

More Decks by Tomohisa Takaoka

Other Decks in Programming

Transcript

  1. 自己紹介 高丘 知央 - Tomohisa Takaoka X: @tomohisa GitHub: @tomohisa

    Works at: 株式会社ジェイテックジャパン、J-Tech Creations, Inc. JTS Group - 株式会社ジャパンテクニカルソフトウェア 品川 CTO: 中小企業の受託開発をモダンな開発スタイルで。イベントソ ーシング、CQRSなどのソフトウェアアーキテクチャに関するコンサ ル業務 Microsoft MVP for Developer Technologies from Nov 2024- OSS: Sekiban - Event Sourcing and CQRS Framework. 2 / 31
  2. 本日のアジェンダ 1. ステートフルAPIのススメ 2. Microsoft Orleans と Dapr など、アクターフレーム ワークの紹介

    3. Azureへのデプロイと負荷テスト 4. 次世代イベントソーシング、DCB (Dynamic Consistency Boundary)の紹介 5. まとめ 3 / 31
  3. 1. ステートフルAPIのススメ なぜ今あえて“ステートフル”なのか? 従来: HTTPはステートレス、スケールしやすい=正義という前提 現実: 一貫性確保や高頻度更新で DB / 外部ストアがボトルネック化

    ("DBヘビー") 目的: 「どこで直列化し、どこで耐久化するか」を明示し開発/運用コストを下げる 次章以降で: その具体化としてアクターモデル (Orleans / Dapr) を紹介 4 / 31
  4. 1-1. ステートレス vs ステートフル 用語整理 観点 ステートレスAPI ステートフルAPI リクエスト処理 各リクエスト独立

    エンティティ/セッション状態を保持 一貫性 DB分離レベルとロックに依存 単一(論理)ライターで直列化 レイテンシ 毎回ストア往復 ホットデータをメモリ命中 複雑化ポイント 排他/リトライ/補償 ステート配置/ライフサイクル 例: カート、ゲームルーム、予約スロット、在庫など“キー単位で直列”したい領域 5 / 31
  5. 1-2. RDB + CRUD + ステートレスの課題 代表的な痛み 集約を跨ぐ更新 → 大きなトランザクション

    or 楽観ロック再試行地獄 Write Skew / Phantom Read / Lost Update への対策コスト増 高分離レベル (Serializable) はスループット劣化 & アボート増加 競合頻発領域ほど DB への集中 I/O + ロック争奪 = “DB税” 水平スケールした API インスタンス間で同じ行を頻繁に読み/書き → レース条件 結果: アプリコードが排他 / リトライ / サガ / アウトボックスで複雑化 6 / 31
  6. 1-3. 一貫性問題の具体例 Write Skew (夜勤最低1人ルール) 1. A/B 両トランザクション: 現在 2人

    在席を 読み取り 2. 各自「自分を外す更新」だけ実行 3. 両方コミット → 0人 (不整合) モデル上の難しさ 行単位ロック/楽観ロックでは「集合制約」を守りに くい Phantom: 条件検索結果が途中で変わる (枠数計算ズ レ) 再試行回数とレイテンシ増大、ユーザー体験悪化 7 / 31
  7. 1-4. なぜ“DBヘビー”はコスト高か トレードオフ構造 分離レベルを上げるほど: 一貫性↑ / 並行度↓ / コスト↑ 悲観ロック:

    待ち行列 & デッドロック対応 楽観ロック: 高競合領域でリトライ雪崩 さらに キャッシュ導入 → 一貫性/無効化の別課題発生 分散ロック (Redis等) → 単一メタストアへの新たな集中 結果として “性能のための複雑性” が累積 8 / 31
  8. 1-5. ステートフル化の基本パターン 代表パターン (軽量 → 構造化) 1. サーバー / Redis

    セッション (短命状態) 2. キュー + Message Group / Partition でキー直列化 (予約/在庫) 3. Redis Lua / 単スレッド演算で原子的更新 (カウンタ/残枠) 4. インメモリシャード (Consistent Hash) でキー→ノード割当 5. アクターモデル (Virtual Actor / Grain) で状態+直列処理をランタイム委譲 共通ゴール: 「キー単位 Single Writer」+「ホットデータはメモリ」 9 / 31
  9. 1-6. ステートフルで得られるメリット メリット 一貫性境界が“コードで明示”される → 誤用を減らす 直列化により行/集合制約を自然に保持 (ロック/再試行削減) メモリ命中で低レイテンシ &

    DBコスト圧縮 並行性バグ (レース / ダブル更新) の発生面積を縮小 考慮点 状態数増大時のリソース/ライフサイクル管理 分散トランザクションは依然サガ/補償が必要 次へ この“キー単位 Single Writer”をフレームワークで体系化 → Orleans / Dapr のアクターモデル紹介へ 10 / 31
  10. Client Command Model Query Model Command Handler Event Store Materialized

    View Event Projector Projection CQRS & Event Sourcing 2-1. イベントソーシングの基礎 Event Sourcing とは すべての状態変化を「過去形イベント」として append-only で記録し、その再生で現在状態を得るアーキテクチャ。 変更履歴 = 監査/分析/リプレイ資産 (消さない “ストーリー”) 状態再構築が決定的 (Deterministic) → テスト/AI 生成が容易 CQRS: 書き込み(決定)と読み取り(投影)の責務分離で最適化 Sekiban は Decide(State, Command)->Events / Evolve(State, Event)->State の純粋関数を核に安全に自動生成/改変しやすい形を提供 12 / 31
  11. Actor 1 State Execution Queue DB Transaction Actor 1 State

    Execution Queue DB Transaction Users Users Users Message Message 2-2. 早期Sekibanの課題とアクター モデル 従来: 単一プロセス/スレッド前提で同一集約への同時コマンド 直列保証が弱い → スケールアウトで競合/重複書き込み懸念 欲しい性質: 集約(キー)単位でシングルスレッド直列処理 場所透過性 (どのノードか意識しない呼び出し) 必要時にだけ活性化・非アクティブ化 (スパース状態数への 対応) → これをランタイムに委譲するモデル = アクターモデル (Virtual Actor) 13 / 31
  12. 2-3. Orleans の Virtual Actor (Grain) 概要 Grain = 状態

    + 振る舞いをカプセル化 (1 Grain 1 Key) メッセージ処理は 1 度に 1 つ (ロック不要で一貫性) = “Key 単位 Single Writer” を自動 実現 アクティベーション/配置はランタイム任せ → 水平スケール容易 ストレージ/ストリーム統合 (Persistence / Streaming) を選択可能 分散機能、クラスタ管理機能がOrleans に統合されていて、数千台の実績もある Sekiban: 集約 = Grain (または Handler) に写像し Decide/Evolve 呼出を直列化 → 排他 制御コード・再試行の削減 14 / 31
  13. 2-4. Dapr との比較と補完関係 観点 Orleans Dapr 直列化モデル Virtual Actor (Grain)

    State Store + Pub/Sub (Building Blocks) 主目的 .NET 向け仮想アクタ & 分散ラン タイム Polyglot サイドカー (標準化 API) 状態管理 Grain Persistence State Store API (Redis/Cosmos 等) ストリーミン グ 内蔵 Streams Pub/Sub Building Block ポリグロット 限定 (.NET中心) 高い (複数言語) Sekiban は コア(イベントソーシング)を共有し Orleans 版 / Dapr 版 をテンプレートで生成可能 → ラ ンタイム選択の柔軟性 15 / 31
  14. 2-5. Sekiban 実装パターン & DX 基本構造: 1. Decide(State, Command) →

    新イベント列 (バリデーション + 不変条件チェック) 2. Evolve(State, Event) → 新状態 (純粋関数) 3. Grain/サービス側で: Command 受信 → イベント再生で State 構築 → Decide → Events Append → Projection へ非同期反映 AI / DX 観点: 決定的・小さな純粋関数面積 → 生成/レビュー容易、過去形イベント命名 + 単純レイアウト = LLM 参照しや すい Projection 追加は副作用隔離で低リスク、アクターモデルが並行バグを構造的に抑止 Append-only で破壊的変更を回避 (“Regret 最小化”) テンプレート: dotnet new sekiban-orleans-aspire / dotnet new sekiban-dapr-aspire 小さく開始 → 必要に応じ Orleans クラスタ / Dapr サイドカーへ水平拡張 16 / 31
  15. 2-6. アクターモデルまとめ この章の要約: Event Sourcing は履歴完全保持 + 決定的再生で開発/AI 支援を強化 Actor

    (Orleans/Dapr) が “Key 単位 Single Writer” をランタイム提供し複雑な排他制御 を除去 Sekiban は両ランタイムに跨る共通関数型コアで移植性と選択肢を確保 結果: 一貫性 / スケール / DX / AI 生成適合性 を同時に高める基盤 次章: これを Azure へどうデプロイし負荷特性を検証するか 17 / 31
  16. Orleans のデプロイに関して App Serivce, Azure Container Apps にデプロイ可能 App Service

    で、Gateway とクライアント接続の2ポートをあけ、スケールアウトした時に相互通信してくれる。 必要なリソース Web Server & Orleans Server (App Service or Azure Container Apps) App Service は固定費用でメモリ量安定、ACAはフレキシブルにスケール クラスタ管理ストレージ (Azure Table Storage or SQL Server or Cosmos DB or Redis ...) ステート管理ストレージ (Azure Blob Storage or SQL Server or Cosmos DB or Redis ...) Pub/Sub用キュー管理 (Azure Queue Storage or Azure Event Hub or Kafka ...) (Sekibanのイベント管理 独自) (Azure Cosmos DB or Postgres) (オプション) リアルタイム処理 (Azure SignalR) SekibanではデフォルトのBicep, デプロイスクリプトをテンプレートに同梱 19 / 31
  17. 管理者サイト App Service / Blazor App Service / Blazor クライアント

    サイト バックエンド App Service Clustoring State Streaming Cosmos DB Cosmos DB Azure Event Hub Streaming State Cosmos DB Events Cosmos DB リアルタイム  処理 Azure SignalR VNet Application Insights Log Analitics Workspace App Service スケールアウト可能 KeyVault 接続 情報 Aggregate Projection Grain 最新の State Snapshot Aggregate Event Handler Event Streaming Table Checkpointer Table Storage SignalR Hub Read Model Updator Event Subscription Event Subscription Multi Projection Grain Multi Projection, Aggregate List ライブプロジェク ション イベントプロセッ サー( 配分) Read Model 作成 処理 Read Model Postgres Command Query 20 / 31 アーキテクチャ概要
  18. Dapr のデプロイに関して Azure Container Apps にデプロイ可能, Dapr Sidecar 標準対応, Azure

    AppService は 多分難しい 必要なリソース Web Server & Dapr Server (Azure Container Apps) クラスタ管理ストレージ (ACAのDaprで標準対応) スケージュールサービス (ACAのDaprで標準対応) ステート管理ストレージ (Azure Blob Storage or Cosmos DB or Redis ...) Pub/Sub用キュー管理 (Azure Queue Storage or Azure Service Bus or Redis...) (Sekibanのイベント管理 独自) (Azure Cosmos DB or Postgres) (オプション) リアルタイム処理 (Azure SignalR) SekibanではデフォルトのBicep, デプロイスクリプトをテンプレートに同梱 21 / 31
  19. Sekibanの負荷テストに関して Azure Load Testing で Python の Locust を定義して、負荷テストを実施 複数拠点から実行してくれる

    10拠点で50スレッドを同時に実行したりできる シンプルな作成、データ読み込み、修正をひたすら実行させる Orleans + Azure Container Apps で、スケールアウト最大5で、分間10000程度実行可能 最低1台から、2分未満で5台までオートスケールアウト、負荷テストが終わったら数分で1台に戻ってくれる Orleans + Azure App Service スケールアウトなし(1台)だと、2拠点からの実行を超えるとエラーが増える スケールアウトにより同時実行性が高まることがわかる。 安価で、同時実行も限定的な場合は、App Service B1 でMinimal で月2000円未満で実行もできる 22 / 31
  20. 4-1. DCB とは何か 課題: 一部ビジネスルールは「複数集約をまたぐ短時間の強整合性」を要求。しかし巨大トランザク ション / グローバルロックはスループットと運用コストを悪化。 DCB (Dynamic

    Consistency Boundary): タグ / クエリ / 指定キー集合から動的に “一時的一貫性境 界” を形成し、その境界内で生成されたイベントセットを整合性検証後にアトミックコミットする構 想。 狙い: Saga の過剰増殖 (補償ロジックの記述量) を削減 強整合性が必要な瞬間だけ境界を構築し普段は疎結合 Event Sourcing の履歴/監査/リプレイ性は維持 (イベントは append) 25 / 31
  21. 4-3. メリット / 課題 / ステータス メリット: 必要箇所だけ強整合性 → 通常は単一アクター直列で軽量

    複雑な補償(Saga)・暫定状態クリーンアップ削減 一括イベントコミットで “何が共に確定したか” 可観測 (境界ID) イベントが集約に限定されず、真の意味での起きた事実の記録を実践できる 課題: 境界サイズ増加時のスループット低下 (統計/メトリクス必須) ホットキー集中境界のスロットリング戦略 ステータス: 現在: テスト実装成功 https://dcb.events/ 本日 Preview 版をリリースしました!!! dcb.events/librariesにも初のC#プロジェクトとしてプルリク作成 https://www.nuget.org/packages/Sekiban.Dcb 27 / 31
  22. まとめ ステートフル化で一貫性確保コストとDBボトルネック/レイテンシを同時に改善 アクターモデル (Orleans / Dapr) が “Key 単位 Single

    Writer” をランタイム提供 Sekiban: Decide/Evolve の純粋関数 + Event Sourcing で DX / AI コーディング最適化 Azure: テンプレート+Bicep で迅速デプロイ & オートスケール負荷検証が容易 DCB: 複数集約を動的境界で束ね瞬間的強整合性を実現する次のチャレンジ (Preview) 今後: ランタイム選択の柔軟性深化 / DCB安定化 / AIファースト開発環境強化 ご質問・フィードバックお待ちしています 29 / 31