Advertisement
Guest User

Untitled

a guest
Feb 19th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.99 KB | None | 0 0
  1. # Operation conflation of Commutative Replicated Data Types
  2.  
  3. ## Intro to Commutative Replicated Data Types
  4.  
  5. Operation-based variant of CRDTs is based on idea, that instead of replicating the state (or its delta), we replicate the operations, and let the corresponding replica build eventually consistent state from operations only. A standardized API for such data types consist of several members:
  6.  
  7. - `initial`: empty instance of CRDT object.
  8. - `query`: returns a value out of the CRDT object.
  9. - `atSource`: which returns a serializable operation. I.e. for a given `Counter` CRDT, its `atSource` function could return operations like `inc(replicaId, delta)` or `dec(replicaId, delta)`.
  10. - `downstream` which is used to consume operations incoming from both local and remote sources to produce new state of the CRDT object.
  11.  
  12. This variant introduces some complexity on the replication protocol itself, as it needs to satisfy at least *reliable causal broadcast* properties. In many practical implementations this means, that we need to perform two kinds of I/O - not only network, but also disk persistence in order to achieve reliable delivery - before applying `downstream` function over incoming operations, produced by `atSource`.
  13.  
  14. ## An opportunity
  15.  
  16. Since at some point we need to broadcast operations to other replicas, usually living on different machines, it means, that we need some form I/O. A problem with I/O is that it's usually orders of magnitude slower than operations performed locally. Most production systems are reducing that cost by applying batching of messages.
  17.  
  18. For operation-based CRDTs it means that before calling `downstream` over incoming operation, we are supposed to already preserve that operation - it's an implicit requirement of providing exactly once delivery required by CmRDT replication protocol - which means involving I/O.
  19.  
  20. This creates a following opportunity: **could we conflate operations awaiting in the buffer, before performing I/O on it?**
  21.  
  22. Example: Imagine operation-based `Counter` implementation, which exposes two operations `inc(replicaId, delta)` and `dec(replicaId, delta)`. Now, we are serving operations incoming with high frequency - at a rate high enough, to require us to start buffering operations before performing I/O. Our buffer could look like this:
  23.  
  24. ```
  25. inc(A,1) -> inc(B,4) -> dec(A,3) -> inc(A,1)
  26. ```
  27.  
  28. **We could conflate those operations into a single equivalent in form of `dec(A,1) -> inc(B,4)`**, and send it over I/O instead. Moreover, we could even apply that replacement in a `downstream` operation and still end up with correct state. To do that, we need 2 things:
  29.  
  30. 1. A conflate operation: `op * op -> op` defined for CRDT's operations, that we want to conflate.
  31. 2. A buffer, that will allow us to perform fast lookups for buffered operations corresponding to the same object (or data type, as we potentially could conflate across multiple objects of the same type).
  32.  
  33. The funny part starts with 2nd point, as I still need to evaluate this one somehow so see if the whole idea has sense.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement