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.3k
ステートフルなアプリケーション のダウンタイムを 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.1k
Using Akka Cluster for a payment service
negokaz
7
4.7k
Other Decks in Programming
See All in Programming
ヤプリ新卒SREの オンボーディング
masaki12
0
130
Jakarta EE meets AI
ivargrimstad
0
660
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
Kaigi on Rails 2024 〜運営の裏側〜
krpk1900
1
230
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
2024/11/8 関西Kaggler会 2024 #3 / Kaggle Kernel で Gemma 2 × vLLM を動かす。
kohecchi
5
930
よくできたテンプレート言語として TypeScript + JSX を利用する試み / Using TypeScript + JSX outside of Web Frontend #TSKaigiKansai
izumin5210
6
1.7k
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
230
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.2k
ローコードSaaSのUXを向上させるためのTypeScript
taro28
1
630
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
Featured
See All Featured
Thoughts on Productivity
jonyablonski
67
4.3k
Into the Great Unknown - MozCon
thekraken
32
1.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Git: the NoSQL Database
bkeepers
PRO
427
64k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Building an army of robots
kneath
302
43k
The Language of Interfaces
destraynor
154
24k
We Have a Design System, Now What?
morganepeng
50
7.2k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
130
Understanding Cognitive Biases in Performance Measurement
bluesmoon
26
1.4k
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