【勉強会】第3回Reactive System Meetup in 西新宿
2016-09-29 ReactiveSystemMeetup
これに行ってきました。
reactive-shinjuku.connpass.com
リアクティブDDDについて
- ChatWork 加藤潤一さん
リアクティブDDD
- 今日は、大規模サービス向け、ハイコンテキストな話になる
- リアクティブDDD→VaughnVernon氏(実践ドメイン駆動設計の著者)
- DDDだと、レイヤ構造深くなる、コールスタック増える、オーバーヘッド大きい
- そこでリアクティブ
- EffectiveAkka(オライリー)を参照
- Domain-driven
- Actor/BDをデザインする
- message passing、現実に起きたイベントをメッセージとして扱う
- WorkDistribution
- (特に説明なし)
- Domain-driven
リアクティブシステムとAkka
背景
- コンテキストの変化、どう対応する?
リアクティブ宣言
- 即応性(Responsive)、可能な限り速やかに応答
- 耐障害性(Resilient)、障害時も即応性を保つ
- 弾力性(Elastic)、スケールアウトしても即応性を保つ
- メッセージ駆動(MessageDriven)、これが大前提
Responsive
- PubSubで、関心のある変更の集合を伝搬することで実現
- Fire&Forget
- 送ったら忘れる
- 送られた方も処理したら忘れる
- 戻ってきたらまた反応する
- ソフトウェアの災いといえば、
- 誤差・誤り、正しい値との差異
- 欠陥、意図しない振る舞い
- 障害、能力の縮退または喪失←Supervisorで対処
- 故障、機能遂行する能力がなくなる
Resilient
- 障害を起こさないこと、ではない。障害から回復する能力を持つこと
- つまり、耐障害性というか、自己回復力のこと
- Supervisorが監督、例外がエスカされたら、Actorを停止/再起動/継続
- Supervisorはチェインできる
- CircuitBrakerの考え方もできる、急激な負荷を防ぐため
Elastic
- 要求に応じたスケーリング戦略、オフピーク時はリソース節約、とか
- 垂直にも水平にもスケーリングできること
- メッセージ駆動によってスケールする
MessageDriven
- メッセージを受信して初めて、利用可能なスレッドを使って反応する。
- メッセージに反応しないコンポーネントは“貴重な”CPU資源を消費しない
- 反応するかどうかは、受け側が決める、投げ側じゃない
- そうすると、インターフェイスと時間の概念から分離される
- akka-remoteだと空間からも分離
- 一度に決まった単位のメッセージを処理
- ポーリング・ブロッキングをしない=頻繁なCPU消費をしない
- 必要に応じた反応、CPUはすぐ解放、によって低レイテンシを実現
- 必要に応じてback pressureによるフロー制御も
Akka
- Why Akka?
- Akkaのプロダクト
- いろいろ(難しいからメモ省略)
DDDのエッセンス
ドメインモデルとは?
- 当面の問題を解決する上で関連する側面を抽象化、それ以外無視
- というスタンスの、現実に対する1つの解釈
- 昔の世界地図の例、自国だけ超詳細。
ドメイン駆動設計の意義
- これまで
- モデルは、データの入れ物であり、
- それを操作して手続きを実現するサービスを実装
- ドメイン駆動では
- モデル自身が意味を持つ
- この責務をになうオブジェクト群を強調動作させる
- そもそもMVCのMとは、
- 単なる「データ」じゃない、概念を示すものだ
DDDでどう変わるのか?
- BC(=境界付けられたコンテキスト)で、システムを適切に分割
- 顧客と開発者で共通の言語体系、ユビキタス言語を確立
- 概念の重複がなくなる→ロジックの重複なくなる
BC?
- 顔と花瓶の絵の例、見方(ベース)を変えることで同じ絵が違う意味。
- 文脈が抽象化されたものは記号
- 文脈が共有されていないと意味が解釈できない
- その文脈こそ、BC
- たとえば「アカウント」と言っても、その環境によって意味が違う
※ここから急激に難しい、キーワードだけ。
- ドメイン層の隔離
- レイヤー化アーキテクチャ
- レイヤーごとに責務を決める、他のレイヤに侵食されない
- 集約
- 集約を意識しないと、モデルが複雑になる
- 変更時の影響が読めない、一貫性が保てない
- 不変条件をつける、制約をつけることで、複雑化を防ぐ
- 集約の大きさ間違えると、集約内でのロックが増えて干渉が問題になる
- ドメインモデルは考え方を投影したもの、テーブルを投影したものではない
- ActiveRecordは集約ではない
AkkaとDDD
※ 難しい、わかるようになってから。
Lagomで学ぶReactiveMicroservicesArchitecture
- TIS 根来和輝さん
www.slideshare.net
目的
- LagomのデザインをベースにMicroservicesの設計のヒントを得る
Lagomとは
- MSA向けフレームワーク
- コンセプトは「ReactiveMSA」
MSAの利点
- チームの独立
- サービスの特性に合った異なる技術の採用
- デプロイの影響範囲を小さく、リリースが素早く
- 障害を一部にとどめて、全体の可用性を高く
MSAの注意点
LagomがReactiveを達成するための道具
非同期・ノンブロッキング
- メリット、相手が応答しない時のスレッド占有を避けられる
- デメリット、学習コストと、スレッドセーフの考慮
CompletionStage<Response> a = serviceA.request(); CompletionStage<Response> b = serviceB.request(); CompletionStage<Integer> responseSize = a.thenCombine( b, (resA, resB) -> resA.size + resB.size ); responseSize.thenAccept(size -> doSomething(size));
Sharding
- シャーディングとは、負荷分散。単一障害点を無くし高可用。
- Entityを分散させて負荷分散
- What is Entity?
- サービスの現在の状態を分散して持つ
- 状態をオンメモリで管理してDBにバックアップ
- 状態をDBに問い合わせる必要がなく、レイテンシを抑えられる
- 位置透過性がありノード間を移動できる、ノードに障害があっても復旧できる
EventSourcing+CQRS
- 分散型の永続化
- EventSourcing
- システムで起きたイベントを永続化(=イベントをストアにINSERT)
- Entityの状態が失われたら、イベントを再生して状態を復元
- イベントは不変、とすることで、ロック不要にする
- デメリット:データの集計にコストがかかる→CQRSで解決
- CQRS
- Command and Query Responsibility Segregation
- コマンドクエリ責務分離
- Command(書込)とQuery(読込)を分離する
- メリット:分離することで異なる技術が使える、別々にスケールできる
- デメリット:完全な一貫性を保てない
- 一時的に一貫性が取れなくてもいいようなビジネス設計すればいい
CircuitBraker
- 外部サービスの障害時に、即座にエラーを返す仕組み
- リトライによるNW帯域のムダが減る
- レイテンシを低く抑える
- 障害の連鎖を抑える
- Close/Open/HalfOpenの状態で制御する
- もともと電子工学の言葉なので、解釈が特殊
- Close=回路が閉じてる=通信できる
- Open=回路が開いている=通信できない
- FailureCountを持ってて、閾値に達するとOpenに
- 一定時間経つと、HalfOpenになって、一時的に試す、うまくいけばCloseに
- メリット:障害の連鎖を食い止める
- Lagom以外だと、NetflixのHystrixなど
まとめ
------------------- | 高可用 | 低レイテンシ | スケーラビリティ |
---|---|---|---|
非同期・NonBlocking | o | o | - |
Sharding | o | - | o |
EventSourcing+CQRS | o | o | o |
CircuitBraker | o | o | - |
- まだ導入の障壁は高い
- が、Reactiveの設計の参考にはなる