Slide 1

Slide 1 text

CockroachDB から覗く 形式手法の世界 #CNDT2020 #CNDT2020_E チェシャ猫 (@y_taka_23) CloudNative Days Tokyo 2020 (9th Sep. 2020)

Slide 2

Slide 2 text

https://github.com/cockroachdb/cockroach

Slide 3

Slide 3 text

QCon 2019 での発表 形式手法ツール TLA+ により「証明」済 https://qconnewyork.com/ny2019/presentation/cockroachdb-architecture-geo-distributed-sql-database

Slide 4

Slide 4 text

本日お話しすること ● CockroachDB の概要 ○ スケーラビリティを実現するアーキテクチャ ○ 生じた課題と Parallel Commit による解決 ● 形式手法ツール TLA+ の概要 ○ 理論はともかく、ツールとしての雰囲気 ○ CockroachDB の挙動をどう表現・検証するか

Slide 5

Slide 5 text

CockroachDB を知る 1. How Does CockroachDB Construct Transactions?

Slide 6

Slide 6 text

CockroachDB ● Spanner 系の分散データベース ○ インタフェースとして SQL をサポート ○ 強い一貫性を持ったトランザクションをサポート ○ 旧来の RDB と異なりスケールアウト可能 ● データは Node 間で冗長化される ○ 一定規模以下の Node 障害時でもデータを守れる

Slide 7

Slide 7 text

中身はどうなっているのか

Slide 8

Slide 8 text

SQL Transaction Distribution Replication Storage クライアントから見た 処理の流れ

Slide 9

Slide 9 text

SQL Transaction Distribution Replication Storage SQL を Key-Value 命令に変換 トランザクション管理(本日メイン) 適切な Node に命令をルーティング Node 間でデータを冗長化 データをディスクに永続化(省略)

Slide 10

Slide 10 text

SQL Transaction Distribution Replication Storage SQL を Key-Value 命令に変換

Slide 11

Slide 11 text

id (PK) author like 1 alice 4 2 alice 8 3 bob 5 table: posts

Slide 12

Slide 12 text

id (PK) author like 1 alice 4 2 alice 8 3 bob 5 table: posts /posts/2/author /posts/2/like /posts/3/id /posts/3/author /posts/3/like /posts/1/id /posts/1/author /posts/1/like /posts/2/id key alice 8 _ bob 5 _ alice 4 _ value

Slide 13

Slide 13 text

SQL Transaction Distribution Replication Storage 適切な Node に命令をルーティング

Slide 14

Slide 14 text

key value すべての Key-Value

Slide 15

Slide 15 text

key value Range 1 (512 MiB) Range 2 (512 MiB) Range 3 (512 MiB)

Slide 16

Slide 16 text

Node 2 Distribution Layer Node 3 Node 1 Range 1 Range 2 Range 3

Slide 17

Slide 17 text

Node 2 Distribution Layer Node 3 Node 1 Range 1 Range 2 Range 3 PUT k1 = v1 (k1 ∈ Range 1)

Slide 18

Slide 18 text

Node 2 Distribution Layer Node 3 Node 1 Range 1 Range 2 Range 3

Slide 19

Slide 19 text

Node 障害で Range 内のデータが喪失

Slide 20

Slide 20 text

SQL Transaction Distribution Replication Storage Node 間でデータを冗長化

Slide 21

Slide 21 text

Raft ● 合意 (Consensus) プロトコル ○ 一度、合意が得られればその値は覆らない ● Leader Election ○ 見本となる Node (Leader, LeaseHolder) を選択 ● Log Replication ○ 操作列について合意し leaseholder の状態を複製

Slide 22

Slide 22 text

Node 2 Distribution Layer Node 3 Node 1 Range 1 Range 2 Range 3 Range 1 Range 2 Range 3 Range 1 Range 2 Range 3

Slide 23

Slide 23 text

Raft Consensus Groups 1, 2, 3 Range 1 (LH) Range 2 Range 3 Range 1 Range 2 (LH) Range 3 Range 1 Range 2 Range 3 (LH) (LH = LeaseHolder)

