Skip to content

Commit

Permalink
Added leaderless replication write conflict example.
Browse files Browse the repository at this point in the history
  • Loading branch information
applebyter committed Apr 16, 2024
1 parent 8a20f64 commit 1e5b56e
Show file tree
Hide file tree
Showing 35 changed files with 196 additions and 23 deletions.
Binary file modified slides/distributed2/diagrams/Async.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/AsyncLag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/AvoidWriteConflict.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/FocusDB.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderFollower.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderFollowerSpread.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/Leaderless.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderlessCoordinator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderlessExampleBad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderlessExampleRead.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/LeaderlessExampleWrite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion slides/distributed2/diagrams/LeaderlessExampleWrite.puml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ note right of db3
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

Rel(client, db, "Rename Inflatable", $tags="browser")
Rel_D(client, db, "Rename Inflatable", $tags="browser")
Rel(client, db2, "Rename Inflatable", $tags="browser")

Lay_L(db2, db3)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions slides/distributed2/diagrams/LeaderlessExampleWriteConflict1.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
@startuml LeaderlessExampleWriteConflict1

left to right direction

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!include DEVICONS/laravel.puml
!include DEVICONS/javascript.puml
!include DEVICONS/mysql.puml
!include DEVICONS/chrome.puml

!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v11.1/dist
!includeurl AWSPuml/AWSCommon.puml
!includeurl AWSPuml/Database/RDS.puml
!includeurl AWSPuml/Compute/EC2.puml
!includeurl AWSPuml/Compute/EC2AutoScaling.puml
!includeurl AWSPuml/NetworkingContentDelivery/ElasticLoadBalancing.puml
!includeurl AWSPuml/Storage/SimpleStorageService.puml
' make orange
AddContainerTag("AWS", $borderColor="#ff9900", $bgColor="#ffffff", $fontColor="#000000")

AddContainerTag("browser", $bgColor="#bcddfc", $fontColor="#000000")
AddContainerTag("database", $bgColor="#ccfddd", $fontColor="#000000", $borderColor="#cccccc")

skinparam roundcorner 20
skinparam Padding 20
skinparam NoteBorderColor transparent
skinparam NoteBackgroundColor #FDDDCC
' skinparam NoteFontColor white

UpdateElementStyle(node, $borderColor="#cccccc", $fontColor="#5c5c5c")
UpdateElementStyle(container, $bgColor="#5388cb")

hide stereotype

Container(client1, "Customer", "")
Container(client2, "Fulfillment Centre", "")

ContainerDb(db, "Replica 1", "Container: Cassandra", $tags="database")
note right of db
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | 20 | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

ContainerDb(db2, "Replica 2", "Container: Cassandra", $tags="database")
note right of db2
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | 20 | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

ContainerDb(db3, "Replica 3", "Container: Cassandra", $tags="database")
note right of db3
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | 20 | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

Rel(client1, db2, "Query Product 1234", $tags="browser")
Rel_D(client1, db, "Query Product 1234", $tags="browser")

Lay_L(db2, db3)
Lay_U(db3, client2)

@enduml
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions slides/distributed2/diagrams/LeaderlessExampleWriteConflict2.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@startuml LeaderlessExampleWriteConflict2

left to right direction

!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml

!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!include DEVICONS/laravel.puml
!include DEVICONS/javascript.puml
!include DEVICONS/mysql.puml
!include DEVICONS/chrome.puml

!define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v11.1/dist
!includeurl AWSPuml/AWSCommon.puml
!includeurl AWSPuml/Database/RDS.puml
!includeurl AWSPuml/Compute/EC2.puml
!includeurl AWSPuml/Compute/EC2AutoScaling.puml
!includeurl AWSPuml/NetworkingContentDelivery/ElasticLoadBalancing.puml
!includeurl AWSPuml/Storage/SimpleStorageService.puml
' make orange
AddContainerTag("AWS", $borderColor="#ff9900", $bgColor="#ffffff", $fontColor="#000000")

