View
15.542
Download
2
Category
Preview:
Citation preview
Developers Summit 2016【18-E-5】#devsumiE
リアクティブ・アーキテクチャ~大規模サービスにおける必要性と課題~岡本 雄太 (@okapies)
2016/02/18
Greg Walters, “Crazy Architecutre (UK)" - CC BY 2.0
自己紹介
• 岡本 雄太(@okapies)
• 製造業で働くソフト屋さん
• Scala と Scala OSSs 愛好家
• 最近の仕事はインフラエンジニアっぽい感じ
• ScalaMatsuri 2016 準備委員会 運営委員
公開してる OSS
• finagle-kafka (https://github.com/okapies/finagle-kafka)
• sircuit (https://github.com/okapies/sircuit)
• rx-process (https://github.com/okapies/rx-process)
書き物
• 翻訳:
• リアクティブ宣言 v2.0
• Effective Scala 日本語版
• 命令型のコールバック、関数型のプロミス
• ブログ記事 (http://okapies.hateblo.jp/):
• 非同期ストリーム処理の標準化を目指す "Reactive Streams" とは
• 関数型プログラマのための Rx 入門
• マイクロサービスが Scala を選ぶ3つの理由
発表してきました
Reactive Programmingの話題が中心
http://www.slideshare.net/okapies/scalamatsuri-58141520
アジェンダ
• なぜ分散システムか? • マイクロサービス
• リアクティブシステムと Reactive Streams
• 分散システムのつらい話と対策 • プログラミングモデル • 結果整合性 • 運用の複雑さ
単体マシン !
!
分散システム
大規模分散システムの例
http://www.slideshare.net/adriancockcroft/goto-berlin/76
なぜ分散システムか?
• 開発組織のスケーラビリティ
• 性能のスケーラビリティ
• 耐障害性
なぜ分散システムか?
• 開発組織のスケーラビリティ
• 性能のスケーラビリティ
• 耐障害性リアクティブシステム
マイクロサービス
概念に名前を与える
• 優れたソフトウェアアーキテクチャのエッセンスを抽出して名前を与えたもの
• マイクロサービス
• リアクティブシステム
マイクロサービスアーキテクチャ
• 一つのアプリケーションを小さなサービス群の組み合わせとして構築する手法
http://martinfowler.com/articles/microservices.html
MSA を採用している企業
• Amazon
• Netflix
• PayPal
• Tumblr
• SoundCloud
• LINE
• ドワンゴ
• etc…
マイクロサービスの特性
1. サービスによるコンポーネント化 2. ビジネス遂行能力に基づく組織化 3. プロジェクトではなくプロダクト 4. 賢いエンドポイントと愚かなパイプ 5. 非中央集権的なガバナンス 6. 非中央集権的なデータ管理 7. インフラの自動化 8. 障害を考慮した設計 9. 進化的設計
http://martinfowler.com/microservices/
マイクロサービスの特性
2. ビジネス遂行能力に基づく組織化 3. プロジェクトではなくプロダクト 5. 非中央集権的なガバナンス 9. 進化的設計 1. サービスによるコンポーネント化 4. 賢いエンドポイントと愚かなパイプ 6. 非中央集権的なデータ管理 7. インフラの自動化 8. 障害を考慮した設計
組織の特性 (目的)
技術の特性 (手段)
http://martinfowler.com/microservices/
マイクロサービスの目的
• 開発組織のスケーラビリティの確保
• ビジネス遂行能力を核とした非中央集権的な機能横断型チームとして組織化する(c.f. Conway’s Law)
http://martinfowler.com/articles/microservices.html
マイクロサービスの方法論
• サービス間にビジネス遂行能力やドメインのライフサイクルに従ってモジュール境界を持つ
• サービス間は REST や単純な MQ で繋ぐ。トランザクションはなるべく使わない
• サービス同士の依存関係を減らして独立に配備できるようにする
マイクロサービスの利点
• 強いモジュール境界:マイクロサービスはモジュール構造を強化する。このことは、チームの規模が大きくなるにつれて特に重要になる
• 独立した配備:単純なサービスは配備が容易であり、また自律的なので、個々に不具合が起きてもシステム障害を引き起こしにくい
• 技術的多様性:複数の言語、開発フレームワーク、データストレージ技術を組み合わせることができる
http://martinfowler.com/articles/microservice-trade-offs.html
なぜ分散システムか?
• 開発組織のスケーラビリティ
• 性能のスケーラビリティ
• 耐障害性リアクティブシステム
マイクロサービス
Reactive Manifesto
• Reactive Systems への支持を呼びかける文書
• 社(Scala/Akka 開発元)が主導
• 他に Dave Farley (”継続的デリバリー”の著者)
や Martin Thompson (元 LMAX CTO) など
• アクターモデル、特に Erlang/OTP や Akka のプラクティスを念頭に置いている
賛同者数13,000 人超え
様々なリアクティブ
Reactive Systems
Reactive Programming
Reactive Streams
プログラミングモデル:
ランタイム:
システムアーキテクチャ:
様々なリアクティブ
Reactive Systems
Reactive Programming
Reactive Streams
プログラミングモデル
ランタイム
システムアーキテクチャ:
アプリケーションの要求の変化
数年前 現在
Configuration 数十のサーバ 数千のマルチコアプロセッサ
Responsetime 秒単位 ミリ秒単位
Availability数時間の
オフラインメンテナンス稼働率 100%
Data size ギガバイト単位 ペタバイト単位
システムの構築方法の変化
“大規模システムを構築する組織はこの変化に対処する設計原則を
すでに発見している”
“そのような特徴を備えるシステムをReactive Systems と呼ぼう”
http://www.reactivemanifesto.org/ja
リアクティブシステムの性質
http://www.slideshare.net/Typesafe_Inc/going-reactive-2016-data-preview/6
即応性
弾力性 レジリエンス
メッセージ駆動
価値
手段
形態
価値
手段
形態
http://www.slideshare.net/Typesafe_Inc/going-reactive-2016-data-preview/6
即応性
弾力性 レジリエンス
メッセージ駆動
リアクティブシステムの性質実現したい価値:
ユーザへ迅速かつ一貫した速度でサービスを提供する
障害時にも即応性を維持する
非同期メッセージパッシングが全ての基盤である
負荷が変動しても即応性を維持する
私が仕事で関わった、大きなシステムのアーキテクチャには類似点があった。 そうしたシステムでは、問題領域における明確な Bounded Context を実装したサービスが疎結合で結びついており、互いの通信は非同期メッセージのみで行う。 これらは、RDB の上に構築された箱出しの標準的な三層アーキテクチャのシステムのやり方とは似ても似つかない。
“The Reactive Manifesto | Dave Farley's Weblog” より妙訳
従来の三層アーキテクチャ
プレゼンテーション
ビジネスロジック
RDB
同期呼出
同期呼出
一枚岩のアプリケーション
リアクティブシステムの例
プレゼンテーション
ビジネスロジック
RDB
同期呼出
同期呼出
RDB
非同期
非同期
非同期
KVS
非同期
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 のマイクロサービス構造
MSA ⊂ リアクティブシステム
• マイクロサービスは、リアクティブシステムの実例の一つと考えることができる
• マイクロサービスは、リアクティブシステムの4つの性質を備えているとより良い、と言える
リアクティブなコンポーネント• 他のコンポーネントから非同期メッセージが到着したときだけ反応する(リアクティブ=受け身)
in out
自己完結性 (self-containment)
• 各コンポーネントの内部状態は互いに隔離され、かつ独立したライフサイクルを持つ
• 障害を外部へ波及させることなく封じ込める
? ?in out
× ×外部の状態を暗黙に参照/更新しない
• コンポーネント同士が非同期メッセージパッシングでデータをやり取りする
• 共有メモリは使わない(競合の原因)
メッセージ駆動 (message-driven)
コンポーネント
コンポーネント
…
メッセージバッファ
• メッセージを明示的にやり取りする
• 負荷管理、弾力性、フロー制御が容易に
• プロトコルは非同期なら何でもよい(REST でもメッセージキュー経由でも)
コンポーネント
コンポーネント
メッセージ駆動 (message-driven)
…
• コンポーネント間は非同期(バイナリ)境界で区切られ、互いに別のスレッド、プロセス、ノード、データセンターに配置できる • 疎結合、時間的・空間的隔離、位置透過性
コンポーネント
コンポーネント
メッセージ駆動 (message-driven)
…
補足: 位置透過性
• 全ては分散コンピューティングである
• メッセージパッシングにおいて、単体ノード(マルチコア)と複数ノードにコンセプトの違いはない
• コンポーネントが任意の場所に配備できるなら、ローカル通信は最適化に過ぎない
• メッセージパッシングは RPC ではない
• ネットワーク関連の障害を明示的に扱う
レジリエンス (resilience)
• 部分的に障害が発生してもシステム全体に波及せず(自律的に)回復する、という特性
• 耐障害性よりも広い概念
• 「物体が元の形へ戻ったり、困難から素早く立ち直る能力」のこと
• 〈抵抗力+復元力〉みたいなニュアンス
レジリエンス (resilience)
• エラーを非同期境界で封じ込め、他のコンポーネントに波及させず隔離する
• (予期可能なエラーと障害を区別する)
例外
レジリエンス (resilience)
• レプリケーションによって高可用性や冗長性を確保(c.f. 非同期境界、位置透過性)
ワークロードを複製
レジリエンス (resilience)
• 障害時には、処理中のタスクや回復処理を他のコンポーネントに委譲する (Let it crash)
• コーヒー自販機の喩え(豆が切れたら客に〈コーヒー豆エラー〉を返すのではなくサービスマンを呼んでほしい)
Super-visor
タスク
エラー通知
補足: Let it crash
• 故障したコンポーネントはその場でクラッシュさせて、監督者 (Supervisor) に回復処理を任せる
• 「予期しない障害は必ず起きるし、人為的には防げない」という実世界のシステムに対する観察
• Erlang 発祥の概念で、極めて高い信頼性が求められるシステム(電話交換機など)で可用性を確保するのが目的
http://www.slideshare.net/jboner/without-resilience-nothing-else-matters-56053062
弾力性 (elasticity)
• 弾力性 = Scale Out + Scale In
• シャーディングやレプリケーションによってコンポーネント間で入力を分散し、スケーラビリティを確保(c.f. 位置透過性)
• 同期の競合やボトルネックの原因になるので、メモリの共有はしない(メッセージ駆動)
マイクロサービスとの比較
• マイクロサービス ⊂ リアクティブコンポーネント
• 強固なモジュール境界: 同期呼出ではなく非同期呼出に
• 独立した配備: レジリエントなシステムは〈障害を考慮した設計〉と〈進化的設計〉を満たす
• 技術的多様性: 非同期処理やメッセージ駆動ミドルウェアを重視(HTTP 等でも実現は可能)
• メッセージ送信はバッチ化(RPC 粒度の課題を解決)
どうやって実現するか?
どのようにこの属性を実現するのかについて、マニュフェストの中で規範的に言及するのは避けたいと思いました。 — Martin Thompson
• マニフェストは、リアクティブシステムの性質や品質についてのみ記述しており、具体的な実現方法には触れていない
http://www.infoq.com/jp/news/2014/11/thompson-reactive-manifesto-2
国内事例
• LINE のメッセージング基盤は、Akka Actor を活用したリアクティブな設計になっている
• 「Akka ActorとAMQPでLINEのメッセージングパイプラインをリプレースした話」
• TIS が Akka を使ったデモを GitHub で公開しているhttps://github.com/tech-sketch/reactive-solar-farm-monitor/
Reactive Solar Farm Monitor デモ
https://github.com/tech-sketch/reactive-solar-farm-monitor/blob/master/README.ja.md
Reactive Solar Farm Monitor デモ
http://www.slideshare.net/yugolf/typesafe-reactive-platformreactive-system/35
リアクティブシステムの課題
• リアクティブシステムは大量データを扱う非同期データストリーム
• 同期型とは異なり、システムに流れ込むデータ流量を制御する仕組み(フロー制御)が必要
• フロー制御に失敗すると、データフローが決壊してシステム全体のクラッシュに繋がる
データフローの決壊
• Publisher は Subscriber へメッセージを送る
Publisher Subscriber…
3 msgs/sec 3 msgs/sec
メッセージバッファ
処理能力送信能力
=
• Subscriber が速いときは暇になる→ 計算機資源を有効活用できない
Publisher Subscriber
データフローの決壊
…
< 3 msgs/sec
来ない…あんま送ると悪いかな…
1 msg/sec
• Publisher が速すぎるとバッファが溢れて死ぬ
Publisher Subscriber
データフローの決壊
…
> 3 msgs/sec
100 msgs/sec
やめて!俺にまかせろー!
https://www.flickr.com/photos/chiaralily/4978843623/
Reactive Streams
• Back-Pressure でフロー制御を行う
• 非同期ストリーム処理ランタイムの
相互運用性を確保するための標準規格
Back-Pressure
• Publisher はリクエストされた分だけメッセージを送る → 安全
…
100 msgs/sec
[Request(3)]
Publisher Subscriber
3 msgs/sec
次、3 個くださいあいよー
Back-Pressure
• Back-pressure は伝播する
• C が遅くなったら B, A もスローダウンする
B C…
今はいいです
A…
今はいいですあいよー
経緯
• Reactive Manifesto の発表 (2013年9月)
• Typesafe の主導で、非同期ストリーム技術を開発するベンダー各社の間で、フロー制御の技術課題の解決策を話し合うコミュニティが発足
• GitHub に reactive-streams グループを作成。正式に共同で仕様策定を始める (2014年初頭)
主な参加者
• (Akka)
• (RxJava)
• (Reactor)
• (Vert.x)
Scala 言語の開発元
米国最大手の動画配信サービス
Spring Frameworkの開発元
主な参加者
• Doug Lea
• JSR 166 (java.util.concurrent)の Specification Lead
• 「Java 並行処理プログラミング」の著者の一人
• JDK での標準化は氏の主導で進められている
http://www.amazon.co.jp/dp/4797337206/
Reactive Streams in JDK 9
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 がベース
仕様書とTCK
• ランタイム間の相互接続性を保証する
準拠実装
• Akka Streams (Typesafe)
• Ratpack
• Reactor (Spring)
• RxJava (Netflix)
• Vert.x 3.0 (Red Hat)
DB アクセスライブラリの準拠実装
• Slick 3.0 a.k.a “Reactive Slick” (JDBC)
• ReactiveMongo
• Reactive Rabbit (AMQP)
• Reactive Kafka
• etc…
すべてがリアクティブになる
• リアクティブシステムを、Reactive Streams 準拠のコンポーネントを使って入口から出口まで組み上げることができる
AMQP RxJava Akka Vert.x RDB
例:
余談
なぜ分散システムか?
• 開発組織のスケーラビリティ
• 性能のスケーラビリティ
• 耐障害性リアクティブシステム
マイクロサービス
…本当に分散したいんだっけ?
分散オブジェクト設計の法則
• 第一法則: ??????????
by Martin Fowlerhttp://martinfowler.com/bliki/FirstLaw.html
分散オブジェクト設計の法則
• 第一法則: オブジェクトを分散させるな
by Martin Fowlerhttp://martinfowler.com/bliki/FirstLaw.html
分散化にはデメリットがたくさんある
「分散コンピューティングの落とし穴」
1. ネットワークは信頼できる。 2. レイテンシはゼロである。 3. 帯域幅は無限である。 4. ネットワークはセキュアである。 5. ネットワーク構成は変化せず一定である。 6. 管理者は1人である。 7. トランスポートコストはゼロである。 8. ネットワークは均質である。
マイクロサービスのコスト
• 分散:分散システムはプログラムが難しい。リモート呼出は遅いし、失敗のリスクがある
• 結果整合性:分散システムで強い一貫性を維持するのは非常に困難なので、結果整合性を管理しなければならない
• 運用の複雑さ:定期的に再配備する大量のサービスを管理する成熟した運用チームが必要
http://martinfowler.com/articles/microservice-trade-offs.html
分散プログラミングのつらみ
• RPC の逐次処理や並列処理
• ネットワークの障害・遅延・分断
• リモートホストの障害
• スロットリング(連鎖障害の防止)
• サービスディスカバリ
• モニタリング、リクエストの分散トレース
マイクロサービス向けフレームワーク
• 大規模なマイクロサービスを運用している企業のうち、いくつかは自社の基盤ソフトウェアを OSS 化している
• Netflix OSS
• Twitter Finagle, Zipkin, etc…
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
分散と関数型プログラミング
• 「あれでしょ?ムーアの法則が破れてフリーランチは終わった、これからはマルチコアで並列処理だ関数型だってやつ」
• 分散処理の文脈における関数型の本質は、非同期処理や分散環境での横断的関心事からビジネスロジックを分離して、容易にモジュール化できること
http://monkey.org/~marius/funsrv.pdf
Your Server as a Function
Future 型と Service, Filter という関数の組み合わせでサーバを記述する
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
他のマイクロサービスへクエリを投げ、全ての応答が揃ったら非同期に集約してタプルにする
What と How の分離Input
Input
Output(2) ランタイム
(1) プログラミングモデル (DSL)
(how を実行する = メッセージ配送)
(what を記述する = データフロー)
関数型プログラミングなどの 宣言的なプログラミングモデルと親和性が高い
横断的関心事の合成
recordHandletime andThentraceRequest andThencollectJvmStats andThenparseRequest andThenlogRequest andThenrecordClientStats andThensanitize andThenrespondToHealthCheck andThenapplyTrafficControl andThenvirtualHostServer
Filter (実態はただの関数) をService に合成するだけで、サーバに様々な横断的関心事を追加できる
http://monkey.org/~marius/funsrv.pdf
運用基盤との連携
• 例えば、Finagle で書いたサーバから、Zipkin などの分散トレースシステムにトレース情報を送信して可視化できる
結果整合性
• マイクロサービスやリアクティブ宣言の警句
• “分散トランザクションを避けよ”
• “shared-nothing にして競合を最小化せよ”
• ユースケース次第で最適解は変わる • 誤っていたら謝って手動で修正する、とか
• とはいえ、万事それで片付くかというと…
トランザクションと MSA
https://martin.kleppmann.com/2015/11/04/transactions-at-code-mesh.html
友達解除 <友達>にメッセを送る
通知サービス
イベントの順序付け
解除した友達に通知が届く…
協調動作なしの整合性保証
• 万能な手法はない
• パフォーマンスと整合性のトレードオフ
• 保証したい整合性に合わせて手法を選ぶ
• ログ指向アーキテクチャ
• CRDT
ログ指向アーキテクチャ
• Kafka のようなログ指向の分散 MQ に、他コンポーネントへの全メッセージを書き込んで永続化
• 全てのコンシューマがメッセージを同じ順序で認識することを保証する(書き込み順序は不定)
• 大規模なマイクロサービスでは一般的?
• Twitter の Cassandra 後継の分散 DB
“Manhattan” も同様のアイデアを採用している
http://postd.cc/using-logs-to-build-a-solid-data-infrastructure-or-why-dual-writes-are-a-bad-idea-part-2/
CRDT
• Conflict-Free Replicated Data Types • 順序に関係なく収束するデータ型と演算の組について、分散ノード間で協調動作なしで強い結果整合性を保ったデータ共有を実現する仕組み
• Set, Counter, Register, Flag, Map, Graph 等
• できないこともあるので注意(ユニーク ID の発行など)
CRDT の利用例
• League of Legends のチャットサーバ
• Riak 上に実装している
• フレンドリスト管理の分散化など
• https://engineering.riotgames.com/news/chat-service-architecture-persistence
• Akka でも利用できる (Akka Distributed Data モジュール)
参考: LASP
• Erlang + Riak Core ベースの分散処理言語
• Basho の Christopher Meiklejohn 氏が開発中。Oz
言語で有名な Peter Van Roy 氏が指導教官?
• “Coordination-Free Computations”
• “Coordination-Free Designs for Mobile Gaming”
参考: Coordination free
• 協調動作 (coordination) をしなくても一貫性が保証できる不変条件を定式化しようという研究
• Peter Bailis, “Coordination Avoidance in Database Systems” (スライド)
• GitHub にある OSS を解析したら 86.9% はテストをパスしたとか
運用の複雑さ
• ひたすらつらい
• 配備自動化やサービスディスカバリは必須
• 宣言型の DSL を書くと Mesos 等からリソースを割り当てて自動配備してくれる世界になってほしい
• 「イミュータブルインフラ」がバズった割には命令型の DSL が主流な現状 (Dockerfile とか)
• ビッグデータ周りではある意味実現している
https://speakerdeck.com/googlecloudjapan/google-cloud-dataflowwoli-jie-suru
DAG でデータ処理パイプラインを記述
in Google Cloud Dataflow
https://speakerdeck.com/googlecloudjapan/google-cloud-dataflowwoli-jie-suru
ランタイムとしてのGoogle Cloud
データフロー定義
データフロー・ランタイムとしての Google クラウドが データフローの最適化とタスクのスケジュールを行う
Typesafe ConductR
https://www.typesafe.com/products/conductr
まとめ
• 分散システムの必要性
• 性能と組織のスケーラビリティ、耐障害性
• 分散システムはつらい
• すでにある体系的な知見やアカデミアの研究にも目を向けよう
Recommended