Slide 1

Slide 1 text

ChatWorkのリアクティブシステム導入事 例から学ぶActor設計プラクティス Junichi Kato (@j5ik2o)

Slide 2

Slide 2 text

自己紹介 ● Scala歴 6年 ● サーバサイド開発・設計担当 ● 最近やってること ○ TISさんやセプテーニさんでDDD基礎講座(有償) ○ OAuth2/OpenID Connectのプロバイダ実装

Slide 3

Slide 3 text

アジェンダ ● Falconで採用したアクターの設計がテーマ ○ Falconのドメインモデル ○ FYI: CQRS+ESアーキテクチャ ○ Falcon の アーキテクチャ概要 ○ Falcon の レイヤ化アーキテクチャ ■ API(Write or Read) ■ SparrowForwarder ○ FYI: Actorの特徴 ○ FYI: Actorヒエラルキーの考え方 ○ SparrowForwarderのActorヒエラルキー ○ FYI: レジリエントを作り込む方法 ○ BackOffSupervisorとその拡張

Slide 4

Slide 4 text

Falconのドメインモデル ● 集中と選択でメッセージとそれにまつわるドメインイベントのみ ● すでに成熟しており、議論が紛糾することがなかったので、Actor を使ったモデル駆動設計の議論が主戦場だった。 Message MessageCreated MessageUpdated

Slide 5

Slide 5 text

FYI: CQRS+ESアーキテクチャ

Slide 6

Slide 6 text

Falconのアーキテクチャ概要

Slide 7

Slide 7 text

Falconのレイヤ化アーキテクチャ

Slide 8

Slide 8 text

API(Write/Read)のアプリケーションアーキテクチャ DAS = Data Access Stream DIPを適用したレイヤ化アーキテクチャ= ヘキサゴナルアーキテクチャ

Slide 9

Slide 9 text

SparrowForwarderのアプリケーションアーキテクチャ

Slide 10

Slide 10 text

FYI:Actorの特徴

Slide 11

Slide 11 text

Actorの特徴(1/2) ● メッセージを受信して初めて、利用可能なスレッドを使って反応する。メッセージに反応しないコンポーネントは 貴重なCPU資源を消費しない。 ● メッセージに反応するかどうかはコンポーネントが選択でき、送信側と受信側のコンポーネントは、インターフェ イスと時間から分離される。 ● アクターは一度に決まった単位のメッセージを処理する。 CPUを頻繁に消費するポーリングとブロッキングを採 用せず、高スループットにフォーカスするために CPUを解放する。必要に応じた反応が低レイテンシーを導く。

Slide 12

Slide 12 text

Actorの特徴(2/2) ● DispatcherはMailboxにImmutableなメッセージを追加する (Shard Nothing)。ActorはMailboxを経由してメッ セージを順番に取得する 。開発者はDispatcherが利用するスレッドを意識しない。決まった単位のメッセージ を処理している際中は、別のメッセージを処理しないので、非同期境界を意識していれば、同一アクター内で はシングルスレッドのように見える。 ● Actor数分のスレッド数が必要になるわけではない。 ライトウェイト。2.7百万Actorは1GB程度。スレッドモデル では1GB=4096スレッド程度と考えると大きな差がある。 ● DispatcherやMailboxは必要に応じて適切な種類と設定を選ぶことでチューニングが可能。

Slide 13

Slide 13 text

FYI:Actorヒエラルキーの考え方

Slide 14

Slide 14 text

ActorSystemのヒエラルキー ● 最初にActorSystemが作られる。ActorSystemを使ってSupervisorを作る。 Supervisorが 子アクターを作ることでヒエラルキーを構築する。 ● 実際には、アプリケーション用のアクターはuser guardian配下に所属する。

Slide 15

Slide 15 text

アクターヒエラルキーの目的 ● スーパバイザのライフタイムは、子アクターが存 在する間と同じ。親によって作られた子アクター は、スーパバイザの監督下に置かれる。スーパ バイザの責任はすべての子アクターが終了した 時に終わる。 ● クラッシュする可能性が高いアクターは、可能な 限りヒエラルキーの下層に配置すべき。下層で 起きた障害は、上位までのヒエラルキーが管理 ・エスカレーションが可能。最上位が障害を起こ した場合は、最上位のアクターの再起動もしく はアクターシステムのシャットダウンが必要にな る。

