Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ステートフルなアプリケーション のダウンタイムを 10 秒以下 にすることを目指して
Search
Kazuki Negoro
March 05, 2021
Programming
1
6.5k
ステートフルなアプリケーション のダウンタイムを 10 秒以下 にすることを目指して
第6回Reactive System Meetup in 西新宿
https://reactive-shinjuku.connpass.com/event/202517/
Kazuki Negoro
March 05, 2021
Tweet
Share
More Decks by Kazuki Negoro
See All by Kazuki Negoro
VS Code を使って快適にナレッジを Zenn にためる
negokaz
1
1.2k
Using Akka Cluster for a payment service
negokaz
7
4.9k
Other Decks in Programming
See All in Programming
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
150
楽しく向き合う例外対応
okutsu
0
650
『テスト書いた方が開発が早いじゃん』を解き明かす #phpcon_nagoya
o0h
PRO
8
2.4k
推しメソッドsource_locationのしくみを探る - はじめてRubyのコードを読んでみた
nobu09
2
280
機能が複雑化しても 頼りになる FactoryBotの話
tamikof
0
140
新宿駅構内を三人称視点で探索してみる
satoshi7190
2
120
Datadog Workflow Automation で圧倒的価値提供
showwin
1
160
GoとPHPのインターフェイスの違い
shimabox
2
210
たのしいSocketのしくみ / Socket Under a Microscope
coe401_
8
1.3k
DRFを少しずつ オニオンアーキテクチャに寄せていく DjangoCongress JP 2025
nealle
2
270
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
230
Serverless Rust: Your Low-Risk Entry Point to Rust in Production (and the benefits are huge)
lmammino
1
150
Featured
See All Featured
Become a Pro
speakerdeck
PRO
26
5.2k
Optimizing for Happiness
mojombo
376
70k
Six Lessons from altMBA
skipperchong
27
3.6k
We Have a Design System, Now What?
morganepeng
51
7.4k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
10
1.3k
Scaling GitHub
holman
459
140k
Visualization
eitanlees
146
15k
Transcript
ステートフルなアプリケーション のダウンタイムを 10 秒以下 にすることを目指 して © 2021 TIS Inc.
1 / 39
私 は何者︖ 根来 和輝 Negoro Kazuki TIS 株式会社 テクノロジー&エンジニアリングセンター ミッション
⾼可 用システムを安価 なインフラで 課外活 動 Akka 実践 バイブル執筆 Scala Matsuri 登壇 @negokaz negokaz © 2021 TIS Inc. 2 / 39
Lerna Stack ⾼可 用性 と⾼ スループットを実現 するソフトウェアスタック ⾃⼰修復可能 なアーキテクチャにより高可 用性
を実現 Event Sourcing を用いたロックフリーな永 続化 方式により 高スループットを実現 © 2021 TIS Inc. 3 / 39
稼働率 99.9999% を実現 できるか︖ キャッシュレス決済などミッションクリティカルな業務 で 要求 される可 用性 許
容できる年間停 止時間は 31.5 秒 従来 、専 用のハードウェアを搭載 した高価なサーバー を用意 して実現 してきた稼働 率 © 2021 TIS Inc. 4 / 39
稼働率 99.9999% を実現 できるか︖ キャッシュレス決済などミッションクリティカルな業務 で 要求 される可 用性 許
容できる年間停 止時間は 31.5 秒 従来 、専 用のハードウェアを搭載 した高価なサーバー を用意 して実現 してきた稼働 率 当 時の Lerna では難 しいことが明 らかに © 2021 TIS Inc. 5 / 39
Lerna Stack が直⾯ した稼働率 の限界 レイヤー 障害 種別 ダウンタイム ネットワーク
ネットワーク分断 ~20s Keepalived ノード停 止 ~ 5s HAProxy ノード停 止 ~ 5s アプリ(Akka) ノード停 止 ~15s Cassandra ノード停 止 0s MariaDB(Galera) ノード停 止 ~ 2s © 2021 TIS Inc. 6 / 39
Lerna Stack が直⾯ した稼働率 の限界 レイヤー 障害 種別 ダウンタイム ネットワーク
ネットワーク分断 ~20s Keepalived ノード停 止 ~ 5s HAProxy ノード停 止 ~ 5s アプリ(Akka) ノード停 止 ~15s Cassandra ノード停 止 0s MariaDB(Galera) ノード停 止 ~ 2s © 2021 TIS Inc. 稼働 率 99.999% (年間 5.26 分以 下の停 止)が限界 7 / 39
アプリの MTTR を10 秒以下 にしたい ただし、ターゲットとする業務領域 では 強整 合性 が求
められる 結 果整 合性 で問題なければ Akka の Replicated Event Sourcing という選択肢 がある © 2021 TIS Inc. MTTR: mean time to recovery(平均復旧 時間) Replicated Event Sourcing • Akka Documentation 8 / 39
ダウンタイムの原因 は何なのか︖ 強整 合性 を保障 しながらスケーラブルな Event Sourcing を 実現
するために Lerna Stack では Akka Persistence Akka Cluster Sharding を組 み合わせて使う © 2021 TIS Inc. 9 / 39
ダウンタイムの原因 は何なのか︖ 強整 合性 を保障 しながらスケーラブルな Event Sourcing を 実現
するために Lerna Stack では Akka Persistence Akka Cluster Sharding を組 み合わせて使う この組 み合わせでネットワーク分断障害 の フェイルオーバーを考える © 2021 TIS Inc. 10 / 39
ネットワーク分断障害 の解 決方法 Split Brain Resolver を使う それぞれの側 が到 達できないノードを確認し、
停⽌ する と判 定したほうが自らをシャットダウンする © 2021 TIS Inc. これは keep-majority の例 (多 数派を維 持する) 11 / 39
フェイルオーバーまでの流 れ Akka Cluster Sharding がフェイルオーバーするまでの流 れ (Split Brain Resolver
を利用した場合) © 2021 TIS Inc. 12 / 39
フェイルオーバーまでの流 れ Akka Cluster Sharding がフェイルオーバーするまでの流 れ (Split Brain Resolver
を利用した場合) © 2021 TIS Inc. 13 / 39
さらに伸 びる合意形成 のための時間 合意形成 のための時間はノード数に合わせて ⻑ くとることが推奨 されている cluster size
stable-after + down-removal- margin 5 14s 10 20s 50 26s 100 40s © 2021 TIS Inc. Split Brain Resolver • Akka Documentation 14 / 39
Split Brain Resolver がなぜ必要 か 強整 合性 (一貫性 )を維持 するため
ネットワーク分断 時に無条件 で Entity を回復 させると、 同 じ Entity が複 数のノードに存在 する状態 になり 一貫性 が損 なわれる可 能性 がある © 2021 TIS Inc. 15 / 39
Split Brain Resolver がなぜ必要 か ステートフルな「口座 A」の Entity が 2
箇所 で起 動すると… © 2021 TIS Inc. 16 / 39
ネットワーク分断 とノード停⽌ ネットワーク分断 とノード停⽌ は区別 できない ノード同⼠ は定期的 に相互 にヘルスチェックを行って
応 答があればノードが生きているとみなす © 2021 TIS Inc. 17 / 39
ネットワーク分断 とノード停⽌ ネットワーク分断 とノード停⽌ は区別 できない ノード同⼠ は定期的 に相互 にヘルスチェックを行って
応 答があればノードが生きているとみなす 応 答がないときは ノードが停 止しているのでしょうか? ネットワークが断線 しているのでしょうか? © 2021 TIS Inc. 18 / 39
ネットワーク分断 とノード停⽌ ネットワーク分断 とノード停⽌ は区別 できない ノード同⼠ は定期的 に相互 にヘルスチェックを行って
応 答があればノードが生きているとみなす 応 答がないときは ノードが停 止しているのでしょうか? ネットワークが断線 しているのでしょうか? ノード停 止であってもフェイルオーバーに ネットワーク分断 と同 じ時間がかかる © 2021 TIS Inc. 19 / 39
ダウンタイムを減 らすには 一貫性 の保証 を Split Brain Resolver に頼らない Entity
を複 製しておきリカバリ時の IO を不 要に © 2021 TIS Inc. 20 / 39
どうやってそれを実現 するのか︖ 分散 合意 アルゴリズム Raft 一貫性 のあるステートマシンの複 製を実現 するアルゴリズム
© 2021 TIS Inc. 21 / 39
どうやってそれを実現 するのか︖ 一貫性 の保証 を Split Brain Resolver に頼らない ©
2021 TIS Inc. 22 / 39
どうやってそれを実現 するのか︖ 一貫性 の保証 を Split Brain Resolver に頼らない Raft
が複数 ノードに複製 された Entity の一貫性 を保証 © 2021 TIS Inc. 23 / 39
どうやってそれを実現 するのか︖ 一貫性 の保証 を Split Brain Resolver に頼らない Raft
が複数 ノードに複製 された Entity の一貫性 を保証 Entity を複 製しておきリカバリ時の IO を不 要に © 2021 TIS Inc. 24 / 39
どうやってそれを実現 するのか︖ 一貫性 の保証 を Split Brain Resolver に頼らない Raft
が複数 ノードに複製 された Entity の一貫性 を保証 Entity を複 製しておきリカバリ時の IO を不 要に 常に複製 が存在 しているためリカバリ時の IO は不要 © 2021 TIS Inc. 25 / 39
どうやってそれを実現 するのか︖ 一貫性 の保証 を Split Brain Resolver に頼らない Raft
が複数 ノードに複製 された Entity の一貫性 を保証 Entity を複 製しておきリカバリ時の IO を不 要に 常に複製 が存在 しているためリカバリ時の IO は不要 Raft によりフェイルオーバー時の 障害 検知より後の時間を全て削 減できる © 2021 TIS Inc. 26 / 39
Raft の適 用効 果 - フェイルオーバー時 © 2021 TIS Inc.
27 / 39
私 たちが目指 したもの ダウンタイムが 10 秒以下 強整 合性 が保障 される
スケーラビリティがある 学習 コストが低 い(Akka ユーザーにとって) © 2021 TIS Inc. 28 / 39
akka-entity-replication © 2021 TIS Inc. カードは GitHub Link Card Creator
で生成 しました 29 / 39
アーキテクチャ © 2021 TIS Inc. Cluster Sharding と似 た Actor
の階層 スケールアウト時は Shard が移 動 Entity のイベント列 を Shard が Raft で同期 30 / 39
ダウンタイムを計測 してみた 目標のダウンタイム10 秒以下 を達成 できたのか? © 2021 TIS Inc.
31 / 39
ダウンタイムを計測 してみた 目標のダウンタイム10 秒以下 を達成 できたのか? 達成 !!! 🎉 レイヤー
障害 種別 ダウンタイム ネットワーク ネットワーク分断 8.0s アプリ(Akka) ノード停 止 6.0s © 2021 TIS Inc. 32 / 39
デモ - 環境 の構成 https://github.com/negokaz/sample-akka-entity-replication © 2021 TIS Inc. 33
/ 39
API Akka の既存 ユーザーが実装 しやすいよう Akka Classic Persistence と似 た
API を提 供 class CountActor extends ReplicationActor[Int] { private[this] var count: Int = 0 ... // 複製の中で代表者だけが実行する override def receiveCommand: Receive = { case CountUp(_, amount) => replicate(Incremented(amount)) { event => count = count + event.amount } // 代表者以外の複製が実行する // ただし、代表者においても起動直後は状態を復元するために呼ばれる override def receiveReplica: Receive = { case Incremented(amount) => count = count + amount ... } } © 2021 TIS Inc. 34 / 39
API Raft のログコンパクションのため Actor の状態 は スナップショットとして自動的 に永 続化 される
class CountActor extends ReplicationActor[Int] { private[this] var count: Int = 0 // 現在の"状態"を返す override def currentState: Int = count override def receiveCommand: Receive = { case CountUp(_, amount) => replicate(Incremented(amount)) { event => count = count + event.amount } override def receiveReplica: Receive = { case Incremented(amount) => count = count + amount // Actor の復元時、最後に保存した "currentState" を最初に適用 case SnapshotOffer(snapshot: Int) => count = snapshot } } © 2021 TIS Inc. 35 / 39
Akka 公 式プロダクトとの⽐較 一貫性 リカバリタイム リソース消費 Replicated Event Sourcing 結
果整 合性 0s - Akka Cluster Sharding 強整 合性 19s 以 上 ※1 - Akka Entity Replication 強整 合性 10s 以下 大 © 2021 TIS Inc. ※1: Akka 公 式の推奨値 で構成 した場合 36 / 39
今後 の予 定 3⽉末 に GA 版 (v1.0.0 )リリース 🚀
© 2021 TIS Inc. 37 / 39
ワンクリックでできる コントリビュートがあります © 2021 TIS Inc. 38 / 39
仲間を探しています! Akka Cluster を用いたシステムの開発 OSS ライブラリの開発 分散システムに関わる課題解決 興味ある方はお気軽にお問い合わせください! @negokaz ©
2021 TIS Inc. 39 / 39