Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do i do an atomic update with etcd

Tags:

etcd

raft

I am trying to understand what an 'atomic' update is in terms on etcd.

When I think 'atomic', I think there is a 'before' and an 'after' (there isn't a during, and if the update fails, it is still 'before').

Here is an example:

curl -s -XPUT http://localhost:2379/v2/keys/message -d value='Hidee Ho'

So, at this point, anyone can access that message and get the current value:

curl -s http://localhost:2379/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Hidee Ho","modifiedIndex":4748,"createdIndex":4748}}

Later on, I can modify this value, like this:

curl -s -XPUT http://localhost:2379/v2/keys/message -d value='Mr Hanky'

And the result can be fetched, just like before. Before my change the value 'Hidee Ho' comes back, after the change the value 'Mr Hanky' comes back. So, my question is am I guaranteed one or the other of the results? That is, I want to confirm that one or the other will be returned (and not a nil value between the result).

I don't particularly care about the timing. If I do the Mr Hanky update and subsequent fetchers of the value continue to get Hidee Ho for a (short) period of time, that's OK.

I am confused because there is an Atomic CompareAndSwap function in the protocol. As far as I can tell, it isn't so much Atomic as it is 'only do the update if the value is what I say it is'. In my case I don't much care what the value used to be. I just want to know that it is changed and that no readers will see anything other than the 'before' or 'after' values.

like image 515
Greg Avatar asked Feb 09 '23 20:02

Greg


1 Answers

You are correct in that a plain PUT is atomic in that a client will only see the previous value or the new value.

The CompareAndSwap feature allows you to do optimistic locking so that you can write new values which depend on the prior value, e.g. a counter. If you were to implement a counter without using CompareAndSwap, you'd have something like write("count", 1 + read("count")) , in this case the read and write are separate, if 2 callers did this at the same time, then its possible they'd both see the same starting value, and you'd loose one of the increments. using CAS the caller can say set it to 12 only if the previous value is 11, now if this happens concurrently, one of the writes will fail, and it can then re-read and reapply its delta, so that you don't loose any increments.

like image 76
superfell Avatar answered Mar 11 '23 18:03

superfell