AddContainerTag("browser", $bgColor="#bcddfc", $fontColor="#000000")
AddContainerTag("database", $bgColor="#ccfddd", $fontColor="#000000", $borderColor="#cccccc")

skinparam roundcorner 20
skinparam Padding 20
skinparam NoteBorderColor transparent
skinparam NoteBackgroundColor #FDDDCC
' skinparam NoteFontColor white

UpdateElementStyle(node, $borderColor="#cccccc", $fontColor="#5c5c5c")
UpdateElementStyle(container, $bgColor="#5388cb")

hide stereotype

Container(client1, "Customer", "")
Container(client2, "Fulfillment Centre", "")

ContainerDb(db, "Replica 1", "Container: Cassandra", $tags="database")
note right of db
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | 20 | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

ContainerDb(db2, "Replica 2", "Container: Cassandra", $tags="database")
note right of db2
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | <color:red>19</color> | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

ContainerDb(db3, "Replica 3", "Container: Cassandra", $tags="database")
note right of db3
|= product_id |= name |= stock |= price |
| 1234 | Nicholas Cage Reversable Pillow | 19 | $10.00 |
| 4321 | Lifelike Inflatable Elephant | 5 | $50.00 |
end note

' Rel_D(client1, db2, "Query Product 1234", $tags="browser")
' Rel_D(client1, db, "Query Product 1234", $tags="browser")

Rel_D(client2, db3, "Decrease Stock of Product 1234", $tags="browser")
Rel_D(client2, db2, "Decrease Stock of Product 1234", $tags="browser")

Rel_D(client1, db2, "Order 20 Items of 1234", $tags="browser")
Rel_D(client1, db, "Order 20 Items of 1234", $tags="browser")
Rel_U(db2, client1, "Error", $tags="browser")

Lay_L(db2, db3)

@enduml
Binary file modified slides/distributed2/diagrams/LeaderlessQuorum.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/MonotonicReads.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/MultiLeader.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/Partitioning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/PartitioningExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/PartitioningLB1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/PartitioningLB2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/PartitioningLB3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/ReadYourWrites.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/ReadYourWritesExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/Replication.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/ReplicationLag.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified slides/distributed2/diagrams/ResolveWriteConflict.png
Binary file modified slides/distributed2/diagrams/Sahara.png
Binary file modified slides/distributed2/diagrams/SaharaScaled.png
Binary file modified slides/distributed2/diagrams/Sync.png
Binary file modified slides/distributed2/diagrams/SyncVsAsync.png
Binary file modified slides/distributed2/diagrams/WriteConflict.png
77 changes: 55 additions & 22 deletions slides/distributed2/main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,13 @@
{braewebb}%
{}%
{}%
\note[item]<1->{Read user details.\vspace{1em}}

\only<2->{
\includegraphics[width=0.3\textwidth]{diagrams/ReadYourWrites}
}
\note[item]<2->{Decide I don't like my name.\vspace{1em}}
\note[item]<2->{Update name.\vspace{1em}}

\only<3->{
\tweet%
Expand All @@ -222,20 +225,16 @@
{}%
{}%
}
\note[item]<3->{Read user details.}

\end{center}
\end{frame}
\note[itemize]{
\item Read user details
\item Decide I don't like my name
\item Update name
\item Read user details
}

\image{diagrams/ReadYourWritesExample}
\note[itemize]{
\item Typical interaction in simple Leader-Follower replication.
\item Write is to \textit{leader}.
\item Read is from \textit{follower}.
\item Write is to \highlight{leader}.
\item Read is from \highlight{follower}.
\item \textit{Replication lag} means reading a field immediately after updating it \highlight{may} lead to reading \highlight{stale} data.
}

Expand All @@ -254,6 +253,7 @@
{My fist post}%
{}%
}
\note[item]<1->{Misspell a tweet.\vspace{1em}}

\only<2->{
\tweet%
Expand All @@ -263,6 +263,7 @@
{My first post}%
{}%
}
\note[item]<2->{Correct spelling, and I see my \textit{updated} tweet.\vspace{1em}}

