More Related Content Similar to Akkaで分散システム入門 (20) Akkaで分散システム入門6. そもそも分散システムとは
● 広義
○ 複数のプロセスが、ネットワークを介して通信しながら、
○ 協調して何かを遂行するシステム
● “故障” に注目した定義もある
○ “分散システムとは自分が存在すら知らないコンピュータ上の障害があなた
のコンピュータを利用不可能してしまうようなシステムだ”
by Leslie Lamport (拙訳)
○ “部分的な故障を許容するシステム” by @kumagi (*)
6
(*) “本当は恐ろしい分散システムの話” 熊崎宏樹 NTTデータテクノロジーカンファレンス2017
8. 分散システムは複雑で難しい
● 考えることがとても多い
○ 8 Fallcies of Distributed Computing
● 多くのコンセプト・アルゴリズムたち
○ 分散システムについて語るときに我々の語ること ― 分散システム
● 不可能性の存在 (故障、ネットワーク分断による限界)
○ データ整合性の限界 → CAP 定理
○ 分散合意の限界 → FLP 不可能性
8
9. 8 Fallcies of Distributed Computing
(分散コンピューティングの落とし穴)
1. ネットワークは信頼できる
2. レイテンシはゼロである
3. 帯域幅は無限である
4. ネットワークはセキュアである
5. ネットワーク構成は変化せず一定である
6. 管理者は1人である
7. トランスポートコストはゼロである
8. ネットワークは均質である
9
wikipedia
10. たくさんのコンセプト・アルゴリズムたち
10
分散システムについて語るときに我々の語ること ― 分散システム ... - POSTD
“分散システムについては、もう随分と前から学びたいと思っていました。ただ、それ
は一度首を突っ込んだら最後、ゴールのない迷路に迷い込むようなものなのです。ど
こまでも続いているウサギの穴のようなものです。分散システムに関する文献は星の
数ほど存在します。
(...中略...)
分散システムについて私が考える主なコンセプトを論文や書籍の他、同システムに
ついて学ぶことができる資料を引用しながら掘り下げていきたいと考えたのです。”
13. CAP 定理 〜データ整合性についての限界〜
● 分散システムではこれら3つを同時に満たすシステムは存在しない
○ Consistency(一貫性): 読めるデータはいつでも最新(もしくはエラー)
○ Availability(可用性): いつでもどこかのプロセスから読み書きできる
○ Partition Tolerance(分断耐性): ネットワークが分断しても耐えられる
● 定理から導かれる取り得る戦略
○ 一貫性(C) + 可用性(A): 分断耐性がない
■ 分断が起きたら片方を切り捨てる (Amazon RDSのMulti-AZによるHA等)
○ 可用性(A) + 分断耐性(P): 一貫性がない
■ 常に読み書きできて、分断しても耐えられるけど、データが最新じゃない可能性有(Cassandra等)
■ Eventual Consistency(結果整合性)があるものが多い
○ 一貫性(C) + 分断耐性(P): 可用性がない
■ 分断しても耐えられるけれど、分断中はデータは利用不可(Apache HBase等)
13
Wikipedia: CAP定理
14. FLP 不可能性 〜分散合意についての限界〜
● Fisher, Lynch, Patersonによって証明された分散合意アルゴリズムの不可能性についての定理
非同期な分散システムにおいて
たった一つのプロセスが故障がした(Crash-Stop)だけでも
分散合意に到るアルゴリズムは存在しない
● 注意: 「不可能である」ための主な前提
○ 非同期な通信モデル (プロセスの実行スピードやメッセージ遅延に保証がない )であること
○ 故障は検知できないこと (通信遅延と故障を区別できない )
○ アルゴリズムは決定性である
14
17. Akka は 分散システム と相性がいい
● イベントベース(メッセージ)の並行処理
○ 分散アルゴリズムは、内部状態とイベント受信時のアクションで記述される事が多い
● アクター階層とSupervisorによる適切な内部状態の復旧/破棄
○ Akka Cluster 上でクラスタから除外されたら速やかに子孫のアクターを破棄できる
● 位置透過性
○ やり取りするActorが、localに存在するActorか、Remoteに存在するActorか気にせずActorを
実装可能(ActorRefという統一的な型によるプログラミング )
○ スケールアップ・スケールアウトの選択が自由
17
18. Akkaが提供してくれる
主な分散システム系のモジュール
● Akka Cluster
○ ゴシッププロトコルを使ってクラスターのメンバーシップを管理、故障検知器付き
● Akka Cluster Singleton
○ 文字通りクラスタ内で唯一のアクターを作成してくれる
○ Cluster Shardingが内部で使っている
● Akka Cluster Sharding
○ アクターをクラスタ内にシャーディングしてくれる。メッセージのルーティングもやってくれる
○ 障害時にアクターがノードを移動したりするのでその時の状態はAkka Persistenceを使う
● Akka Distributed Data
○ CRDTという分散システムと親和性の高いデータ構造の実装
○ Cluster Shardingが内部で使っている
18
19. ● Amazon Dynamo, Riak に影響を受けている
● 主な機能
○ 非中央集権的なクラスタメンバーシップ管理
○ Φ漸増型故障検出器(Φ Accrual Failure Detector) による故障検知
● Akka Clusterの耐障害性について
○ ネットワーク分断・プロセス故障による影響
○ Split Brain 問題
○ Split Brain Resolverによる 耐障害性
Akka Cluster - 動的クラスタメンバーシップ管理 -
19
Building reactive distributed systems with Akka - SlideShare
21. seed-nodeの指定方法
● 通常はクラスタ起動時に事前知識としてseed nodesを指定する
○ seed-nodes = ["akka.tcp://ClusterSystem@1.2.3.4:5678"]
● seed node を探す手助けしてくれる方法・モジュールもある
○ ConstructR
■ Etcd, Zookeeper, Consul, Redis といったcoordinationサービスと連携
○ Akka Cluster Bootstrap (Akka Management の 一部)
■ Akka Discoveryというモジュールを使ってクラスタメンバを探す
● DNS, Kubernetes, Marathon, EC2 Tag等が使える
21
Building reactive distributed systems with Akka - SlideShare
22. Akka Clusterのメンバーシップの状態遷移
● 状態の更新はリーダーアクションによって
行われる
○ 離脱時、ノードはleaveをリクエストし、
最終的にremovedになって除外される
● リーダーは決まる(≠決める)
○ リーダー選挙アルゴリズムみたいのは行われない
○ unreachableでない最小のノードがリーダー
● MemberのIdは “hostname:port:uid”
○ uidは起動時に毎回変わる
○ 再Join時は別ノード扱い
○ Crash-Failureだけ考えれば良くなる
● failure detectorによってnodeはunreachableになる
22
https://doc.akka.io/docs/akka/2.5.11/common/cluster.html
23. Akka Clusterの故障検知とその動作
Φ漸増型故障検出器(Φ Accrual Failure Detector)
● 検出方法
○ ハートビートを送り合う。受け取ったハートビート受信履歴から
○ 今後もハートビートが来るか?という確率を予測して
○ その確率を元に相手が死んでいるかどうかというレベル (Φ値: suspicious level)を算出
○ 閾値を事前に決めておいて 、それを上回ったら、故障と判断する
■ default は 8, EC2のようなcloud環境では12が推奨されている
○ 注意: ネットワークが遅いのか、分断なのか、処理が遅いのか、本当に故障しているか
は検知できない
● 状態の変更とその影響
○ 故障と判断されたら unreachable になる(ハートビートが再開したら復旧する )
○ unreachableがいるとgossipが収束しないのでリーダーアクションが取れなくなる
■ つまり、システムが一切スケールできなくなる 23
24. Akka Clusterの提供する耐障害性
● Akka Clusterの耐障害設計 - SlideShare がとても詳しいので必読です
● ここでは駆け足で下記の要点だけを紹介していきます
○ auto-down + Split Brain Resolverを使うとCrash-Stop Failureへの耐性が持てる
○ クラスターを適切に回復させるためには seedの設定に注意
○ CAP定理だと C+A の戦略
■ 分断した片方を(戦略に従って)放棄する
24
26. ● 故障判定されたプロセスが実は生きていたら?
→ Leaderが複数出現する
● Auto-Downが一定時間後にunreachableなメンバを
お互いにauto-downしあって、
● 結果的にgossipが別々に収束してクラスタが複数個
に分割されてしまう!!
○ もしもCluster-Sharding、Cluster-Singletonを使っている
場合、データの破損が起きる可能性がある
auto-downによるSplit Brain問題
26
Down
Down
Down
リーダー リーダー
リーダー
27. Split Brain Resolverによる解決法
● お互いにDownしあわないようにするSplit Brain Resolver
○ Akka Commercial Addons
○ GitHub - TanUkkii007/akka-cluster-custom-downing
● 雑に言うと、分断/障害前の情報はそれぞれ持っているので、それを元に、
自分が残るべきかというルールを作って、結果として高々1クラスタだけが残るようにする
● 利用可能な戦略: Keep Referee, Keep Oldest, Static Quorum, Keep Majority
○ どれも一長一短あり。すべてのnodeを停止してしまう場合がそれぞれある
■ 例えばKeep Majorityだと半分以上のnodeが停止するとすべてのノードが停止
○ FLP 不可能性によって万能な戦略は存在しえない事に注意
● 分断時に一つを選んでその他を切り捨てるという意味では C+A 戦略を取っているとも見れる
27
28. Join
再起動時のseed node誤指定によるSplitBrain
● Split Brain Resolverによって安全にDownされた後、
そのノードを再起動する場合
● 生き残っているクラスタをseedに
指定しないと再度Split Brainが起こる可能性有
○ 確認してちゃんとseedを手動で指定して起動するか
○ 自動で再起動されるようにしている場合 (ASG, kubernetes, etc.)
■ 一つのAZに寄せるか、
■ もしくは、Akka Cluster Bootstrapで確実に生きている
nodeを検出するか
28
Join
Join
29. Akka Clusterの耐障害性まとめ
● Membership Id に uid を使うことで Crash-Stop Failure を作り出している
○ Crash-Recovery を 考えなくても良いように工夫している
● Split Brain Resolverを使うとCrash-Stop Failure 耐性を持てる
○ 使っている戦略によって故障時に得るものと失うものが異なるので、
要求にあったものを使うことが大切
■ 例えば Keep Majority 戦略 だとプロセスの半分以上が停止すると
クラスタ全体が停止する(Split Brainは発生しない)
● Split Brain Resolverを使うことで、CAPの C+A の戦略を取ることができる
○ 分断したら一つを残してあとは切り捨てるという意味で
29
31. ● Akka Cluster内でSingleton Actorを作ってくれる
○ ”oldest” な node上に実際のActorが生成される
● 主な用途
○ クラスタ全体での集中管理(coordination)
○ single master, many workers
○ 外部システムへの連携ポイント
● 注意
○ 簡単にボトルネックになる
○ OldestのLeave/Down時(含障害時)はHand-Over
によってCluster Singleton不在があり得る
Akka Cluster Singleton
31
Building reactive distributed systems with Akka - SlideShare
32. Akka Cluster Sharding
● Akka Cluster上でActorをシャーディング
○ EntityId(論理Id) ベースで物理位置を気にせず
ルーティングもしてくれる (位置透過)
○ どのシャードがどのノードにあるか?
は、ShardCoordinatorが管理する
32Building reactive distributed systems with Akka - SlideShare
33. Akka Cluster Sharding
● 効果
○ スケールしやすい: ノード数が伸縮しても自動でシャード単位で Actorを再配置してくれる
■ Actorが状態を持っている場合は Akka Persistenceを使う
○ 位置透過的にentityId(論理Id)でactorにメッセージが送れる
○ DDD (Domain Driven Design) ととても相性がいい
■ 集約ルートをActorで抽象化して、クラスター上に Shardingしてくれてスケールできる
■ ドメイン操作 = その集約ルートにメッセージを送って状態を変更する
33
34. ● Akka Persistence
○ Event Sourcingの考え方に基づいて
Actorの状態をStorageとsyncする
● ノードがDownするとShardは移動する
○ Akka Persistenceを使えば
安全に状態を移動できる
● 分散システム観点で見ると
○ Single Writer Principle が実装できて
いて排他制御の必要がなくなる
○ KVSで十分スケール可能
Akka Cluster Sharding + Akka Persistence
34
Building reactive distributed systems with Akka - SlideShare
Reliable and Scalable Storage
※点線囲み以外は筆者による加筆
35. Akka Distributed Data = CRDT
≒ バラバラに更新されても全部操作をマージすれば結果的には
OKなデータ構造
35
CountUp(1) 時間
CountUp(2)
3
3
32
1
2
0
0
0
● 分散システムととても相性が良い (スケールしやすい&故障に強い )
○ CAP の A+P をサポートする データタイプの実装
○ Eventual Consistency によるデータ整合性 (いつか正しくなるだけ )
● ShardCordinator の状態を Cluster 上で 記憶 するために利用 (デフォルト)
● CRDT (Conflict-free Replicated Data Type)を15分で説明してみる - Qiita
36. Akka Distributed Data
● CRDTには二種類ある
○ 操作を送り合う Commutative Replicated Data Type
○ レプリカ自体を送りあう Convergent Replicated Data Type
■ Akka Distributed Dataはこちら
■ Majority Quorum を利用して整合性の高い読み書きもサポート
● サポートされるデータタイプ
○ Counter, Set, Map, Register, Flag
36
37. 全体のまとめ
● 分散システムの故障モデル階層・著名な不可能性(CAP, FLP)について紹介
● Akka が提供する主な分散システムモジュールの概要
○ Akka Cluster
■ Akka ClusterはSplit Brain Resolverを使わないとほぼ障害耐性がない
■ Split Brain Resolverを使えばCrash-Stop耐性を確保できる
● どの故障パターン時に node全停止があり得るか認識することが重要
■ Split Brain Resolverを使うと CAP で言うところの C+A の戦略を取れる
○ Akka Cluster Sharding with Akka Persistence
■ DDDを活用したWebアプリケーションと親和性が高い
■ Akka Cluster レベルで シャーディング & Single Writer Principleを実現してくれる
■ ACIDな分散DBを用いなくても、KVSで十分スケールするシステムが構築できる
37
39. おすすめ文献
● 分散システム
○ 分散システムについて語るときに我々の語ること ― 分散システム ... - POSTD
○ Introduction to Reliable and Secure Distributed Programming
○ Stumbling over consensus research: Misunderstandings and issues
○ A Comprehensive study of Convergent and Commutative Replicated Data Types
○ 分散システムについて語らせてくれ - SlideShare
● Akka
○ Documentation | Akka
○ Building reactive distributed systems with Akka - SlideShare
○ Akka実践バイブル アクターモデルによる並行・分散システムの実現 - 翔泳社
○ Akka Clusterで超レジリエンスを手に入れる | Think IT(シンクイット)
○ Akkaの分散されたアクター間で DBを使わずにデータを共有する方法 - Qiita
○ Akka Clusterの耐障害設計 - SlideShare 39