Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eventualy consistent distributed database with idempotent increase operator?

Is there a distributed high availability, eventually consistent db that supports idempotent operation on scalar values?

If we use normal updates then there is a possibility that we will have 2 different values on different nodes and none of the values would be correct because we need to increase amounts by both transaction values.

Is there a distributed db where I can send a command increase(key, attribute[column], diff) so that when I receive a response I can be sure that that operation will be executed on other replicas regardless of the current value of the account? In that way I will have eventual consistency for increase operation even if 2 different nodes are increased by a different value because that increase would propagate to other replicas.

I am not talking about conditional updates as it would not work on high availability db like cassandra (that's why they don't have that feature), I am interested in atomic increase operation.

Thanks.

P.S. In the case of idempotent increase I would have a command increase(key, attribute, diff, lock_key) so that db wouldn't do increase if it already received the same command with the same lock_key

tl;dr:

Is there a way to make a precise counter in distributed AP kind database? 2 problems: 1) If I send operation to increase a counter and I don't get response I would send that request again but do not want to increase the counter twice. 2) If that counter is updated in the same time on another replica I would like to eventually combine this increases, not to overwrite the values. So is there a command like increase("John's balance", +5.67, "sdfsdfas") where sdfsdfas is a string used to discard duplicate update. Is there a db that replicates this kind of commands?

like image 738
user1944408 Avatar asked Nov 03 '22 07:11

user1944408


2 Answers

It seems to me that you are talking about two different things. Idempotence would mean that you can send several times the increase instruction but the counter would only be increased once. Atomicity does not make sense for a single operation (it makes sense for more than one, for example, increase the counter AND the date of increase atomically; either both get modified, or none does).

MongoDB supports atomic operations at the "document" level (which I'm not sure you need), but obviously an increment operator is not idempotent (by definition! How would you increase your counter otherwise?).

Can you clarify your question?

Also, you cannot have an "eventually consistent" database where all the nodes will have the same value of a given key at every time. That's why it is "eventually consistent", because it cannot guarantee that they are the same "right now".

As for an answer, if you want to use MongoDB for maintaining an increment operator, use the following pattern (from their website, example of the [$inc operator][1]):

db.collection.update( { age: 20 }, { $inc: { age: 1 } } );
db.collection.update( { name: "John" }, { $inc: { age: 1 } } );

In your case, it would be db.collection.update({$inc:{mycounter:1}});

like image 62
Escualo Avatar answered Nov 15 '22 05:11

Escualo


Ok, I see that problem 2 has been resolved in cassandra https://issues.apache.org/jira/browse/CASSANDRA-1072 Distributed counters will combine increase operations so everything will be consistent at the end.

Problem 1 (idempotency) is an open issue: https://issues.apache.org/jira/browse/CASSANDRA-4775

At least I know that people think about that, it is really important for my scenario so I will try to help resolving that issue.

I hope that this helps clarifying my question.

like image 31
user1944408 Avatar answered Nov 15 '22 05:11

user1944408