Slide 24

Slide 24 text

Node 2 Distribution Layer Node 3 Node 1 k1 = v1 PUT k1 = v1 (k1 ∈ Range 1)

Slide 25

Slide 25 text

Node 2 Range 1: Raft Consensus Node 3 Node 1 k1 = v1 k1 = v1 k1 = v1

Slide 26

Slide 26 text

Node 2 Distribution Layer Node 3 Node 1 k1 = v1 k1 = v1 k1 = v1 Ack Success

Slide 27

Slide 27 text

Node よりむしろ Range が基本単位

Slide 28

Slide 28 text

Range 2 Distribution Layer Range 3 Range 1 k1 = v1 PUT k1 = v1 (k1 ∈ Range 1)

Slide 29

Slide 29 text

Range 2 Distribution Layer Range 3 Range 1 k1 = v1 PUT k1 = v1 (k1 ∈ Range 1)

Slide 30

Slide 30 text

Distribution Layer Range 1 k1 = v1 PUT k1 = v1 (k1 ∈ Range 1) ● 各 Range は Raft で可用性と一貫性が 保たれた一塊の DB とみなせる ● Range 間にはコミュニケーションの 仕組みがない

Slide 31

Slide 31 text

INSERT INTO table VALUES (k1, v1), (k2, v2); SQL Layer

Slide 32

Slide 32 text

INSERT INTO table VALUES (k1, v1), (k2, v2); PUT k1 = v1 + PUT k2 = v2 SQL Layer

Slide 33

Slide 33 text

Range 2 Range 3 Range 1 Client 1 Client 2 k1 = v1 k2 = v2

Slide 34

Slide 34 text

Range 2 Range 3 Range 1 k1 = v1’ k2 = v2’ (合意待ち) Client 1 Client 2 k2 = v2

Slide 35

Slide 35 text

Range 2 Range 3 Range 1 k1 = v1’ k2 = v2 Client 1 Client 2 v1’ + v2 (?)

Slide 36

Slide 36 text

分散トランザクションが必要

Slide 37

Slide 37 text

SQL Transaction Distribution Replication Storage トランザクション管理(本日メイン)

Slide 38

Slide 38 text

Transaction Record 1. トランザクション開始時、Key-Value データと同様に Pending 状態の Transaction Record を書き込む 2. データを書き込む際は上書きする代わりに、 Intent と呼ばれるマーカをつけ、Record を参照 3. 全てのデータ書き込みが成功したら Record の状態を Committed に変更することでコミット

Slide 39

Slide 39 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2

Slide 40

Slide 40 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ : t1 k2 = v2’ : t1 t1 = pending Round-1 Consensus

Slide 41

Slide 41 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ : t1 k2 = v2’ : t1 t1 = pending Round-1 Consensus

Slide 42

Slide 42 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ : t1 k2 = v2’ : t1 t1 = committed Round-2 Consensus

Slide 43

Slide 43 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ : t1 k2 = v2’ : t1 t1 = committed Round-2 Consensus

Slide 44

Slide 44 text

Transaction Record 1. データを読み込もうとした際、Intent を見つけたら まず対応する Transaction Record の状態を確認 2. Record が Pending 状態であれば元の値を採用 3. Record が Committed 状態であれば Intent として 保持されている値を採用

Slide 45

Slide 45 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = pending

Slide 46

Slide 46 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = pending

Slide 47

Slide 47 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = pending

Slide 48

Slide 48 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = pending v1 + v2

Slide 49

Slide 49 text

第 1 章のまとめ ● CockroachDB のアーキテクチャ ○ Range ごとに Raft Group を構成し合意 ● 分散トランザクションの必要性 ○ SQL に伴う Raft Group をまたいだ操作 ● Transaction Record による実装 ○ データ + Transaction Record で 2 回の合意

Slide 50

Slide 50 text

