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
CRDTs - The science behind Phoenix Presence
Search
Maciej Kaszubowski
May 25, 2017
Programming
2
230
CRDTs - The science behind Phoenix Presence
Maciej Kaszubowski
May 25, 2017
Tweet
Share
More Decks by Maciej Kaszubowski
See All by Maciej Kaszubowski
Error-free Elixir
mkaszubowski
0
180
Modular Design in Elixir (ElixirConf EU 2019)
mkaszubowski
2
500
The Big Ball of Nouns
mkaszubowski
0
85
Modular Design in Elixir
mkaszubowski
1
290
Our three years with Elixir
mkaszubowski
0
170
Concurrency Basics for Elixir
mkaszubowski
0
89
Distributed Elixir
mkaszubowski
0
84
Software Architecture
mkaszubowski
0
99
Let it crash - fault tolerance in Elixir/OTP
mkaszubowski
0
300
Other Decks in Programming
See All in Programming
Documentation testsの恩恵 / Documentation testing benefits
ssssota
1
560
Effectで作る堅牢でスケーラブルなAPIゲートウェイ / Robust and Scalable API Gateway Built on Effect
yasaichi
7
1.2k
Ruby on Fails - effective error handling with Rails conventions
talyssonoc
0
300
2024 コーディング研修
ckazu
2
650
TypeScriptのパフォーマンス改善
yajihum
14
5k
Powerfully Typed TypeScript
euxn23
3
1.5k
Docker_OSS_ホスティング入門
satokoki645
0
140
otelcol receiver 自作RTA / Pepabo Tech Conference #22 春のSREまつり
arthur1
0
830
Revisiting the Hotwire Landscape after Turbo 8 @ RailsConf 2024, Detroit
marcoroth
3
610
『WordPressコミュニティで学ぶ』OSS貢献の多様性
ippey
0
220
The Cutting Edge Of Versioning (LambdaConf 2024)
chriskrycho
0
250
Open AI APIを使う前に知っておきたいアカウントTier の話
akki_megane
0
130
Featured
See All Featured
Web development in the modern age
philhawksworth
203
10k
Practical Orchestrator
shlominoach
183
9.8k
Designing for humans not robots
tammielis
247
25k
Infographics Made Easy
chrislema
238
18k
For a Future-Friendly Web
brad_frost
172
9k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
20
1.8k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
34
6.1k
Raft: Consensus for Rubyists
vanstee
133
6.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
1
120
A Philosophy of Restraint
colly
197
16k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
22
1.4k
The MySQL Ecosystem @ GitHub 2015
samlambert
244
12k
Transcript
The Problem
None
Server Node 1 Server Node 2
Node A Node B [User] [User] [User] [] [] [User]
User connects User disconnects
There's no global time
Node A Node B [User] [User] [User] [] [] [User]
User connects User disconnects
Node A Node B [User] [User] [User] [] [] [User]
User connects User disconnects
Node A Node B
P.track(self, "users", "U1", %{})
P.track(self, "users", "U1", %{}) P.list("users") %{"U1" %{metas: [%{phx_ref: "…"}]}}
P.track(self, "users", "U1", %{}) P.list("users") P.track(self, "users", "U2", %{}) %{"U1"
%{metas: [%{phx_ref: "…"}]}}
P.track(self, "users", "U1", %{}) P.list("users") P.track(self, "users", "U2", %{}) P.list("users")
%{"U1" %{metas: [%{phx_ref: "…"}]}, "U2" %{metas: [%{phx_ref: "…"}]}} %{"U1" %{metas: [%{phx_ref: "…"}]}}
P.track(self, "users", "U1", %{}) P.list("users") P.track(self, "users", "U2", %{}) P.list("users")
%{"U1" %{metas: [%{phx_ref: "…"}]}, "U2" %{metas: [%{phx_ref: "…"}]}} P.track(self, "users", "U1", %{}) P.untrack(self, "users", "U1") %{"U1" %{metas: [%{phx_ref: "…"}]}}
P.track(self, "users", "U1", %{}) P.list("users") P.track(self, "users", "U2", %{}) P.list("users")
%{"U1" %{metas: [%{phx_ref: "…"}]}, "U2" %{metas: [%{phx_ref: "…"}]}} P.track(self, "users", "U1", %{}) P.untrack(self, "users", "U1") P.list("users") %{"U1" %{metas: [%{phx_ref: "…"}]}, "U2" %{metas: [%{phx_ref: "…"}]}} P.list("users") %{"U1" %{metas: [%{phx_ref: "…"}]}, "U2" %{metas: [%{phx_ref: "…"}]}} %{"U1" %{metas: [%{phx_ref: "…"}]}}
CRDTs The science behind Phoenix Presence Maciej Kaszubowski
Conflict-free Replicated Data Type
Alternatives
• Single source of truth (DB) • Consensus algorithm •
Resolving conflicts manually
Why CRDTs?
Eventually consistent Highly available Easy to use
Eventually consistent Highly available Easy to use Hard to create
:(
Features
1. Commutative 2. Associative 3. Idempotent x y = y
x (x y) z = x (y z) x x = x
Server Node 1 Server Node 2 Server Node 3
Client Client Client Client Client Client Client Client Client Server
Examples
Counters
Node A Node B +5 5 8 -2 3 +5
User connects User disconnects 0 0 5 3 8
Node A Node B +5 5 8 -2 8 +5
User connects User disconnects 0 0 5 3 13 10
G-Counter Grow-only counter
Node 2: 3 Value=8 Node 1: 5 Node 3: 1
Merge
Node 2: 3 Value=9 Node 1: 6 Node 3: 1
+1 Merge
PN-Counter Positive-Negative Counter
Node 2: P=2 N=2 Value=7 Node 1: P=5 N=2 Node
3: P=4 N=0 3 0 4 Merge
Node 2: P=2 N=2 Value=6 Node 1: P=5 N=3 Node
3: P=4 N=0 2 0 4 +1 Merge
Node 2: P=2 N=2 Value=8 Node 1: P=5 N=3 Node
3: P=6 N=0 2 0 6 +2 +1 Merge
Sets
Node A Node B [User] [User] [User] [] [] [User]
User connects User disconnects
G-Set Grow-only set
Node 2: [1,2] Value=[1,2,3,4] Node 1: [1] Node 3: [3,4]
Merge
Node 2: [1,2] Value=[1,2,3,4,5] Node 1: [1,5] Node 3: [3,4]
Merge
2P-Set Two-phase set
Node 2: [1,2],[] Value=[1,2,3,4] Node 1: [1],[] Node 3: [3,4],[]
Merge
Node 2: [1,2],[] Value=[1,2,3,4] Node 1: [1],[] Node 3: [3,4],[]
Merge G-Set for adds
Node 2: [1,2],[] Value=[1,2,4] Node 1: [1],[] Node 3: [3,4],[3]
Merge G-Set for removals
Elements cannot be re-added
Removes win
Node A Node B [ ] Add Remove [1] [
] [1]
Node A Node B [ ] [1] Add Remove [1]
[1] [ ] [1] [ ] [1]
Node A Node B [ ] [1] Add Remove [1]
[1] [ ] [1] [ ] [1]
Node A Node B [ ] [1] [1] Add Remove
[1] [1] [1] [ ] [1] [1] [1] [ ] [1]
OR-Set Observed-remove set
Node A Node B [ ] Add Remove [{A,1}] [
] [{A,1}]
Node A Node B [ ] [ ] Add Remove
[{A,1}] [{A,1}] [ ] [ ] [{A,1}] [{A,1}, ]
Node A Node B [ ] [ 1 ] Add
Remove [{A,1}] [{A,1}] [ ] [ ] [{A,1}] [{A,1},{A,2}]
Node A Node B [ ] [ 1 ] Add
Remove [{A,1}] [{A,1}] [ ] [ ] [{A,1}] [{A,1},{A,2}]
Node A Node B [ ] [ 1 ] Add
Remove [{A,1}] [{A,1}] [ ] [ ] [{A,1}] [{A,1},{A,2}] [ 1 ] [{A,1},{A,2}] [{A,1},{A,2}] [ 1 ]
Node A Node B [ ] [ 1 ] Add
Remove [{A,1}] [{A,1}] [ ] [ ] [{A,1}] [{A,1},{A,2}] [ 1 ] [{A,1},{A,2}] [{A,1},{A,2}] [ 1 ] [A] [A]
Add 1000 Remove 1000 Add Remove …
ORSWOT Observed-remove set without tombstones
None
None
Use Cases
None
None
None
None
• Load balancing / routing • Mobile clients synchronisation •
Temporary data on the servers • Avoiding work duplication • Collaborative editing
None
lasp-lang.readme.io
Summary
You're (almost) always designing a distributed system
Think about failures
Choose the correct tool for the job
References • https://medium.com/@istanbul_techie/a-look-at-conflict-free-replicated-data- types-crdt-221a5f629e7e • http://basho.com/posts/technical/distributed-data-types-riak-2-0/ • http://highscalability.com/blog/2014/10/13/how-league-of-legends-scaled- chat-to-70-million-players-it-t.html •
https://hal.inria.fr/inria-00609399v1/document • https://developers.soundcloud.com/blog/roshi-a-crdt-system-for- timestamped-events
Thanks!