Slide 16

Slide 16 text

アクターヒエラルキーの実装パターン1 ● 利点は、各アクターが相互に直接通信するこ と。スーパバイザは監督業務とインスタンス作 成のみ。 ● 欠点は、再起動しか使えないことと、メッセージ がデッドレターに送られて失われてしまうこと。 親のスーパーバイザはメッセージフローから分 離してしまう。

Slide 17

Slide 17 text

アクターヒエラルキーの実装パターン2 ● スーパバイザは単なる生成や監督ではなく、間 接参照として、すべてのメッセージを単に透過 的にフォワードする。スーパバイザは子を終了 したり、他のアクターとは無関係に新しいもの を生み出したりできる。 ● 先の例と比べてメッセージフローのギャップが ない。

Slide 18

Slide 18 text

 SparrowForwarder内部設計 ココの話

Slide 19

Slide 19 text

SparrowForwarderのActorヒエラルキー ● このモデルは、SQSなどでも利用できる。 ● Exponential BackOff機能を備えた Supervisorを経由してメッセージを透過的 に扱う。 ● 下位層のActorはいつでもクラッシュしても よい。上位はクラッシュしてはならない。 ● KafkaComsumerActorがエラーを起こした 場合はSupervisorが指数関数的な BackOffを掛けてリトライを自動的に行う。 ● APIExecutorも同様に振る舞うが、 Kafka へのポーリング間隔が延びると Consumer に異常があったと見なされセッションタイム アウトが起こり、リバランスが起こってしま う。この場合はAPIExecutor側でBackOff せずに全体のフローを最初からやり直す 方がよい。現在はAPIExecutorSupervisor は利用していない。

Slide 20

Slide 20 text

FYI:レジリエントを作り込む方法

Slide 21

Slide 21 text

Supervisorを実装する

Slide 22

Slide 22 text

子アクターを実装する

Slide 23

Slide 23 text

Supervisor経由で実行する

Slide 24

Slide 24 text

Supervisor経由での実行結果

Slide 25

Slide 25 text

akkaのBackOff Supervisor ● データ送信処理が失敗して再送信するときに、失敗回数が増えるに連れて再送信す るまでの待ち時間を指数関数的に増やす仕組みを exponential backoff という。 ● SupervisorにExponential Backoffを付加するakka標準API ○ 子アクターが停止もしくは再起動した時にBackoffする ○ Supervisorにメッセージを送ると子アクターに転送される ○ ただし、子アクターが開始・停止のイベントがとれない

Slide 26

Slide 26 text

BackOffSupervisorの拡張(1/3) ● akkaからフォークした拡張(本家でも改善中なのでご参考程度に) → https://git.io/vyotj ● 子アクターの開始と停止をフックできる ● 以下はハンドラーを指定する方法

Slide 27

Slide 27 text

BackOff Supervisorの拡張(2/3) ● ハンドラーの代わりにアクターを指定する方法

Slide 28

Slide 28 text

BackOff Supervisorの拡張(3/3) ● Backoff機能付きSupervisor を自前で作る方法 ● Supervisor自身がBackoff Retryが可能

Slide 29

Slide 29 text

まとめ ● ActorRefは疎結合になるので、依存の方向性に気をつけながら、レイ ヤー化アーキテクチャを作る(Propsファクトリとメッセージの依存を間 違えなければまず問題が起きることはない)。静的型配線したいなら、 akka-streamを検討する価値はある。 ● Actorの自己回復力(BackOffSupervisor)をいかした設計は、運用負 荷が下がる。これがActorのすべてと言ってもいいすぎではない。 ● でもActorの設計は難しい。Actorヒエラルキーなしはあまり意味がな い。歯を食いしばってActorのコンセプトを学びましょう…。

Slide 30

Slide 30 text

ご静聴ありがとうございました。