As a database that prides itself on geo-distributed use cases, we must strive to reduce the latency incurred by common OLTP transactions to near the theoretical minimum: the sum of all read latencies plus one consensus latency. CockroachDB RFC: Parallel Commits https://github.com/cockroachdb/cockroach/blob/master/docs/RFCS/20180324_parallel_commit.md

Slide 51

Slide 51 text

合意を 1 ラウンド分にできないか?

Slide 52

Slide 52 text

形式手法に触れる 2. How Do Formal Methods Handle the Complexity?

Slide 53

Slide 53 text

例:投稿に「いいね!」する機能

Slide 54

Slide 54 text

各ユーザの動作 1. DB から現在の Like の個数を取得 2. ローカルでその値を + 1 する 3. DB に新しい値を書き戻す

Slide 55

Slide 55 text

DB Alice Bob 0 0

Slide 56

Slide 56 text

DB Alice Bob 0 0 0 0

Slide 57

Slide 57 text

DB Alice Bob 0 1 1 0 0 0

Slide 58

Slide 58 text

DB Alice Bob 0 1 1 0 0 0 1 1

Slide 59

Slide 59 text

DB Alice Bob 0 1 1 0 0 0 1 1

Slide 60

Slide 60 text

Lost Update Anomaly

Slide 61

Slide 61 text

分散システムのテスト困難性 ● マルチプロセスの問題 ○ 動作する順番の全組み合わせを考える必要がある ● 故障の問題 ○ 個々の Node の動作にもランダム性がある ● ネットワークの問題 ○ 通信は遅延・消失し、順番も保存されない

Slide 62

Slide 62 text

理論的・体系的にバグを発見したい

Slide 63

Slide 63 text

形式手法 Formal Methods 形式手法

Slide 64

Slide 64 text

形式手法とは ● システムを数学的対象により表現 ○ その対象が満たす理論に基づいて検証 ● エンドユーザ視点のメリット ○ システムの挙動や仕様を曖昧さなく表現できる ○ ケースの抜けや漏れが原理的に生じない ○ 実装ではなく仕様・設計に対して検査できる

Slide 65

Slide 65 text

https://lamport.azurewebsites.net/tla/tla.html

Slide 66

Slide 66 text

TLA+ の特徴 ● モデル検査ツールとして使われることが多い ○ IDE (TLA Toolbox) とセットで配布 ○ Lamport (Paxos の人) が中心となって開発 ○ Temporal Logic of Actions と呼ばれる論理が基盤 ● システムを状態遷移系として表現 ○ 擬似プログラミング言語 PlusCal から生成可能

Slide 67

Slide 67 text

TLA+ は実証的な事例が豊富

Slide 68

Slide 68 text

CloudNative 界隈の TLA+ 人気 ● AWS DynamoDB / S3 ● Elasticsearch ● Cosmos DB ● TiDB ● FINAL FANTASY XV POCKET EDITION ○ DynamoDB の結果整合性が問題にならないか検証

Slide 69

Slide 69 text

そして CockroachDB でも採用 形式手法ツール TLA+ により「証明」済 https://qconnewyork.com/ny2019/presentation/cockroachdb-architecture-geo-distributed-sql-database

Slide 70

Slide 70 text

TLA+ による「いいね!」の検証

Slide 71

Slide 71 text

process user \in { "alice", "bob" } variables x = 0; begin Get: x := like; Incr: x := x + 1; Put: like := x; Ack: acked_users := acked_users + 1 end process; CountOK == acked_users = 2 => like = 2

Slide 72

Slide 72 text

process user \in { "alice", "bob" } variables x = 0; begin Get: x := like; Incr: x := x + 1; Put: like := x; Ack: acked_users := acked_users + 1 end process; CountOK == acked_users = 2 => like = 2 プロセス alice と bob が並行に動く

Slide 73

Slide 73 text

process user \in { "alice", "bob" } variables x = 0; begin Get: x := like; Incr: x := x + 1; Put: like := x; Ack: acked_users := acked_users + 1 end process; CountOK == acked_users = 2 => like = 2 ラベルが一つの実行ステップを表し その間では他プロセスの割り込みが入る

