Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CockroachDB から覗く形式手法の世界 #CNDT2020 / CloudNative Days Tokyo 2020

y_taka_23
September 09, 2020

CockroachDB から覗く形式手法の世界 #CNDT2020 / CloudNative Days Tokyo 2020

CloudNative Days Tokyo 2020 で使用したスライドです。

バグのない分散システムの設計は果たして可能でしょうか? この問いに対する一つの答えとして、CockroachDB では形式手法ツール TLA+ を用いて分散トランザクションの正しさを担保しています。 形式手法はシステムの挙動を数学的に解析する技法で、「ノードが特定のタイミングで故障した場合にのみ発生するバグ」といった再現困難な問題を確実に検出することができます。 本講演では、CockroachDB の事例を通して、形式手法が実世界で活用されている様子をお伝えします。

イベント概要:https://event.cloudnativedays.jp/cndt2020
ブログ記事:https://ccvanishing.hateblo.jp/entry/2020/09/10/044848

y_taka_23

September 09, 2020
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

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

    View Slide

  2. https://github.com/cockroachdb/cockroach

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  12. 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

    View Slide

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

    View Slide

  14. key value
    すべての Key-Value

    View Slide

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

    View Slide

  16. Node 2
    Distribution Layer
    Node 3
    Node 1
    Range 1
    Range 2
    Range 3

    View Slide

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

    View Slide

  18. Node 2
    Distribution Layer
    Node 3
    Node 1
    Range 1
    Range 2
    Range 3

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. 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

    View Slide

  23. 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  40. 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

    View Slide

  41. 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

    View Slide

  42. 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

    View Slide

  43. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  50. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  55. DB
    Alice
    Bob
    0
    0

    View Slide

  56. DB
    Alice
    Bob
    0
    0
    0
    0

    View Slide

  57. DB
    Alice
    Bob
    0
    1
    1
    0
    0
    0

    View Slide

  58. DB
    Alice
    Bob
    0
    1
    1
    0
    0
    0 1
    1

    View Slide

  59. DB
    Alice
    Bob
    0
    1
    1
    0
    0
    0 1
    1

    View Slide

  60. Lost Update Anomaly

    View Slide

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

    View Slide

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

    View Slide

  63. 形式手法
    Formal Methods
    形式手法

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  71. 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

    View Slide

  72. 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 が並行に動く

    View Slide

  73. 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
    ラベルが一つの実行ステップを表し
    その間では他プロセスの割り込みが入る

    View Slide

  74. 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 検査したい条件

    View Slide

  75. View Slide

  76. View Slide

  77. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  83. 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

    View Slide

  84. 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

    View Slide

  85. 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

    View Slide

  86. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  92. 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’

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  103. 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 に対し

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  135. 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/

    View Slide

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

    View Slide