A queue for each object keeps related operations in order and leaves unrelated ones in queues of their own.
A blocking queue gives total ordering: the object behind cannot be accessed before the first object is completed. A priority queue does not give causal ordering. Gaurav adds 10 rupees, a get from a premium account is served first, and it returns the old balance.
With total ordering only one server can pick at a time, the one which picked the head of the queue. So the queues are split:
- A queue for every object. Abhitej's operations go in one queue and Ash's in another, like topics in Kafka.
- One server for one document. The document ID is hashed and gives a server ID, so every operation on document 1 falls on S2 and is processed in order of arrival.
- A cost. If S2 goes down, D4 and D1 are not accessible.
Google went for globally ordered timestamps from Spanner instead. An atomic clock is necessary only for external consistency. Locally the clocks are always ordered.