Slide 74

Slide 74 text

process user \in { "alice", "bob" } variables x = 0; begin Get: x := like; Incr: x := x + 1; Put: like := x; Ack: acked_users := acked_users + 1 end process; CountOK == acked_users = 2 => like = 2 検査したい条件

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

No content

Slide 77

Slide 77 text

No content

Slide 78

Slide 78 text

第 2 章のまとめ ● 分散システムをテストするのは難しい ○ タイミングに依存したバグの再現性 ● TLA+ による問題の発見 ○ 状態遷移系を網羅的に探索して条件を確認 ● TLA+ が使用された事例 ○ CockroachDB、Cosmos DB、TiDB など

Slide 79

Slide 79 text

Parallel Commit を学ぶ 3. How Does the Protocol Reduce the Latencies?

Slide 80

Slide 80 text

合意のレイテンシを 1 回分に抑えたい

Slide 81

Slide 81 text

Parallel Commit 1. データと Transaction Record を並列で書き込み 2. ただしこの時点での Record の状態は Staging とし、 トランザクションに属するキーのリストも付ける 3. データと Record が合意して戻ってきたら クライアントにトランザクション完了通知を出す 4. 最後に Record の状態を Committed に変更

Slide 82

Slide 82 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2

Slide 83

Slide 83 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2 Round-1 Consensus

Slide 84

Slide 84 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2 Round-1 Consensus

Slide 85

Slide 85 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = committed : k1, k2 Round-2 Consensus

Slide 86

Slide 86 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = committed : k1, k2 Round-2 Consensus

Slide 87

Slide 87 text

結局、合意 2 回分が必要なのでは

Slide 88

Slide 88 text

Transaction Recovery 1. Intent を発見したら Transaction Record を確認 2. その Record が Staging だった場合、リストされている キーについて Intent が書き込み成功かどうか確認 3. 全キーが OK なら Record を Committed に変更 4. まだ書き込まれていないキーを見つけた場合は Conflict と判断して Record を Aborted に変更

Slide 89

Slide 89 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2

Slide 90

Slide 90 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2

Slide 91

Slide 91 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2

Slide 92

Slide 92 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = staging : k1, k2 v1’ + v2’

Slide 93

Slide 93 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) k2 = v2’ (t1) t1 = committed : k1, k2

Slide 94

Slide 94 text

トランザクション途中だった場合

Slide 95

Slide 95 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) t1 = staging : k1, k2

Slide 96

Slide 96 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) t1 = staging : k1, k2

Slide 97

Slide 97 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) t1 = staging : k1, k2

Slide 98

Slide 98 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) t1 = staging : k1, k2 (No k2 intent)

Slide 99

Slide 99 text

Range 2 Range 3 Range 1 k1 = v1 k2 = v2 Client 1 Client 2 k1 = v1’ (t1) t1 = aborted : k1, k2 v1 + v2

Slide 100

Slide 100 text

TLA+ ではどう表現できるのか?

Slide 101

Slide 101 text

コミット状態の再定式化 ● 暗黙的コミット済み状態(読み取り可能状態) ○ Transaction Record が Staging 状態 ○ かつ全てのキーについて Intent が書き込み成功 ● 明示的コミット済み状態 ○ Transaction Record が Committed 状態 ○ Parallel Commit 導入前と同じ、安全側の条件

Slide 102

Slide 102 text

ImplicitlyCommitted == /\ record.status = "staging" /\ \A k \in KEYS: /\ intent_writes[k].epoch = record.epoch /\ intent_writes[k].ts <= record.ts ExplicitlyCommitted == Record.status = "committed"

Slide 103

Slide 103 text

ImplicitlyCommitted == /\ record.status = "staging" /\ \A k \in KEYS: /\ intent_writes[k].epoch = record.epoch /\ intent_writes[k].ts <= record.ts ExplicitlyCommitted == Record.status = "committed" 任意の key ∈ KEYS に対し

