Synchronization when updating KV store

We have a consul key across region/datacenter that needs to be updated when certain event happens. What is the best way to synchronize this update operation in kv store among various servers competing on that one consul key and allow only one server to perform that operation successfully? I am using java and consul client API.

I don’t get the question right… You want to watch a key and if the key is updated, you want to do something with Java? But only one of this Java apps should do the operation?

For watching for updates on keys, you can use watch:

There are several servers, in datacenter for e.g. dc1 watching a consul key(x/y/z) which is in dc2. In case of some type of event received by these servers in dc1, they are suppose to update the that particular consul key(x/y/z) in dc2 to some value which will trigger a corrective action to fix the issue that caused that event. In case when more than one server received such bad event at the same time and try to call this–>consul kv put -datacenter=dc2 x/y/z to set the consul key, I need some sort of synchronization among such servers so that only one server should succeed in setting the key(x/y/z) to let say value “true”. Thanks

serf maybe?

I wanted to achieve this programmatically using java code. The serf is not the solution at this time. Thanks for your time.

Are there any settings or is there a way that will allow watcher to execute handler only once if the value of key (x/y/z) changed by several competing servers to same value. So for e.g. if many servers update the key x/y/z to true and this key is being watched by several other servers then they should only execute external handler once and not many times. Thanks

Hi @rschuntigit,

Take a look at Consul Sessions. I believe they will provide the functionality you’re looking for. Please note this paragraph at the end of the K/V Integration section.

This locking system is purely advisory . There is no enforcement that clients must acquire a lock to perform any operation. Any client can read, write, and delete a key without owning the corresponding lock. It is not the goal of Consul to protect against misbehaving clients.

You will need to ensure that your applications are written to only update a key if they hold the lock, and not update a key if it has changed since they last read the value. The latter can be achieved by specifying the cas parameter in the KV update.

The following blog post provide a good walk through of this functionality.

http://alesnosek.com/blog/2017/07/25/check-and-set-operation-and-transactions-in-consul/

This is very helpful. Thank you

Hi, Once again thanks. I went through the blog post which is useful. This uses examples of curl command. Further question, I see that consul provides client java API. So which specific method/function from that API I can use to achieve this objective. I will be passing parameters such as 1) Consul key path and 2) Datacenter where the consul key exists and 3) may be cas=0? And that function should give me list of values which I can use for further processing. I tried to look at the git link https://github.com/rickfast/consul-client but could not locate such function so far. I appreciate if I can get help from that perspective. Thanks

Hi,

I’m not a Java programmer, and not familiar with that consul-client library. It was developed by the community, and is not official an official API client. However, I’ll try my best to help.

According to the docs putValue() docs from the KeyValueClient class it appears that you can pass in a series of query parameters in order to set things like cas, dc, etc. I found a small example of this being done in the KeyValue test code (consul-client/src/itest/java/com/orbitz/consul/KeyValueITest.java#L131). The full list of supported query parameters can be found in consul-client/src/main/java/com/orbitz/consul/option/PutOptions.java.

The other open source API client, Ecwid/consul-api, also seems to support providing a series of PutParams. I found this random GitHub repo, dyc87112/consul-distributed-lock, which contains an example of how to pass query params using this particular API client.

Hope this info helps.

I will check it. Thank you.