lamassu / merrimack

An event store with a REST API for FoundationDB
The Unlicense
1 stars 3 forks source link

Global counter conflict resolution #1

Open joshmh opened 9 years ago

joshmh commented 9 years ago

Currently, Merrimack is not designed for more than ~100 incoming messages per second. In order to remove this limitation, we need to limit global counter incrementation. Here's an idea:

joshmh commented 9 years ago

Improved periodic global counter increment logic in a client could work as follows:

Trigger maintainCounter every k milliseconds, where a reasonable value would be 20ms.

function maintainCounter() {
  if (noNewRecordsSinceLastCheck) return;
  if (localCounter % n === 0 && noRecordsWithCurrentGlobalCounter())
    incrementGlobalCounter();
  localCounter++;
}
joshmh commented 9 years ago

The problem with maintainCounter is that it's sensitive to event traffic patterns, which could change abruptly. Instead it should be dependent on number of clients connected, which shouldn't change abruptly. The solution is for maintainCounter to have its own mLocalCounter and backoff regime.

function maintainCounter() {
  if (noNewLocalRecordsSinceLastCheck) return;
  if (mcLocalCounter % mcn === 0 && noRecordsWithCurrentGlobalCounter())
    incrementGlobalCounter();
  if (conflictDetected) mcn <<= 1;
  if (mcLocalCounter % 100 === 0 && mcn > 1) mcn >>= 1;
  mcLocalCounter++;
}

For simplicity, we can dispense entirely with globalCounter incrementing while publishing, and therefore with backoff managing for publishing. Then, consuming latency will depend entirely on maintainCounter.

joshmh commented 9 years ago

See also: http://community.foundationdb.com/questions/3221/message-store-pubsub-signalr-scaleout-layer.html