Slide 104

Slide 104 text

保証したい性質 ● トランザクション完了通知の正しさ ○ 完了通知の際は必ずコミット済みである ○ ただし暗黙的コミット済みの段階で構わない ● 暗黙的コミット済み状態の妥当性 ○ 暗黙的にコミットされればいずれ明示的にもされる ○ 仮に Node が故障した場合であっても保証したい

Slide 105

Slide 105 text

安全性と活性 ● 安全性 (Safety) ○ 何か悪いことが「起こらない」ことを要求 ○ 実行中、常に有効なアサーションのようなもの ● 活性 (Liveness) ○ 何か良いことがいつかは「起こる」ことを要求 ○ 何もしないシステムは無意味なので検証には必須

Slide 106

Slide 106 text

A A A A が成り立つ: いつか A が成り立つ:

Slide 107

Slide 107 text

A A A A が成り立つ:個々の状態に対する条件 いつか A が成り立つ: True True False False

Slide 108

Slide 108 text

A A A A が成り立つ:個々の状態に対する条件 いつか A が成り立つ:状態の「列」に対する条件 True False True True False False

Slide 109

Slide 109 text

普通の条件式では表現できない

Slide 110

Slide 110 text

時相論理 (Temporal Logic) ● 通常の論理式に以下の記号を追加した体系 ○ □A:現在の状態から先では常に A が真 ○ ◇A:現在の状態から A が真になるルートが存在 ● 状態の「列」に対して真偽が決まる ○ 一連の実行の様子に対して条件を定義できる ○ 真偽の与え方は CTL、LTL などいくつか存在

Slide 111

Slide 111 text

A □A:現時点以降、常に A が成り立つ ◇A:現時点以降、いつかは A が成り立つ A A A A A

Slide 112

Slide 112 text

A □A:現時点以降、常に A が成り立つ ◇A:現時点以降、いつかは A が成り立つ A A A A A False True

Slide 113

Slide 113 text

A □A:現時点以降、常に A が成り立つ ◇A:現時点以降、いつかは A が成り立つ True False A A A A A False True

Slide 114

Slide 114 text

AckImpliesCommit == commit_ack => ImplicitlyCommitted \/ ExplicitlyCommitted ImplicitCommitLeadsToExplicitCommit == ImplicitlyCommitted ~> ExplicitlyCommitted AckLeadsToExplicitCommit == commit_ack ~> ExplicitlyCommitted

Slide 115

Slide 115 text

AckImpliesCommit == commit_ack => ImplicitlyCommitted \/ ExplicitlyCommitted ImplicitCommitLeadsToExplicitCommit == ImplicitlyCommitted ~> ExplicitlyCommitted AckLeadsToExplicitCommit == commit_ack ~> ExplicitlyCommitted 安全性

Slide 116

Slide 116 text

AckImpliesCommit == commit_ack => ImplicitlyCommitted \/ ExplicitlyCommitted ImplicitCommitLeadsToExplicitCommit == ImplicitlyCommitted ~> ExplicitlyCommitted AckLeadsToExplicitCommit == commit_ack ~> ExplicitlyCommitted 活性

Slide 117

Slide 117 text

AckImpliesCommit == commit_ack => ImplicitlyCommitted \/ ExplicitlyCommitted ImplicitCommitLeadsToExplicitCommit == ImplicitlyCommitted ~> ExplicitlyCommitted AckLeadsToExplicitCommit == commit_ack ~> ExplicitlyCommitted A ~> B (lead to) 一度 A が成立すると その後いつか B も成立

Slide 118

Slide 118 text

AckImpliesCommit == commit_ack => ImplicitlyCommitted \/ ExplicitlyCommitted ImplicitCommitLeadsToExplicitCommit == ImplicitlyCommitted ~> ExplicitlyCommitted AckLeadsToExplicitCommit == commit_ack ~> ExplicitlyCommitted A ~> B == A => <>B

Slide 119

Slide 119 text