\only<3->{
\tweet%
Expand All @@ -272,13 +273,9 @@
{My fist post}%
{}%
}
\note[item]<3->{Other users may still see \textit{stale}, misspelt post.}
\end{center}
\end{frame}
\note[enumerate]{
\item Misspell a tweet.
\item Correct spelling, and I see my \textit{updated} tweet.
\item Other users may still see \textit{stale}, misspelt post.
}

\image{diagrams/MonotonicReads}
\note[itemize]{
Expand All @@ -305,14 +302,20 @@
\point[Second approach]{Multi-leader Replication}

\image[height=\textheight]{diagrams/MultiLeader}
\note[itemize]{
\item Application can be partitioned to perform certain types of writes to a specific leader.
\item Reads are from replicas, as with Leader-Follower replication.
}

\point[Why multi-leader?]{
\vspace{1em}
\begin{itemize}[<+->]
\item If you have multiple leaders,
you can write to any,
allowing \highlight{writes to scale}.
you can write to any,
allowing \highlight{writes to scale}.
\vspace{1em}
\item A leader going down doesn't prevent writes,
giving \highlight{better fault-tolerance}.
giving \highlight{better fault-tolerance}.
\end{itemize}
}
\note[itemize]{
Expand All @@ -328,7 +331,7 @@
% }

\questionanswer{What might go wrong?}{Write conflicts}
\note{Write conflicts require the conflict to be resolved.}
\note{Conflict needs to be \highlight{resolved}.}

\image{diagrams/WriteConflict}
\note[enumerate]{
Expand All @@ -352,17 +355,20 @@
\item Custom resolution logic.
\end{itemize}
}
\note{Yes, this can be \highlight{challenging}.}

\image[height=\textheight]{diagrams/ResolveWriteConflict}

\point[Resolving Conflicts]{
\vspace{1em}
\begin{description}
\item[On Write] When a conflict is first noticed, take proactive resolution action.
\vspace{1em}
\item[On Read] When a conflict is next read, ask for a resolution.
\end{description}
}
\note[itemize]{
\item Bucardo allows a perl script for on write resolution.
\item Bucardo allows a perl script for on write resolution.\vspace{1em}
\item CouchDB prompts reads to resolve the conflict.
}

Expand Down Expand Up @@ -392,13 +398,11 @@
\point[How are changes propagated?]{
\begin{itemize}[<+->]
\item Read Repair
\note[item]<1->{Read Repair: Client detects stale data on read and writes updated data to that replica.\vspace{1em}}
\item Anti-Entropy Process
\note[item]<2>{Anti-Entropy Process: Background process looks for stale or missing data and updates replicas.}
\end{itemize}
}
\note[itemize]{
\item Read Repair: Client detects stale data on read and writes updated data to that replica.
\item Anti-Entropy Process: Background process looks for stale or missing data and updates replicas.
}

\question{How do we know it's consistent?}

Expand Down Expand Up @@ -457,6 +461,35 @@
\end{tikzpicture}
\end{center}
\end{frame}
\note[itemize]{
\item Graphical representation of previous equation. \vspace{3mm}
\item \textcolor{eq2}{\textbf{Orange}} inner group (\highlight{reads}), overlaps with \\
\textcolor{eq1}{\textbf{Blue}} inner group (\highlight{writes}). \vspace{3mm}
\item Showing how reads overlap writes via a quorum.
}

\questionanswer{What about write conflicts?}{Same problem as with Multi-leader replication.}

\image{diagrams/LeaderlessExampleWriteConflict1}
\note{
Same scenario as before:
\begin{enumerate}
\item Customer queries how many pillows are available.
\item Retrieves 20.
\end{enumerate}
}

\image{diagrams/LeaderlessExampleWriteConflict2}
\note{Same scenario as before:}
\note{
Same scenario as before:
\begin{enumerate}
\item Fulfilment centre finds faulty pillow and decreases inventory.
\item Customer orders 20 pillows, what they saw as the number available.
\item -1 Pillows?
\item How do we resolve this?
\end{enumerate}
}

\point[Summary]{
\begin{itemize}[<+->]
Expand Down

0 comments on commit 1e5b56e

Please sign in to comment.