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

Microsoft Orleansで始める、アクターモデルを使った分散システム入門

Tomohisa Takaoka
February 22, 2025
46

Microsoft Orleansで始める、アクターモデルを使った分散システム入門

https://dotnetlab.connpass.com/event/344101/

株式会社ジェイテックジャパン CTO Sekiban Framework メンテナ Microsoft MVP for Developer Technologies 高丘 知央

大量のデータ処理や高い可用性が求められる現代のサービスでは、分散システムによるスケーラブルな構成が不可欠です。しかし、分散システムは並行処理や状態管理が複雑になる課題があります。この課題に対応するために、アクターモデルとMicrosoft Orleansが効果的です。Orleansの仮想アクターは状態管理と負荷分散を容易にし、非同期処理をシンプルに記述可能です。本セッションでは、その仕組みと効率的な開発手法を紹介します。

Tomohisa Takaoka

February 22, 2025
Tweet

More Decks by Tomohisa Takaoka

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. 2025年3月14日に『イベントソーシング勉強会』を開催 2 / 32
  2. Application Servers Front End BFF Application Servers Application Servers Front

    End BFF Load Balancer Write DB Read DB Read DB Users Users Users Users Replication Transaction 1. アクターモデルとは ❶ モノリシックアプリケーションの負荷 対応の基本 水平スケーリング (Horizontal Scaling): 複数サーバーで負荷分散 アプリケ ーションサーバーは無限に近いスケ ール可能。 ロードバランサー: トラフィックを健康なサーバーに均 等分配。 キャッシング: レスポンス高速化のため、データを メモリ上に保存。 5 / 32
  3. Application Servers Front End BFF Application Servers Application Servers Front

    End BFF Load Balancer Write DB Read DB Read DB Users Users Users Users Replication Transaction 1. アクターモデルとは ❷ 一般的な3層アーキテクチャの課題 1. 3層アーキテクチャの制約: プレゼンテー ション層、ビジネス層、ストレージ層の 構造は、特にストレージ層がスケーリン グのボトルネックになる。 2. ステートレス: REST通信はステートレス なためデータベースに一貫性の管理が委 ねられる 3. キャッシュ導入時の問題: キャッシュはレ イテンシーを低減する一方、データ整合 性の維持が難しくなる。 6 / 32
  4. Application Servers Payment Domain Front End BFF Application Servers Shipping

    Domain Application Servers Analytic Domain Front End BFF Load Balancer Write DB Users Users Users Users Write DB Write DB API API API 1. アクターモデルとは ❸ マイクロサービス化は? サービス間通信の複雑さ: 水平方向のサービス呼び出しにより、通 信処理やトランザクション管理が複雑 化。 APIを直接呼び出すことによる密結合、修 正が難しくなる 7 / 32
  5. Application Servers Payment Domain Front End BFF Application Servers Shipping

    Domain Application Servers Analytic Domain Front End BFF Load Balancer Write DB Users Users Users Users Write DB Write DB API API API 1. アクターモデルとは ❹ マイクロサービス+イベント駆動は? イベント『駆動』による疎結合 密結合を解決するためにKafkaやEvent Busにより、コミュニケーションを Pub/Subで行う方法がマイクロサービス のベストプラクティス システムが巨大、複雑になる 8 / 32
  6. Actor 1 State Execution Queue DB Transaction Actor 1 State

    Execution Queue DB Transaction Users Users Users Message Message 1. アクターモデルとは ❺『アクターモデル』とは? 1973年にCarl Hewittらによって提案された並行計算モデルで す。分散システムにおけるスケーラビリティやデータ整合性の 課題を解決するために考案 アクターモデルの基本概念: 状態のカプセル化: 各アクターは自分の状態を持ち、他のア クターと共有しない。 メッセージの送受信: アクターはメッセージを通じて通信。 直接の状態共有を避けることで並行処理が容易になる。 アクターの生成: 必要に応じて他のアクターを生成できる。 こうした特徴により、アクターモデルは競合状 態を防ぎ、効率的な並行処理を可能にします。 9 / 32
  7. Actor 1 State Execution Queue DB Transaction Actor 1 State

    Execution Queue DB Transaction Users Users Users Message Message 1. アクターモデルとは ❻ アクターモデルの利点 アクターモデルでの解決策: 単一スレッド処理: アクターはシングルスレッドで実行されるため、ロッ ク不要で競合状態を回避。 自己管理された状態: 各アクターが状態を内部に保持し、状態管理の複雑さ を軽減。 非同期メッセージング: 通信処理が非同期で行われ、システムの全体的な応答 性が向上。 アクター内のステートが Single Source of Truthとなる!! 10 / 32
  8. Actor Users Users Users Applicatio Server 1 Actor Actor Actor

    Actor Actor Applicatio Server 2 Actor Actor Actor Actor Actor Model Message Message Message 1. アクターモデルとは ❼ アクターモデルにおけるクラスター 透過的な通信: クラスター内のアクター同士が自動的 に通信し、位置を意識する必要がない。 スケーラビリティ: アクターが分散されても、シーム レスに連携し負荷分散が可能。 高可用性: クラスター内で自動フェイルオーバーが行 われ、障害時も通信が継続。 簡潔な開発: 複雑なネットワーク処理を気にせず、ビ ジネスロジックに集中できる。 11 / 32
  9. 2. Orleans入門 ❶Akkaなどの『アクターモデル』と「仮想アクターモデル」の違い 項目 アクターモデル 仮想アクターモデル 管理 アクターの生成・破棄を明示的に管理 システムが自動でライフサイクル管理 アクターの連携

    木構造、親子関係 [種別] [キー] で判別、それぞれ独立している スケーリング 開発者がスケーリングを考慮 自動スケーリングで負荷分散が容易 利点 柔軟で制御が可能 開発がシンプルで分かりやすい Microsoft Orleansは、分散システム開発の複雑さを解消し、非専門家でも効率的でスケーラブルなアプリケーシ ョンを簡単に構築できるようにすることを目的として、Microsoft ResearchのeXtreme Computing Groupにより 2010年に開発されました​。 2015年: プロジェクトがオープンソース化され、コミュニティからの改善や貢献が活発に。 2022年:Orleans 7としてパフォーマンスの大幅な向上や開発体験の改善、GrainとStreamの識別方法の簡素化な ど、多くの新機能が導入。Orleans 8, 9 でも分散やスケーリングの効率化が開発されている 13 / 32
  10. 2. Orleans入門 OrleansとAkkaの違い /user /user/a1 /system /user/a2 / Actor Model

    - Akka Actor Actor Actor Actor Actor Actor Actor Actor Actor Actor Virtual Actor Model - Orleans /user/a2/b3 /user/a1/b2 /user/a1/b1 /user /user/a1 /system /user/a2 / /user/a2/b3 /user/a1/b2 /user/a1/b1 Node 1 Node 2 /user /user/a1 /system /user/a2 / /user/a2/b3 /user/a1/b2 /user/a1/b1 Node 3 Actor Actor Actor Actor Actor Silo 1 Silo 2 Silo 3
  11. 2. Orleans入門 Orleansの「グレイン」 Orleansでは、アクターの実装として「グレイン (Grain)」を導入しています。 常に「仮想的に存在」し、必要に応じて自動的にアクティブ化。 開発者はライフサイクル管理を意識せず、ビジネスロジックに集中可能。 グレイン同士の通信は自動的に処理され、通信チャネルを気にする必要がない。 Orleansの「サイロ」 Orleansにおける「サイロ(Silo)

    」は、Grain(仮想アクター)のホスト役を担うプロセスであり、Orleansランタ イムの実行単位です。サイロはGrainのライフサイクルを管理し、クライアントはGrainインターフェースを介して サイロ内のGrainとやり取りします。 Orleansの「クラスター」 Orleansのクラスターは、複数のサイロ(Silo)で構成される分散システムの集合体です。クラスター内の各サイ ロは、リクエストに応じてGrainを自動的にアクティベートし、不要になれば非アクティベートします。これによ り、負荷の分散や高可用性が実現されます。 15 / 32
  12. 3. Orleansでコードを書いてみた Grainの定義、使用方法 Grain定義、インターフェースを実装 public class AggregateProjectorGrain( [PersistentState("aggregate", "Default")] IPersistentState<Aggregate>

    state, SekibanDomainTypes sekibanDomainTypes, IServiceProvider serviceProvider) : Grain, IAggregateProjectorGrain { ... public async Task<Aggregate> GetStateAsync() { await state.ReadStateAsync(); var eventGrain = GrainFactory.GetGrain<IAggregateEventHandlerGrain>( GetPartitionKeysAndProjector().ToEventHandlerGrainKey()); var read = await GetStateInternalAsync(eventGrain); return read; } } 19 / 32
  13. 3. Orleansでコードを書いてみた Grainの定義、使用方法 Grainを使う apiRoute.MapGet("/branch/{branchId}", async (( [FromRoute] Guid branchId,

    [FromServices] IClusterClient clusterClient, [FromServices] DomainTypes sekibanTypes) => { var partitionKeyAndProjector = new PartitionKeysAndProjector(PartitionKeys<BranchProjector>.Existing(branchId), new BranchProjector()); var grain = clusterClient.GetGrain<IAggregateProjectorGrain>( partitionKeyAndProjector.ToProjectorGrainKey()); var state = await aggregateProjectorGrain.GetStateAsync(); return sekibanTypes.AggregateTypes.ToTypedPayload(state.ToAggregate()).UnwrapBox(); })).WithName("GetBranch").WithOpenApi(); 20 / 32
  14. 4. Orleansプロジェクトのデプロイに関して 必要なコンポーネント クラスタストレージ Redis, Cosmos, Dynamo or Azure Table

    Storage etc... ステート永続化ストレージ RDB, Redis, Cosmos or Blob Storage etc... Siloサーバー App Service, ACS, AKS or .NET動けばどこでも Streamを使う場合 Kafka, Azure Queue, Event Bus, RabbitMQ, etc... (イベントソーシングを行う場合)イベントストア 27 / 32
  15. App Service Queue Storage Blob Storage Table Storage Stream State

    Cluster Event Static Web App Blazor Azure Cosmos DB Microsoft Orleans シンプル構成 Orleans Silos 4. Orleansプロジェクトのデプ ロイに関して 中小企業向けおすすめミニマム最小構成 クラスタストレージ Azure Table Storage or Cosmos ステート永続化ストレージ Blob Storage or Cosmos Siloサーバー App Service with VNET, B1でも可能なはず、スケー ルアウトも可能 Streamを使う場合 Azure Queue Storage (イベントソーシングを行う場合)イベントストア Cosmos or Postgres 28 / 32
  16. 4. Orleansプロジェクトのデプロイに関して サーバー間通信 Microsoft Orleans では、既定で以下のポートが使用されます: サイロ間通信(サーバー同士の通信) :TCP ポート 11111

    クライアントとサイロ間通信:TCP ポート 30000 これらの値は、.ConfigureEndpoints メソッドなどでカスタマイズ可能です。 App Service + VNETの場合、サイロ間通信で11111を使用可能、外から30000には直接はアクセスで きないので、80, 443にOrleansアクセス用のAPIを定義する。 AKS, ACSだとコントロールしやすい 29 / 32