Node の故障をどう表現するか?

Slide 120

Slide 120 text

プロセスの公平性 ● 公平性なし(TLA+ のデフォルト) ○ まったく動かない可能性がある ● 弱い公平性の仮定(fair をつけた場合) ○ 常に動ける状態ならいつか必ず動く ● 強い公平性の仮定 ○ 動ける瞬間が無限回来るならいつか必ず動く

Slide 121

Slide 121 text

process committer = "committer" begin ... end process; fair process preventer \in PREVENTER begin ... end process;

Slide 122

Slide 122 text

process committer = "committer" begin ... end process; fair process preventer \in PREVENTER begin ... end process; トランザクションの持ち主のプロセスが 任意のタイミングで Stall する分岐を生成

Slide 123

Slide 123 text

process committer = "committer" begin ... end process; fair process preventer \in PREVENTER begin ... end process; それ以外のプロセスは、動ける状況が続けば 必ずどこかのタイミングでは動く

Slide 124

Slide 124 text

通信の遅延・消失をどう表現するか?

Slide 125

Slide 125 text

PipelineWrites: while to_write /= {} do with key \in to_write do to_write := to_write \ {key}; ... end with; end while;

Slide 126

Slide 126 text

PipelineWrites: while to_write /= {} do with key \in to_write do to_write := to_write \ {key}; ... end with; end while; Key を一つ取り出す際、 すべての「取り出し方」を 網羅して分岐を生成

Slide 127

Slide 127 text

... either Intent_writes[k] := [ epoch |-> txn_epoch, ts |-> txn_ts, resolved |-> FALSE ]; or skip; end either; ...

Slide 128

Slide 128 text

... either Intent_writes[k] := [ epoch |-> txn_epoch, ts |-> txn_ts, resolved |-> FALSE ]; or skip; end either; ... 二つのパターンのうち どちらが選ばれるかを両方考えて 分岐を生成

Slide 129

Slide 129 text

... either Intent_writes[k] := [ epoch |-> txn_epoch, ts |-> txn_ts, resolved |-> FALSE ]; or skip; end either; ... 書き込みが成功したパターン

Slide 130

Slide 130 text

... either Intent_writes[k] := [ epoch |-> txn_epoch, ts |-> txn_ts, resolved |-> FALSE ]; or skip; end either; ... 書き込みが失敗したパターン

Slide 131

Slide 131 text

ランダム性を網羅性に ● 分散システムに特有な非決定的な動作の扱い ○ 通信の失敗:成功・失敗でランダムに分岐 ○ 通信の非順序性:値をランダムに取り出す ● E2E テストと違い、実際に実行するわけではない ○ 全ての可能性を考慮して状態遷移を分岐させる ○ 起こりうる全てのランダム性が考慮できる

Slide 132

Slide 132 text

第 3 章のまとめ ● Parallel Commits のプロトコル ○ Staging 状態の導入と Transaction Recovery ● 時相論理式の導入 ○ 時間的な幅を持った実行列に関する仕様を検証 ● ランダム実行ではなく分岐の網羅 ○ 障害の際にもプロトコルが正しく動くかを検証

Slide 133

Slide 133 text

本日のまとめ 4. Wrap Up the Session!

Slide 134

Slide 134 text

本日のまとめ ● CockroachDB と Parallel Commit ○ 一貫性を保ったままパフォーマンスを改善したい ● 分散システムのテスト困難性 ○ 動作順・故障・通信のランダムネス ● 形式手法を利用したシステムの記述や検証 ○ より厳密な仕様の理解と膨大なパターン網羅

Slide 135

Slide 135 text

We found that the process of writing this specification gave us more confidence in the Parallel Commit protocol itself and in its integration into CockroachDB. Parallel Commits: An Atomic Commit Protocol For Globally Distributed Transactions https://www.cockroachlabs.com/blog/parallel-commits/

Slide 136

Slide 136 text

Have a Nice Formalism! Presented by チェシャ猫 (@y_taka_23)