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
subpath importsで始めるモック生活
10tera
0
300
카카오페이는 어떻게 수천만 결제를 처리할까? 우아한 결제 분산락 노하우
kakao
PRO
0
110
Compose 1.7のTextFieldはPOBox Plusで日本語変換できない
tomoya0x00
0
190
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
310
型付き API リクエストを実現するいくつかの手法とその選択 / Typed API Request
euxn23
8
2.2k
ペアーズにおけるAmazon Bedrockを⽤いた障害対応⽀援 ⽣成AIツールの導⼊事例 @ 20241115配信AWSウェビナー登壇
fukubaka0825
6
1.8k
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
CSC509 Lecture 09
javiergs
PRO
0
140
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
220
Contemporary Test Cases
maaretp
0
130
Featured
See All Featured
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Unsuck your backbone
ammeep
668
57k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Optimizing for Happiness
mojombo
376
70k
The Language of Interfaces
destraynor
154
24k
GitHub's CSS Performance
jonrohan
1030
460k
How GitHub (no longer) Works
holman
310
140k
Raft: Consensus for Rubyists
vanstee
136
6.6k
[RailsConf 2023] Rails as a piece of cake
palkan
52
4.9k
Writing Fast Ruby
sferik
627
61k
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