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
300
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
420
Modular Design in Elixir (ElixirConf EU 2019)
mkaszubowski
2
900
The Big Ball of Nouns
mkaszubowski
0
120
Modular Design in Elixir
mkaszubowski
1
400
Our three years with Elixir
mkaszubowski
0
270
Concurrency Basics for Elixir
mkaszubowski
0
140
Distributed Elixir
mkaszubowski
0
180
Software Architecture
mkaszubowski
0
150
Let it crash - fault tolerance in Elixir/OTP
mkaszubowski
0
510
Other Decks in Programming
See All in Programming
ぼくの開発環境2026
yuzneri
0
250
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.6k
高速開発のためのコード整理術
sutetotanuki
1
410
AgentCoreとHuman in the Loop
har1101
5
250
プロダクトオーナーから見たSOC2 _SOC2ゆるミートアップ#2
kekekenta
0
230
並行開発のためのコードレビュー
miyukiw
0
1.2k
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
620
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
6
680
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
4k
開発者から情シスまで - 多様なユーザー層に届けるAPI提供戦略 / Postman API Night Okinawa 2026 Winter
tasshi
0
210
Featured
See All Featured
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
470
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
1
58
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.2k
RailsConf 2023
tenderlove
30
1.3k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
920
Balancing Empowerment & Direction
lara
5
900
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
170
Product Roadmaps are Hard
iamctodd
PRO
55
12k
What does AI have to do with Human Rights?
axbom
PRO
0
2k
A better future with KSS
kneath
240
18k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
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!