Slide 1

Slide 1 text

ネットシェア可 Microsoft Orleansで始める、 アクターモデルを使った分散 システム入門 株式会社ジェイテックジャパン 高丘 知央 2025年2月22日(土曜日) .NETラボ 勉強会 2025年2月 #dotnetlab

Slide 2

Slide 2 text

自己紹介 高丘 知央 - 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

Slide 3

Slide 3 text

本日のアジェンダ 1. アクターモデルとは 2. Orleans入門 3. Orleansでコードを書いてみた 4. Orleansプロジェクトのデプロイに関して 5. まとめ 3 / 32

Slide 4

Slide 4 text

1. アクターモデルとは 4 / 32

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

2. Orleans入門 12 / 32

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

2. Orleans入門 Orleansの「グレイン」 Orleansでは、アクターの実装として「グレイン (Grain)」を導入しています。 常に「仮想的に存在」し、必要に応じて自動的にアクティブ化。 開発者はライフサイクル管理を意識せず、ビジネスロジックに集中可能。 グレイン同士の通信は自動的に処理され、通信チャネルを気にする必要がない。 Orleansの「サイロ」 Orleansにおける「サイロ(Silo) 」は、Grain(仮想アクター)のホスト役を担うプロセスであり、Orleansランタ イムの実行単位です。サイロはGrainのライフサイクルを管理し、クライアントはGrainインターフェースを介して サイロ内のGrainとやり取りします。 Orleansの「クラスター」 Orleansのクラスターは、複数のサイロ(Silo)で構成される分散システムの集合体です。クラスター内の各サイ ロは、リクエストに応じてGrainを自動的にアクティベートし、不要になれば非アクティベートします。これによ り、負荷の分散や高可用性が実現されます。 15 / 32

Slide 16

Slide 16 text

2. Orleans入門 まとめ アクターモデルは、スケーラブルで高可用性を持つ分散アプリケーションの構築において不可欠な手 法です。Microsoft Orleansは、開発者が複雑なインフラ制御を意識することなく、簡潔で効果的にア クターモデルを実装できる強力なツールを提供しています。 16 / 32

Slide 17

Slide 17 text

3. Orleansでコードを書いてみた 17 / 32

Slide 18

Slide 18 text

3. Orleansでコードを書いてみた Grainの定義、使用方法 インターフェース public interface IAggregateProjectorGrain : IGrainWithStringKey { Task GetStateAsync(); } 18 / 32

Slide 19

Slide 19 text

3. Orleansでコードを書いてみた Grainの定義、使用方法 Grain定義、インターフェースを実装 public class AggregateProjectorGrain( [PersistentState("aggregate", "Default")] IPersistentState state, SekibanDomainTypes sekibanDomainTypes, IServiceProvider serviceProvider) : Grain, IAggregateProjectorGrain { ... public async Task GetStateAsync() { await state.ReadStateAsync(); var eventGrain = GrainFactory.GetGrain( GetPartitionKeysAndProjector().ToEventHandlerGrainKey()); var read = await GetStateInternalAsync(eventGrain); return read; } } 19 / 32

Slide 20

Slide 20 text

3. Orleansでコードを書いてみた Grainの定義、使用方法 Grainを使う apiRoute.MapGet("/branch/{branchId}", async (( [FromRoute] Guid branchId, [FromServices] IClusterClient clusterClient, [FromServices] DomainTypes sekibanTypes) => { var partitionKeyAndProjector = new PartitionKeysAndProjector(PartitionKeys.Existing(branchId), new BranchProjector()); var grain = clusterClient.GetGrain( partitionKeyAndProjector.ToProjectorGrainKey()); var state = await aggregateProjectorGrain.GetStateAsync(); return sekibanTypes.AggregateTypes.ToTypedPayload(state.ToAggregate()).UnwrapBox(); })).WithName("GetBranch").WithOpenApi(); 20 / 32

Slide 21

Slide 21 text

3. Orleansでコードを書いてみた シリアライザー デフォルトでは、サイロ間通信に効率化したシリアライザーを使用していて、デフォ ルトでは、そのシリアライザー非対応のデータをGrainのパラメーター、戻り値に使う と実行時エラーになる! [GenerateSerializer] 属性をデータにつける 外部ライブラリで作ったデータには属性がつけられないので、サロゲート方、変換ク ラスを定義すれば使うことができ、勝手に変換して流してくれる 21 / 32

Slide 22

Slide 22 text

3. Orleansでコードを書いてみた 単体テスト テスト用のクラスターをUnitTest内で起動、使用できる シリアライズ、デシリアライズができないとだめなのをテストできる 起動、終了に14秒かかる。デフォルトで2サイロでエミュレーター シリアライズ、デシリアライズだけはできるようにした(TODO:Zennブログを書く) 22 / 32

Slide 23

Slide 23 text

3. Orleansでコードを書いてみた イベントソーシングライブラリ、Sekibanの移植 これまでのSekibanは1サーバーではスレッド管理をして、同じデータを同時に使わな いようなスレッド管理を行なっていた スケールアウト時に不整合なデータが出来うる状況だったので、アクターモデルに注 目して、Orleans版を1月に1から作成開始。 イベントソーシングの機能としてもこれまでのSekibanをよりシンプルに拡張性の高い ものに改善 Clineの助けで開発速度を上げてどんどん機能追加 先週、preview版をリリース 23 / 32

Slide 24

Slide 24 text

3. Orleansでコードを書いてみた 簡単に使用できるようにリリース 今までやっていなかった、ソリューションテンプレートを作るのをやってみた。MSド キュメントにもあまり体系的に書いていなくて、大変でしたが、なんとか出来まし た。 (TODO:Zennブログを書く) dotnet new install OrleansSekiban.Template dotnet new sekiban-orleans -n YourProjectName これで、Orleans、Sekiban、Aspireで開発を開始できる構成をローカルに構築できる!! 24 / 32

Slide 25

Slide 25 text

3. Orleansでコードを書いてみた デモ 25 / 32

Slide 26

Slide 26 text

4. Orleansプロジェクトのデプロイに関して 26 / 32

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

5. まとめ 30 / 32

Slide 31

Slide 31 text

5. まとめ 分散システムを適切に設計するのは難し い Microsoft Orleansはリソースを効率的に 用いつつ、シンプルに分散システムを作 ることができる、仮想アクターモデル。 SekibanのOrleans対応もPreview版で公 開中、今までと同じような使い勝手で、 分散システムのパワーを、スモールスタ ートから始められます。 31 / 32

Slide 32

Slide 32 text

ネットシェア可 Thank you! 株式会社ジェイテックジャパン https://www.jtechs.com/japan/ Sekiban - イベントソーシング・CQRSフレームワーク https://github.com/j-tech-japan/sekiban Zenn - ジェイテックジャパンブログ https://zenn.dev/p/jtechjapan_pub