Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Akkaで分散システム入門

2,935 views

Published on

ScalaMatsuri 2018 Training Day (2018/03/16)での講演資料です
http://2018.scalamatsuri.org/

Published in: Technology

Akkaで分散システム入門

  1. 1. Akkaで分散システム入門 大村伸吾 2018/03/16 ScalaMatsuri 2018 Training Day http://2018.scalamatsuri.org/
  2. 2. 今日の流れ ● 分散システムとはなにか ● 分散システムをなぜつくるのか ● 分散システムの難しさ ● Akkaの分散システム構築のためのモジュール群 ● おすすめの ○ ScalaMatsuri 2018セッション達 2
  3. 3. 注意 ● トレーニング・デイということでAkkaを使って分散システムに挑戦してみたいと思う方の最初の足 がかりになれる程度の概要レベルのお話をさせていただきます ● 出来る限りAkkaの前提知識がなくても良いような概論をわかりやすく説明することを心がけます が、わかりにくいところがあればセッション後に質問お願いします ● 分散システムはとても多くの文献・研究論文があり非常に広い分野です。私も学習を続けていま すが、間違い等あるかもしれませんので、もしあればコメントいただけると幸いです。 ● Akkaのモジュール群の詳細な利用方法は書籍・Webを参照してください (参考文献のリストを最後の載せています) 3
  4. 4. 自己紹介 - 大村 伸吾 (おおむら しんご) ● 職歴 4
  5. 5. なぜ分散システムを作るのか ● スケーラビリティ ○ 複数で並行処理を行うことでたくさん処理をしたい ○ 全部一箇所でやるのではなくて分担作業したい ● 耐障害性 ○ 一箇所だと何処かが壊れたらおしまい ■ システムも使えなくなる ■ 最悪データがなくなったりする ○ どこかは故障するけど全体は故障しない &データなくなってほしくない 5
  6. 6. そもそも分散システムとは ● 広義 ○ 複数のプロセスが、ネットワークを介して通信しながら、 ○ 協調して何かを遂行するシステム ● “故障” に注目した定義もある ○ “分散システムとは自分が存在すら知らないコンピュータ上の障害があなた のコンピュータを利用不可能してしまうようなシステムだ” by Leslie Lamport (拙訳) ○ “部分的な故障を許容するシステム” by @kumagi (*) 6 (*) “本当は恐ろしい分散システムの話” 熊崎宏樹 NTTデータテクノロジーカンファレンス2017
  7. 7. 普通のWebアプリもそうなの? ● 広義の定義に当てはめるとそうとも言える ○ アプリサーバが一台くらい落ちたっていまどきはサービスは落ちない ● 難しさをDBに閉じ込めているようにも見える? ○ アプリケーションプロセスは状態を持たないのが普通 ○ DBがSPOF (Single Point of Failure) になりがち ○ KVS(Key-Value Storage)はもうかなりポピュラー ■ いわゆるトランザクション (ACIDな操作)未対応が多い ○ 分散DBも最近良く聞く様になってきた (Spanner, Kudu, CockroachDB)になってきた 7
  8. 8. 分散システムは複雑で難しい ● 考えることがとても多い ○ 8 Fallcies of Distributed Computing ● 多くのコンセプト・アルゴリズムたち ○ 分散システムについて語るときに我々の語ること ― 分散システム ● 不可能性の存在 (故障、ネットワーク分断による限界) ○ データ整合性の限界 → CAP 定理 ○ 分散合意の限界 → FLP 不可能性 8
  9. 9. 8 Fallcies of Distributed Computing (分散コンピューティングの落とし穴) 1. ネットワークは信頼できる 2. レイテンシはゼロである 3. 帯域幅は無限である 4. ネットワークはセキュアである 5. ネットワーク構成は変化せず一定である 6. 管理者は1人である 7. トランスポートコストはゼロである 8. ネットワークは均質である 9 wikipedia
  10. 10. たくさんのコンセプト・アルゴリズムたち 10 分散システムについて語るときに我々の語ること ― 分散システム ... - POSTD “分散システムについては、もう随分と前から学びたいと思っていました。ただ、それ は一度首を突っ込んだら最後、ゴールのない迷路に迷い込むようなものなのです。ど こまでも続いているウサギの穴のようなものです。分散システムに関する文献は星の 数ほど存在します。 (...中略...) 分散システムについて私が考える主なコンセプトを論文や書籍の他、同システムに ついて学ぶことができる資料を引用しながら掘り下げていきたいと考えたのです。”
  11. 11. たくさんのコンセプト・アルゴリズムたち 実行・故障モデル系 タイミングモデル(同期・非同期) プロセス間通信(メッセージパッシング・共有メモリ) 故障モデル 11 アルゴリズム系 故障検出機能 リーダー選出 合意 Quorums 分散システムの時間 (VectorClock, etc.) FLP 分散システムについて語るときに我々の語ること ― 分散システム ... - POSTD
  12. 12. プロセスの故障モデル 12 Byzantine Failure Crash-Recovery Failure Omission Failure Crash-Stop Failures 何でもあり(システムを騙すような挙動もあり ) 故障停止するが、有限時間内に正常に戻る可能性あり (これを繰り返す可能性も有る ) 停止して二度と戻らない メッセージを送らなかったり、受信しなかったりする Introduction to Reliable and Secure Distributed Programming 難/広 易/狭
  13. 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. 14. FLP 不可能性 〜分散合意についての限界〜 ● Fisher, Lynch, Patersonによって証明された分散合意アルゴリズムの不可能性についての定理 非同期な分散システムにおいて たった一つのプロセスが故障がした(Crash-Stop)だけでも 分散合意に到るアルゴリズムは存在しない ● 注意: 「不可能である」ための主な前提 ○ 非同期な通信モデル (プロセスの実行スピードやメッセージ遅延に保証がない )であること ○ 故障は検知できないこと (通信遅延と故障を区別できない ) ○ アルゴリズムは決定性である 14
  15. 15. Akkaで分散システム入門 15
  16. 16. Akkaとは = アクターモデルによる並行・分散プログラミングツールキット 16 非同期メッセージによる Shared-Nothingな並行処理 Actor階層とSupervisor による障害処理 ActorRefによる位置透過 なActorプログラミング Actor Actor Actor Inbox Dispatchers Parent Child Child Failure A B C Actor Ref Actor Ref Restart
  17. 17. Akka は 分散システム と相性がいい ● イベントベース(メッセージ)の並行処理 ○ 分散アルゴリズムは、内部状態とイベント受信時のアクションで記述される事が多い ● アクター階層とSupervisorによる適切な内部状態の復旧/破棄 ○ Akka Cluster 上でクラスタから除外されたら速やかに子孫のアクターを破棄できる ● 位置透過性 ○ やり取りするActorが、localに存在するActorか、Remoteに存在するActorか気にせずActorを 実装可能(ActorRefという統一的な型によるプログラミング ) ○ スケールアップ・スケールアウトの選択が自由 17
  18. 18. Akkaが提供してくれる 主な分散システム系のモジュール ● Akka Cluster ○ ゴシッププロトコルを使ってクラスターのメンバーシップを管理、故障検知器付き ● Akka Cluster Singleton ○ 文字通りクラスタ内で唯一のアクターを作成してくれる ○ Cluster Shardingが内部で使っている ● Akka Cluster Sharding ○ アクターをクラスタ内にシャーディングしてくれる。メッセージのルーティングもやってくれる ○ 障害時にアクターがノードを移動したりするのでその時の状態はAkka Persistenceを使う ● Akka Distributed Data ○ CRDTという分散システムと親和性の高いデータ構造の実装 ○ Cluster Shardingが内部で使っている 18
  19. 19. ● Amazon Dynamo, Riak に影響を受けている ● 主な機能 ○ 非中央集権的なクラスタメンバーシップ管理 ○ Φ漸増型故障検出器(Φ Accrual Failure Detector) による故障検知 ● Akka Clusterの耐障害性について ○ ネットワーク分断・プロセス故障による影響 ○ Split Brain 問題 ○ Split Brain Resolverによる 耐障害性 Akka Cluster - 動的クラスタメンバーシップ管理 - 19 Building reactive distributed systems with Akka - SlideShare
  20. 20. ゴシッププロトコルによるメンバーシップ管理 ● ゴシッププロトコルの大まかな流れ ○ 自分の持っているメンバーリスト情報を、 知っているメンバーと交換し続ける ○ メンバーシップ情報が全員に行き渡って収束する ○ 収束すると後リーダーが決まる ○ 新しいノードはJoinメッセージをクラスタメンバに送る ○ リーダーがメンバシップを更新する。更新時もゴシップを使う → また次のリーダーが決まる ● 一番最初全員自分しか知らないとどうしよう もないのでseed-nodesをどうにかして指定する必要がある 20 Building reactive distributed systems with Akka - SlideShare
  21. 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. 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. 23. Akka Clusterの故障検知とその動作 Φ漸増型故障検出器(Φ Accrual Failure Detector) ● 検出方法 ○ ハートビートを送り合う。受け取ったハートビート受信履歴から ○ 今後もハートビートが来るか?という確率を予測して ○ その確率を元に相手が死んでいるかどうかというレベル (Φ値: suspicious level)を算出 ○ 閾値を事前に決めておいて 、それを上回ったら、故障と判断する ■ default は 8, EC2のようなcloud環境では12が推奨されている ○ 注意: ネットワークが遅いのか、分断なのか、処理が遅いのか、本当に故障しているか    は検知できない ● 状態の変更とその影響 ○ 故障と判断されたら unreachable になる(ハートビートが再開したら復旧する ) ○ unreachableがいるとgossipが収束しないのでリーダーアクションが取れなくなる ■ つまり、システムが一切スケールできなくなる 23
  24. 24. Akka Clusterの提供する耐障害性 ● Akka Clusterの耐障害設計 - SlideShare がとても詳しいので必読です ● ここでは駆け足で下記の要点だけを紹介していきます ○ auto-down + Split Brain Resolverを使うとCrash-Stop Failureへの耐性が持てる ○ クラスターを適切に回復させるためには seedの設定に注意 ○ CAP定理だと C+A の戦略 ■ 分断した片方を(戦略に従って)放棄する 24
  25. 25. ゴシップをすすめるために Unreachableノードの除去する必要がある ● downを経由してremovedに遷移させる必要がある ● 方法は2つ ○ Cluster Http Management, JMX等を使って 手動でDown処理をする ■ Downするまでシステムはスケールできない ○ unreachableになってから一定時間後に自動で downするauto-downという機能を使う ■ !!!Split Brainを引き起こすのでauto-downは!!! !!!プロダクションでは使ってはいけない !!! 25 https://doc.akka.io/docs/akka/2.5.11/common/cluster.html
  26. 26. ● 故障判定されたプロセスが実は生きていたら? → Leaderが複数出現する ● Auto-Downが一定時間後にunreachableなメンバを お互いにauto-downしあって、 ● 結果的にgossipが別々に収束してクラスタが複数個 に分割されてしまう!! ○ もしもCluster-Sharding、Cluster-Singletonを使っている 場合、データの破損が起きる可能性がある auto-downによるSplit Brain問題 26 Down Down Down リーダー リーダー リーダー
  27. 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. 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. 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
  30. 30. Akka Cluster上で動くモジュール達 Akka Cluster Singleton Akka Cluster Sharding Akka Distributed Data 30
  31. 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. 32. Akka Cluster Sharding ● Akka Cluster上でActorをシャーディング ○ EntityId(論理Id) ベースで物理位置を気にせず ルーティングもしてくれる (位置透過) ○ どのシャードがどのノードにあるか? は、ShardCoordinatorが管理する 32Building reactive distributed systems with Akka - SlideShare
  33. 33. Akka Cluster Sharding ● 効果 ○ スケールしやすい: ノード数が伸縮しても自動でシャード単位で Actorを再配置してくれる ■ Actorが状態を持っている場合は Akka Persistenceを使う ○ 位置透過的にentityId(論理Id)でactorにメッセージが送れる ○ DDD (Domain Driven Design) ととても相性がいい ■ 集約ルートをActorで抽象化して、クラスター上に Shardingしてくれてスケールできる ■ ドメイン操作 = その集約ルートにメッセージを送って状態を変更する 33
  34. 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. 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. 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. 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
  38. 38. このセッションに関連する おすすめのScalaMatsuriセッション ● 土曜 ○ 15:00 - 15:40 @ 会場B: Akka を用いた分散システムの構築 , Anil Wadghule ○ 17:00 - 17:40 @ 会場A: リアクティブDDD実践入門, かとじゅん ● 日曜 ○ 15:00 - 16:30 @ 会場C: Akka実践バイブルワークショップ , 前出祐吾 38
  39. 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

×