98
Developers Summit 201618-E-5#devsumiE リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題~ 岡本 雄太 (@okapies) 2016/02/18 Greg Walters, “Crazy Architecutre (UK)" - CC BY 2.0

リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Embed Size (px)

Citation preview

Page 1: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Developers Summit 2016【18-E-5】#devsumiE

リアクティブ・アーキテクチャ~大規模サービスにおける必要性と課題~岡本 雄太 (@okapies)

2016/02/18

Greg Walters, “Crazy Architecutre (UK)" - CC BY 2.0

Page 2: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

自己紹介

• 岡本 雄太(@okapies)

• 製造業で働くソフト屋さん

• Scala と Scala OSSs 愛好家

• 最近の仕事はインフラエンジニアっぽい感じ

• ScalaMatsuri 2016 準備委員会 運営委員

Page 3: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

公開してる OSS

• finagle-kafka (https://github.com/okapies/finagle-kafka)

• sircuit (https://github.com/okapies/sircuit)

• rx-process (https://github.com/okapies/rx-process)

Page 4: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

書き物

• 翻訳:

• リアクティブ宣言 v2.0

• Effective Scala 日本語版

• 命令型のコールバック、関数型のプロミス

• ブログ記事 (http://okapies.hateblo.jp/):

• 非同期ストリーム処理の標準化を目指す "Reactive Streams" とは

• 関数型プログラマのための Rx 入門

• マイクロサービスが Scala を選ぶ3つの理由

Page 5: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

発表してきました

Reactive Programmingの話題が中心

http://www.slideshare.net/okapies/scalamatsuri-58141520

Page 6: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

アジェンダ

• なぜ分散システムか? • マイクロサービス

• リアクティブシステムと Reactive Streams

• 分散システムのつらい話と対策 • プログラミングモデル • 結果整合性 • 運用の複雑さ

Page 7: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

単体マシン !

!

分散システム

Page 8: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

大規模分散システムの例

http://www.slideshare.net/adriancockcroft/goto-berlin/76

Page 9: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

なぜ分散システムか?

• 開発組織のスケーラビリティ

• 性能のスケーラビリティ

• 耐障害性

Page 10: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

なぜ分散システムか?

• 開発組織のスケーラビリティ

• 性能のスケーラビリティ

• 耐障害性リアクティブシステム

マイクロサービス

Page 11: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

概念に名前を与える

• 優れたソフトウェアアーキテクチャのエッセンスを抽出して名前を与えたもの

• マイクロサービス

• リアクティブシステム

Page 12: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://martinfowler.com/microservices/

Page 13: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスアーキテクチャ

• 一つのアプリケーションを小さなサービス群の組み合わせとして構築する手法

http://martinfowler.com/articles/microservices.html

Page 14: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

MSA を採用している企業

• Amazon

• Twitter

• Netflix

• PayPal

• LinkedIn

• Tumblr

• SoundCloud

• LINE

• ドワンゴ

• etc…

Page 15: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://anond.hatelabo.jp/20111018190933

Amazon の最初期からの事例

Page 16: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスの特性

1. サービスによるコンポーネント化 2. ビジネス遂行能力に基づく組織化 3. プロジェクトではなくプロダクト 4. 賢いエンドポイントと愚かなパイプ 5. 非中央集権的なガバナンス 6. 非中央集権的なデータ管理 7. インフラの自動化 8. 障害を考慮した設計 9. 進化的設計

http://martinfowler.com/microservices/

Page 17: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスの特性

2. ビジネス遂行能力に基づく組織化 3. プロジェクトではなくプロダクト 5. 非中央集権的なガバナンス 9. 進化的設計 1. サービスによるコンポーネント化 4. 賢いエンドポイントと愚かなパイプ 6. 非中央集権的なデータ管理 7. インフラの自動化 8. 障害を考慮した設計

組織の特性 (目的)

技術の特性 (手段)

http://martinfowler.com/microservices/

Page 18: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスの目的

• 開発組織のスケーラビリティの確保

• ビジネス遂行能力を核とした非中央集権的な機能横断型チームとして組織化する(c.f. Conway’s Law)

http://martinfowler.com/articles/microservices.html

Page 19: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスの方法論

• サービス間にビジネス遂行能力やドメインのライフサイクルに従ってモジュール境界を持つ

• サービス間は REST や単純な MQ で繋ぐ。トランザクションはなるべく使わない

• サービス同士の依存関係を減らして独立に配備できるようにする

Page 20: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスの利点

• 強いモジュール境界:マイクロサービスはモジュール構造を強化する。このことは、チームの規模が大きくなるにつれて特に重要になる

• 独立した配備:単純なサービスは配備が容易であり、また自律的なので、個々に不具合が起きてもシステム障害を引き起こしにくい

• 技術的多様性:複数の言語、開発フレームワーク、データストレージ技術を組み合わせることができる

http://martinfowler.com/articles/microservice-trade-offs.html

Page 21: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

なぜ分散システムか?

• 開発組織のスケーラビリティ

• 性能のスケーラビリティ

• 耐障害性リアクティブシステム

マイクロサービス

Page 22: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://www.reactivemanifesto.org/ja

Page 23: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Reactive Manifesto

• Reactive Systems への支持を呼びかける文書

• 社(Scala/Akka 開発元)が主導

• 他に Dave Farley (”継続的デリバリー”の著者)

や Martin Thompson (元 LMAX CTO) など

• アクターモデル、特に Erlang/OTP や Akka のプラクティスを念頭に置いている

賛同者数13,000 人超え

Page 24: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

様々なリアクティブ

Reactive Systems

Reactive Programming

Reactive Streams

プログラミングモデル:

ランタイム:

システムアーキテクチャ:

Page 25: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

様々なリアクティブ

Reactive Systems

Reactive Programming

Reactive Streams

プログラミングモデル

ランタイム

システムアーキテクチャ:

Page 26: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

アプリケーションの要求の変化

数年前 現在

Configuration 数十のサーバ 数千のマルチコアプロセッサ

Responsetime 秒単位 ミリ秒単位

Availability数時間の

オフラインメンテナンス稼働率 100%

Data size ギガバイト単位 ペタバイト単位

Page 27: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

システムの構築方法の変化

“大規模システムを構築する組織はこの変化に対処する設計原則を

すでに発見している”

“そのような特徴を備えるシステムをReactive Systems と呼ぼう”

http://www.reactivemanifesto.org/ja

Page 28: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

リアクティブシステムの性質

http://www.slideshare.net/Typesafe_Inc/going-reactive-2016-data-preview/6

即応性

弾力性 レジリエンス

メッセージ駆動

価値

手段

形態

Page 29: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

価値

手段

形態

http://www.slideshare.net/Typesafe_Inc/going-reactive-2016-data-preview/6

即応性

弾力性 レジリエンス

メッセージ駆動

リアクティブシステムの性質実現したい価値:

ユーザへ迅速かつ一貫した速度でサービスを提供する

障害時にも即応性を維持する

非同期メッセージパッシングが全ての基盤である

負荷が変動しても即応性を維持する

Page 30: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

 私が仕事で関わった、大きなシステムのアーキテクチャには類似点があった。 そうしたシステムでは、問題領域における明確な Bounded Context を実装したサービスが疎結合で結びついており、互いの通信は非同期メッセージのみで行う。 これらは、RDB の上に構築された箱出しの標準的な三層アーキテクチャのシステムのやり方とは似ても似つかない。

“The Reactive Manifesto | Dave Farley's Weblog” より妙訳

Page 31: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

従来の三層アーキテクチャ

プレゼンテーション

ビジネスロジック

RDB

同期呼出

同期呼出

一枚岩のアプリケーション

Page 32: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

リアクティブシステムの例

プレゼンテーション

ビジネスロジック

RDB

同期呼出

同期呼出

RDB

非同期

非同期

非同期

KVS

非同期

Page 33: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

STORAGE & RETRIEVAL

LOGICPRESENTATIONROUTING

Redis

Memcache

Flock

T-Bird

MySQLTweet

User

Timeline

Social Graph

DMs

API

Web

Monorail

TFE

HTTP Thrift “Stuff”http://monkey.org/~marius/scala2015.pdf

Twitter のマイクロサービス構造

Page 34: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

MSA ⊂ リアクティブシステム

• マイクロサービスは、リアクティブシステムの実例の一つと考えることができる

• マイクロサービスは、リアクティブシステムの4つの性質を備えているとより良い、と言える

Page 35: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

リアクティブなコンポーネント• 他のコンポーネントから非同期メッセージが到着したときだけ反応する(リアクティブ=受け身)

in out

Page 36: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

自己完結性 (self-containment)

• 各コンポーネントの内部状態は互いに隔離され、かつ独立したライフサイクルを持つ

• 障害を外部へ波及させることなく封じ込める

? ?in out

× ×外部の状態を暗黙に参照/更新しない

Page 37: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

• コンポーネント同士が非同期メッセージパッシングでデータをやり取りする

• 共有メモリは使わない(競合の原因)

メッセージ駆動 (message-driven)

コンポーネント

コンポーネント

メッセージバッファ

Page 38: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

• メッセージを明示的にやり取りする

• 負荷管理、弾力性、フロー制御が容易に

• プロトコルは非同期なら何でもよい(REST でもメッセージキュー経由でも)

コンポーネント

コンポーネント

メッセージ駆動 (message-driven)

Page 39: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

• コンポーネント間は非同期(バイナリ)境界で区切られ、互いに別のスレッド、プロセス、ノード、データセンターに配置できる • 疎結合、時間的・空間的隔離、位置透過性

コンポーネント

コンポーネント

メッセージ駆動 (message-driven)

Page 40: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

補足: 位置透過性

• 全ては分散コンピューティングである

• メッセージパッシングにおいて、単体ノード(マルチコア)と複数ノードにコンセプトの違いはない

• コンポーネントが任意の場所に配備できるなら、ローカル通信は最適化に過ぎない

• メッセージパッシングは RPC ではない

• ネットワーク関連の障害を明示的に扱う

Page 41: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

レジリエンス (resilience)

• 部分的に障害が発生してもシステム全体に波及せず(自律的に)回復する、という特性

• 耐障害性よりも広い概念

• 「物体が元の形へ戻ったり、困難から素早く立ち直る能力」のこと

• 〈抵抗力+復元力〉みたいなニュアンス

Page 42: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

レジリエンス (resilience)

• エラーを非同期境界で封じ込め、他のコンポーネントに波及させず隔離する

• (予期可能なエラーと障害を区別する)

例外

Page 43: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

レジリエンス (resilience)

• レプリケーションによって高可用性や冗長性を確保(c.f. 非同期境界、位置透過性)

ワークロードを複製

Page 44: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

レジリエンス (resilience)

• 障害時には、処理中のタスクや回復処理を他のコンポーネントに委譲する (Let it crash)

• コーヒー自販機の喩え(豆が切れたら客に〈コーヒー豆エラー〉を返すのではなくサービスマンを呼んでほしい)

Super-visor

タスク

エラー通知

Page 45: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

補足: Let it crash

• 故障したコンポーネントはその場でクラッシュさせて、監督者 (Supervisor) に回復処理を任せる

• 「予期しない障害は必ず起きるし、人為的には防げない」という実世界のシステムに対する観察

• Erlang 発祥の概念で、極めて高い信頼性が求められるシステム(電話交換機など)で可用性を確保するのが目的

Page 46: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://www.slideshare.net/jboner/without-resilience-nothing-else-matters-56053062

Page 47: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

弾力性 (elasticity)

• 弾力性 = Scale Out + Scale In

• シャーディングやレプリケーションによってコンポーネント間で入力を分散し、スケーラビリティを確保(c.f. 位置透過性)

• 同期の競合やボトルネックの原因になるので、メモリの共有はしない(メッセージ駆動)

Page 48: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスとの比較

• マイクロサービス ⊂ リアクティブコンポーネント

• 強固なモジュール境界: 同期呼出ではなく非同期呼出に

• 独立した配備: レジリエントなシステムは〈障害を考慮した設計〉と〈進化的設計〉を満たす

• 技術的多様性: 非同期処理やメッセージ駆動ミドルウェアを重視(HTTP 等でも実現は可能)

• メッセージ送信はバッチ化(RPC 粒度の課題を解決)

Page 49: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

どうやって実現するか?

どのようにこの属性を実現するのかについて、マニュフェストの中で規範的に言及するのは避けたいと思いました。 — Martin Thompson

• マニフェストは、リアクティブシステムの性質や品質についてのみ記述しており、具体的な実現方法には触れていない

http://www.infoq.com/jp/news/2014/11/thompson-reactive-manifesto-2

Page 50: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

国内事例

• LINE のメッセージング基盤は、Akka Actor を活用したリアクティブな設計になっている

• 「Akka ActorとAMQPでLINEのメッセージングパイプラインをリプレースした話」

• TIS が Akka を使ったデモを GitHub で公開しているhttps://github.com/tech-sketch/reactive-solar-farm-monitor/

Page 51: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Reactive Solar Farm Monitor デモ

https://github.com/tech-sketch/reactive-solar-farm-monitor/blob/master/README.ja.md

Page 52: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Reactive Solar Farm Monitor デモ

http://www.slideshare.net/yugolf/typesafe-reactive-platformreactive-system/35

Page 53: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

リアクティブシステムの課題

• リアクティブシステムは大量データを扱う非同期データストリーム

• 同期型とは異なり、システムに流れ込むデータ流量を制御する仕組み(フロー制御)が必要

• フロー制御に失敗すると、データフローが決壊してシステム全体のクラッシュに繋がる

Page 54: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

データフローの決壊

• Publisher は Subscriber へメッセージを送る

Publisher Subscriber…

3 msgs/sec 3 msgs/sec

メッセージバッファ

処理能力送信能力

=

Page 55: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

• Subscriber が速いときは暇になる→ 計算機資源を有効活用できない

Publisher Subscriber

データフローの決壊

< 3 msgs/sec

来ない…あんま送ると悪いかな…

1 msg/sec

Page 56: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

• Publisher が速すぎるとバッファが溢れて死ぬ

Publisher Subscriber

データフローの決壊

> 3 msgs/sec

100 msgs/sec

やめて!俺にまかせろー!

Page 57: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

https://www.flickr.com/photos/chiaralily/4978843623/

Page 58: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Reactive Streams

• Back-Pressure でフロー制御を行う

• 非同期ストリーム処理ランタイムの

相互運用性を確保するための標準規格

Page 59: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Back-Pressure

• Publisher はリクエストされた分だけメッセージを送る → 安全

100 msgs/sec

[Request(3)]

Publisher Subscriber

3 msgs/sec

次、3 個くださいあいよー

Page 60: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Back-Pressure

• Back-pressure は伝播する

• C が遅くなったら B, A もスローダウンする

B C…

今はいいです

A…

今はいいですあいよー

Page 61: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

経緯

• Reactive Manifesto の発表 (2013年9月)

• Typesafe の主導で、非同期ストリーム技術を開発するベンダー各社の間で、フロー制御の技術課題の解決策を話し合うコミュニティが発足

• GitHub に reactive-streams グループを作成。正式に共同で仕様策定を始める (2014年初頭)

Page 62: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

主な参加者

• (Akka)

• (RxJava)

• (Reactor)

• (Vert.x)

Scala 言語の開発元

米国最大手の動画配信サービス

Spring Frameworkの開発元

Page 63: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

主な参加者

• Doug Lea

• JSR 166 (java.util.concurrent)の Specification Lead

• 「Java 並行処理プログラミング」の著者の一人

• JDK での標準化は氏の主導で進められている

http://www.amazon.co.jp/dp/4797337206/

Page 64: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Reactive Streams in JDK 9

Page 65: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

SPI のインタフェース

public interface Publisher<T> { public void subscribe(Subscriber<? super T> s);}public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete();}public interface Subscription { public void request(long n); public void cancel();}

すべて戻り値なし=非同期

語彙は RxJava がベース

Page 66: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

仕様書とTCK

• ランタイム間の相互接続性を保証する

Page 67: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

準拠実装

• Akka Streams (Typesafe)

• Ratpack

• Reactor (Spring)

• RxJava (Netflix)

• Vert.x 3.0 (Red Hat)

Page 68: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

DB アクセスライブラリの準拠実装

• Slick 3.0 a.k.a “Reactive Slick” (JDBC)

• ReactiveMongo

• Reactive Rabbit (AMQP)

• Reactive Kafka

• etc…

Page 69: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

すべてがリアクティブになる

• リアクティブシステムを、Reactive Streams 準拠のコンポーネントを使って入口から出口まで組み上げることができる

AMQP RxJava Akka Vert.x RDB

例:

Page 70: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

余談

Page 71: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

なぜ分散システムか?

• 開発組織のスケーラビリティ

• 性能のスケーラビリティ

• 耐障害性リアクティブシステム

マイクロサービス

…本当に分散したいんだっけ?

Page 72: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

分散オブジェクト設計の法則

• 第一法則: ??????????

by Martin Fowlerhttp://martinfowler.com/bliki/FirstLaw.html

Page 73: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

分散オブジェクト設計の法則

• 第一法則: オブジェクトを分散させるな

by Martin Fowlerhttp://martinfowler.com/bliki/FirstLaw.html

分散化にはデメリットがたくさんある

Page 74: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

「分散コンピューティングの落とし穴」

1. ネットワークは信頼できる。 2. レイテンシはゼロである。 3. 帯域幅は無限である。 4. ネットワークはセキュアである。 5. ネットワーク構成は変化せず一定である。 6. 管理者は1人である。 7. トランスポートコストはゼロである。 8. ネットワークは均質である。

Page 75: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービスのコスト

• 分散:分散システムはプログラムが難しい。リモート呼出は遅いし、失敗のリスクがある

• 結果整合性:分散システムで強い一貫性を維持するのは非常に困難なので、結果整合性を管理しなければならない

• 運用の複雑さ:定期的に再配備する大量のサービスを管理する成熟した運用チームが必要

http://martinfowler.com/articles/microservice-trade-offs.html

Page 76: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

分散プログラミングのつらみ

• RPC の逐次処理や並列処理

• ネットワークの障害・遅延・分断

• リモートホストの障害

• スロットリング(連鎖障害の防止)

• サービスディスカバリ

• モニタリング、リクエストの分散トレース

Page 77: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

マイクロサービス向けフレームワーク

• 大規模なマイクロサービスを運用している企業のうち、いくつかは自社の基盤ソフトウェアを OSS 化している

• Netflix OSS

• Twitter Finagle, Zipkin, etc…

Page 78: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Finagle

Twitter の Finagle は、(Tumblr が) Scala を採用した抗し難い要因だ。Finagle は、分散トレース、サービスディスカバリやサービス登録といった分散の課題のほとんどに対処してくれる。

• Finagle は、Tumblr や SoundCloud などが自社のマイクロサービスへの Scala 導入に踏み切る大きな要因になっている

• 解説記事書いてます: 「マイクロサービスが Scala を選ぶ3つの理由」

Tumblr Architecture - 15 Billion Page Views a Month and Harder to Scale than Twitter

Page 79: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

分散と関数型プログラミング

• 「あれでしょ?ムーアの法則が破れてフリーランチは終わった、これからはマルチコアで並列処理だ関数型だってやつ」

• 分散処理の文脈における関数型の本質は、非同期処理や分散環境での横断的関心事からビジネスロジックを分離して、容易にモジュール化できること

Page 80: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://monkey.org/~marius/funsrv.pdf

Your Server as a Function

Future 型と Service, Filter という関数の組み合わせでサーバを記述する

Page 81: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Finagle による分散処理

val userAndTweets = Future.join( userService.findByUserId(userId), tweetService.findByUserId(userId))

find

finduserId userAndTweets

User Service

Tweet Service

http://www.slideshare.net/knoldus/finagle-by-twitter-engineer/16

join

他のマイクロサービスへクエリを投げ、全ての応答が揃ったら非同期に集約してタプルにする

Page 82: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

What と How の分離Input

Input

Output(2) ランタイム

(1) プログラミングモデル (DSL)

(how を実行する = メッセージ配送)

(what を記述する = データフロー)

関数型プログラミングなどの 宣言的なプログラミングモデルと親和性が高い

Page 83: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

横断的関心事の合成

recordHandletime andThentraceRequest andThencollectJvmStats andThenparseRequest andThenlogRequest andThenrecordClientStats andThensanitize andThenrespondToHealthCheck andThenapplyTrafficControl andThenvirtualHostServer

Filter (実態はただの関数) をService に合成するだけで、サーバに様々な横断的関心事を追加できる

http://monkey.org/~marius/funsrv.pdf

Page 84: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

運用基盤との連携

• 例えば、Finagle で書いたサーバから、Zipkin などの分散トレースシステムにトレース情報を送信して可視化できる

Page 85: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

結果整合性

• マイクロサービスやリアクティブ宣言の警句

• “分散トランザクションを避けよ”

• “shared-nothing にして競合を最小化せよ”

• ユースケース次第で最適解は変わる • 誤っていたら謝って手動で修正する、とか

• とはいえ、万事それで片付くかというと…

Page 86: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

トランザクションと MSA

https://martin.kleppmann.com/2015/11/04/transactions-at-code-mesh.html

友達解除 <友達>にメッセを送る

通知サービス

イベントの順序付け

解除した友達に通知が届く…

Page 87: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

協調動作なしの整合性保証

• 万能な手法はない

• パフォーマンスと整合性のトレードオフ

• 保証したい整合性に合わせて手法を選ぶ

• ログ指向アーキテクチャ

• CRDT

Page 88: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

ログ指向アーキテクチャ

• Kafka のようなログ指向の分散 MQ に、他コンポーネントへの全メッセージを書き込んで永続化

• 全てのコンシューマがメッセージを同じ順序で認識することを保証する(書き込み順序は不定)

• 大規模なマイクロサービスでは一般的?

• Twitter の Cassandra 後継の分散 DB

“Manhattan” も同様のアイデアを採用している

Page 89: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

http://postd.cc/using-logs-to-build-a-solid-data-infrastructure-or-why-dual-writes-are-a-bad-idea-part-2/

Page 90: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

CRDT

• Conflict-Free Replicated Data Types • 順序に関係なく収束するデータ型と演算の組について、分散ノード間で協調動作なしで強い結果整合性を保ったデータ共有を実現する仕組み

• Set, Counter, Register, Flag, Map, Graph 等

• できないこともあるので注意(ユニーク ID の発行など)

Page 91: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

CRDT の利用例

• League of Legends のチャットサーバ

• Riak 上に実装している

• フレンドリスト管理の分散化など

• https://engineering.riotgames.com/news/chat-service-architecture-persistence

• Akka でも利用できる (Akka Distributed Data モジュール)

Page 92: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

参考: LASP

• Erlang + Riak Core ベースの分散処理言語

• Basho の Christopher Meiklejohn 氏が開発中。Oz

言語で有名な Peter Van Roy 氏が指導教官?

• “Coordination-Free Computations”

• “Coordination-Free Designs for Mobile Gaming”

Page 93: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

参考: Coordination free

• 協調動作 (coordination) をしなくても一貫性が保証できる不変条件を定式化しようという研究

• Peter Bailis, “Coordination Avoidance in Database Systems” (スライド)

• GitHub にある OSS を解析したら 86.9% はテストをパスしたとか

Page 94: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

運用の複雑さ

• ひたすらつらい

• 配備自動化やサービスディスカバリは必須

• 宣言型の DSL を書くと Mesos 等からリソースを割り当てて自動配備してくれる世界になってほしい

• 「イミュータブルインフラ」がバズった割には命令型の DSL が主流な現状 (Dockerfile とか)

• ビッグデータ周りではある意味実現している

Page 95: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

https://speakerdeck.com/googlecloudjapan/google-cloud-dataflowwoli-jie-suru

DAG でデータ処理パイプラインを記述

in Google Cloud Dataflow

Page 96: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

https://speakerdeck.com/googlecloudjapan/google-cloud-dataflowwoli-jie-suru

ランタイムとしてのGoogle Cloud

データフロー定義

データフロー・ランタイムとしての Google クラウドが データフローの最適化とタスクのスケジュールを行う

Page 97: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

Typesafe ConductR

https://www.typesafe.com/products/conductr

Page 98: リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題〜 #devsumi

まとめ

• 分散システムの必要性

• 性能と組織のスケーラビリティ、耐障害性

• 分散システムはつらい

• すでにある体系的な知見やアカデミアの研究にも目を向けよう