strls
Joined 10 years ago
Joined 10 years ago
On the other hand, if you are thinking of using bare VMs, then better go with managed K8s. I think in 2025 it's a draw in terms of initial setup complexity, but managed K8s doesn't require constant babysitting in my experience, unlike VMs, and you are not sinking hours into a bespoke throwaway setup.
They are conflict-free only because they hide conflicts by forcing a consistent order on concurrent updates. How do they do it? By using logical clocks to version events. A logical clock is not magic. It orders concurrent events arbitrarily. Is this correct? In practice, probably not, meaning that more recent updates can be lost in favor of less recent updates. What does 'recent' mean? For a user it means latest in physical time. Just because the system doesn't know any better than to arbitrarily order a pair of events (that appear concurrent), doesn't mean the user doesn't know which event comes first. This is why not everything is implemented as a CRDT and conflicts will always exist in use cases where updates must never be lost.
This is what is required to build an app where any instance (node) can be offline for an arbitrary amount of time, but still be able to share state with the rest of the nodes when it's reconnected.
To implement this, every application node keeps a vector clock per register (an atomic piece of shared state). The vector clock allows any node the compare its own version of the register with the state received from any other node. Two values of a vector clock can either be causally related (in which case the most recent write wins) or concurrent. However the concurrency is from the system's perspective, but not necessarily from the user's perspective. An extra physical timestamp can be kept at the register level to order concurrent updates in a way consistent with the user's time perception.
Now, having the hybrid clocks in place to version each register on each node, the system must implement a protocol to ship every register update to all nodes (reliable broadcast).
Once all updates are shipped to all nodes, it's guaranteed that all nodes have the same (most recent) state.
(I built an offline-first product and had to roll my own protocol)