Relational Reasoning for Mergeable Replicated Data Types
- 1
KC Sivaramakrishnan
joint work with
Gowtham Kaki, Swarn Priya, Suresh Jagannathan
Relational Reasoning for Mergeable Replicated Data Types KC - - PowerPoint PPT Presentation
Relational Reasoning for Mergeable Replicated Data Types KC Sivaramakrishnan joint work with Gowtham Kaki, Swarn Priya, Suresh Jagannathan 1 INTERNET INTERNET INTERNET INTERNET Serializability Linearizability Weak
joint work with
Gowtham Kaki, Swarn Priya, Suresh Jagannathan
INTERNET
INTERNET
INTERNET
INTERNET
4
5
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d end
5
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d end type counter_list = Counter.t list
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
INTERNET
Replicated Counter
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8
+1
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
24
*3
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
24 22
*3 +1
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
24 22
*3 +1 Diverges
8
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
24 22
*3 +1 Diverges
Addition and multiplication do not commute
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8
+1
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
22
+14
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
22 22
+14 +1
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
22 22
+14 +1 Converges
addition operation
9
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n end
7 8 21
+1 *3
22 22
+14 +1 Converges
addition operation
10
★ G-counters, PN-counters, OR-Sets, Graphs, Ropes, docs, sheets ★ Simple interface for the clients of CRDTs 10
★ G-counters, PN-counters, OR-Sets, Graphs, Ropes, docs, sheets ★ Simple interface for the clients of CRDTs
(commutativity)
★ Do not mirror sequential counter parts => implementation & proof
burden
★ Do not compose!
✦
counter set is not a composition of counter and set CRDTs
10
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8
+1
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
22
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
22 22
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
22 22
22 = 7 + (8-1) + (21 -7)
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
22 22
22 = 7 + (8-1) + (21 -7)
12
module Counter : sig type t val read : t -> int val add : t -> int -> t val sub : t -> int -> t val mult : t -> int -> t val merge : lca:t -> v1:t -> v2:t -> t end = struct type t = int let read x = x let add x d = x + d let sub x d = x - d let mult x n = x * n let merge ~lca ~v1 ~v2 = lca + (v1 - lca) + (v2 - lca) end
7 8 21
+1 *3
22 22
22 = 7 + (8-1) + (21 -7)
extend data-type
13
13
systems level concerns such as exactly once delivery
13
systems level concerns such as exactly once delivery
automatically
13
7 8 21
+1 *3
22 22
systems level concerns such as exactly once delivery
automatically
??
13
7 8 21
+1 *3
22 22
systems level concerns such as exactly once delivery
automatically
??
13
7 8 21
+1 *3
22 22 22
22 = 21 + (21-21) + (22 -21)
systems level concerns such as exactly once delivery
automatically
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2]
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2]
pop() 1
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2]
pop() 1 pop() 1
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ]
pop() 1 pop() 1 pop()
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
[1]
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
[1] [1,2]
push(2)
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
[1] [1,2] [1,3]
push(2) push(3)
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
[1] [1,2] [1,3] [1,2,3]
push(2) push(3) push(3)
15
module type Queue = sig type 'a t val push : 'a t -> 'a -> 'a t val pop : 'a t -> ('a * 'a t) option (* at-least once semantics *) end
[1,2] [2] [2] [ ] [ ]
pop() 1 pop() 1 pop() pop()
[1] [1,2] [1,3] [1,2,3] [1,3,2]
push(2) push(3) push(3) push(2)
16
★ How can we formalise the intent of operations on a data
structure?
16
★ How can we formalise the intent of operations on a data
structure?
16
l v1 v2 v
★ How can we formalise the intent of operations on a data
structure?
16
l v1 v2 v
★ How can we formalise the intent of operations on a data
structure?
16
l v1 v2 v
★ How can we formalise the intent of operations on a data
structure?
16
l v1 v2 v
★ How can we formalise the intent of operations on a data
structure?
16
l v1 v2 v
★ How can we formalise the intent of operations on a data
structure?
m, if those elements are present in v.
16
l v1 v2 v
17
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
17
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
17
l v1 v2 v
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
17
l v1 v2 v
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
1.Any element popped in either v1 or v2 does not remain in v
17
l v1 v2 v
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
1.Any element popped in either v1 or v2 does not remain in v
17
l v1 v2 v
★ Rmem [1,2,3] = {1,2,3} ★ Rob [1,2,3] = { (1,2), (1,3), (2,3) }
1.Any element popped in either v1 or v2 does not remain in v
17
l v1 v2 v
18
l v1 v2 v
18
l v1 v2 v
★ Consider l = [0], v1= [0,1], v2 = [ ], v = [1]
18
l v1 v2 v
★ Consider l = [0], v1= [0,1], v2 = [ ], v = [1]
insertions will only be present in Rob(v)
★ Consider l = [ ], v1= [0], v2 = [1], v = [0,1]
19
19
[1,2]
Rmem = {1,2} Rob = { (1,2) }
19
[1,2] [2]
pop() 1
Rmem = {1,2} Rob = { (1,2) } Rmem = {2} Rob = { }
19
[1,2] [2] [2]
pop() 1 pop() 1
Rmem = {1,2} Rob = { (1,2) } Rmem = {2} Rob = { } Rmem = {2} Rob = { }
19
[1,2] [2] [2] [2] [2]
pop() 1 pop() 1
Rmem = {1,2} Rob = { (1,2) } Rmem = {2} Rob = { } Rmem = {2} Rob = { } Rmem = {2} Rob = { } Rmem = {2} Rob = { }
20
20
[1]
Rmem = {1} Rob = { }
20
[1] [1,2]
push(2)
Rmem = {1} Rob = { } Rmem = {1,2} Rob = { (1,2) }
20
[1] [1,2] [1,3]
push(2) push(3)
Rmem = {1} Rob = { } Rmem = {1,2} Rob = { (1,2) } Rmem = {1,3} Rob = { (1,3) }
20
[1] [1,2] [1,3]
push(2) push(3)
Rmem = {1} Rob = { } Rmem = {1,2} Rob = { (1,2) } Rmem = {1,3} Rob = { (1,3) }
Use < as an arbitration function between concurrent insertions
20
[1] [1,2] [1,3] [1,2,3] [1,3,2]
push(2) push(3)
Rmem = {1} Rob = { } Rmem = {1,2} Rob = { (1,2) } Rmem = {1,3} Rob = { (1,3) } Rmem = {1,2,3} Rob = { (1,2), (1,3), (2,3) } Rmem = {1,2,3} Rob = { (1,2), (1,3). (2,3) }
Use < as an arbitration function between concurrent insertions
21
A sequence of relations RT is called a characteristic relation
x and y are extensionally equal as interpreted under T.
21
A sequence of relations RT is called a characteristic relation
x and y are extensionally equal as interpreted under T.
★ Ignore distribution when defining characteristic relations.
21
A sequence of relations RT is called a characteristic relation
x and y are extensionally equal as interpreted under T.
22
across data types
22
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
Abstraction function
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
Abstraction function Concretisation function
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
Abstraction function Concretisation function Synthesize (goal)
across data types
★ Can we synthesise merge functions for arbitrary data type? 22
Abstraction function Concretisation function
Directed synthesis using the type of the characteristic relations
Synthesize (goal)
23
23
23
23
23
24
24
24
25
25
26
27
constituents
27
constituents
27
constituents
merge spec is:
27
constituents
merge spec is:
27
28
28
28
28
28
the same merge specification can be used.
28
types as keys and mergeable types as values
29
30
30
★ Membership (Rmem) 30
R : {v : T} → P
★ Membership (Rmem) ★ Ordering (Rob, Rans, Rto)
✦
where 𝜍 is a sequence of non-mergeable types and other relations, which flattens to a sequence of non-mergeable types
30
R : {v : T} → P
R : {v : T} → P (ρ)
★ Membership (Rmem) ★ Ordering (Rob, Rans, Rto)
✦
where 𝜍 is a sequence of non-mergeable types and other relations, which flattens to a sequence of non-mergeable types
★ Ordinates (Rpair, Rkv) 30
R : {v : T} → P
R : {v : T} → P (ρ)
R : {v : T} → P
31
★ Data structures: Set, Heap, Graph, Queue, TreeDoc ★ Larger apps: TPC-C, TPC-E, Twissandra, Rubis
31
32
★ Quickly compute LCA ★ Optimise storage through sharing ★ Optimise network transmissions (state based merge)
32
★ Quickly compute LCA ★ Optimise storage through sharing ★ Optimise network transmissions (state based merge)
★ A reimplementation of Git in pure OCaml ★ Arbitrary OCaml objects, not just files + User-defined 3-way merges ★ Only transmit diffs over the network ★ Multiple storage backends including in-memory, filesystems, log-structured-
merge database, distributed databases
32
33
33
★ 2 Replicas, fixed number of rounds, each round has N operations ★ 75% inserts, 25% deletions ★ Synchronise after each round 33
★ 2 Replicas, fixed number of rounds, each round has N operations ★ 75% inserts, 25% deletions ★ Synchronise after each round 33
Binary Heap Growable Array
34