I've started looking at approaches to data synchronisation among a set of peers. The peers must be able to work in a disconnected way and then synchronise together to merge their local changes.
Peers should be able to merge local updates with a "three way merge". So, at synchronisation peers should know which facts are more recent, but where there is no strict ordering, they should be able to merge together the facts based on the common root.
When independent peers make changes, they can "time stamp" them with a "clock". I use the term "clock" and "time stamp" but I'm not meaning a wall time clock. I mean some kind of partial ordering of events which makes causality clear. It's the "happened before" relationship among events that forms a directed acyclic graph (DAG).
It seems like the "usual" way to do build this partial ordering is by using a vector clock. These can become very large, however. More recent developments such as interval tree clocks provide more compact storage of time stamps.
What I'm not at all clear about is why synchronisation protocols apparently don't "simply" store the DAG explicitly. (Or do they?)
Peers can independently create a time stamp by randomly generating a UUID (or by other means, such as
<peer-name> + <local-monotonically-increasing-counter>). The ordering of this time stamp is entirely clear to that peer.
When 2 peers sync to each other, they can agree on a new time stamp. Again, the ordering of this time stamp is clear to both peers.
There is now a requirement to pass the happened before DAG between peers, but the storage and bandwidth requirements of this are small. Time points are graph vertexes. As such they have 1 or 2 incoming edges (1 for an event on a client and 2 for a sync between clients). This is bounded and independent of the number of peers in the network.
To use an individual time point, you require the graph of time points that lead in to this. However, as far as I can see, any peer that is able to know of a time point (it has generated it itself, or generated it with another peer, or has been told it by another peer when synchronising with it) has also had an opportunity to know about the history leading up to that time point. I think there's probably an inductive proof for this.
Given that storing and synching the DAG explicitly seems simple: is this used in practice? If not, why are vector clocks preferred?
Peer to peer
I'd prefer to a peer to peer solution over a client server solution.
The likely end topology will be many clients connecting to a much smaller group of servers that replicate among themselves. However, it'd be nice to have a general solution that supported this particular topology rather than a solution that requires this specific topology.