ZooKeeper_Node Data Version Number

Reposted from: Simba_cheng

Method for updating node data:

  • Synchronization method: Stat setData(final String path, byte data[], int version)
  • Asynchronous method: void setData(final String path, byte data[], int version, StatCallback cb, Object ctx)

Parameter description:

  • path: specify the path of the data node
  • data[]: a byte array, that is, the data needs to be overwritten The current data content of the node
  • version: Specify the data version of the node
  • cb: Register an asynchronous callback function
  • ctx: Object used to pass context information< /li>

Among them:

The version parameter is used to specify the data version of the node. The update operation of the table name is performed for the specified data version.

What is the point of specifying the data version update?

In layman’s terms, “CAS”: For the value V, before each update, it will be compared whether the value is the expected value A. Only when it meets the expected value will it be compared with the expected value A. Update V atomically to the new value B

CAS specific explanation
The version parameter in the setData interface of zookeeper is derived from CAS

each zookeeper Nodes have the concept of data version. When calling the update operation, you can add the parameter version, which can correspond to the “expected value” in the CAS

principle, indicating that it is for the data version Update.

Something to say:

If a client attempts to update, it will update with the version value obtained last time.

If during this period of time, the value of the node on the ZooKeeper server happens to have been updated by other clients, then the data version must also change,

So it must be It can’t match the version carried by the client, so it can’t be updated successfully – So it can effectively avoid some distributed update concurrency issues .

Demo code:

 1 public class TestSetData implements Watcher {
2
3 // barrier, counter
4 span> private static CountDownLatch downLatch = new< /span> CountDownLatch(1);
5
6 private static ZooKeeper zookeeper = null;
7
8 public static void main(String[] args) throws Exception {
9
10 zookeeper = new ZooKeeper("10.0.227.66:2181", 5000, new< /span> TestSetData());
11
12 System.out.println("zookeeper.getState()1: "+ zookeeper.getState());
13
14 try {
15 downLatch.await();< spa n style="color: #008000">//
Before the counter is reset to zero, all threads wait
16} catch (Exception e) {
17 e.printStackTrace();
18 }
19
< span style="color: #008080">20
System.out.println("zookeeper.getState()2: "+ zookeeper.getState());< br />21
22 zookeeper.create("/cyx ", "ccc".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
23
24 zookeeper.getData("/cyx", true, null);
25
< span style="color: #008080">26
// First time setting
27 Stat stat = zookeeper.setData("/cyx", "456".getBytes(), -1);
28 System.out.println(stat.getCzxid() + "," + stat.getMzxid( ) + "," + stat.getVersion());
29
30 // Second setting
31 Stat stat2 = zookeeper.setData("/cyx", "789".getBytes(), -1);
32 System.out.println(stat2.getCzxid() + "," + stat2 .getMzxid() + "," + stat 2.getVersion());
33
34 // Get the first setting to get the version, update it
35 try {
< span style="color: #008080">36
37 zookeeper.setData("/cyx", "123".getBytes(), stat.getVersion());
38
39} catch (Exception e) {
40 e.printStackTrace();
41 }
42
43 }
44
45 @Override
46 public void process(WatchedEvent event) {
47
48 System.out.println("receive watched event: "+ event);
49
50 < span style="color: #0000ff">if (KeeperState.SyncConnected == event.getState()) {
51
52 if ( EventType.None == event.getType() && null == event.getPath()) {
53 downLatch.countDown();// Counter-1
54 }
< /span>55 }
56 }
57 }

Output result:

zookeeper.getState()1: CONNECTING
receive watched event: WatchedEvent state:SyncConnected type:None path:
null
zookeeper .getState()
2: CONNECTED
receive watched event: WatchedEvent state:SyncConnected type:NodeDataChanged path:
/cyx
197568501464, 197568501465, 1
197568501464, 19 7568501466, 2
org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode
= BadVersion for /cyx

Code writing ideas:

  1. First create the node “/cyx” node and set the node parameter “ccc”
  2. Next we setData for the first time, update the node parameter to “456”, and get the stat at the same time, at this time the version has changed
  3. Then we setData again, and update the node parameter to “789” , While getting the stat, the version is also changed
  4. Next, we use the version number obtained the first time to setData.
  5. Then it throws an exception, because the version number has already been updated in the second setData. At this time, we update with the version number of the first update, which cannot be successful.

Explain the “-1” in setData:

In ZooKeeper, the data version starts counting from 0, so Strictly speaking, “-1” is not a legally obtained data version, it is just an identifier.

If the version parameter passed in by the client is “-1”, it tells the zookeeper server that the client needs to update based on the latest version of the data.

 1 public class TestSetData implements Watcher {
2
3 //< /span> Barrier, counter
4 private static CountDownLatch downLatch = new CountDownLatch(1);
5
6 span> private static ZooKeeper zookeeper = null< /span>;
7
8 public static void main(String[] args) throws Exception {
9
10 zookeeper = new ZooKeeper("10.0.227.66:2181", 5000, new TestSetData ());
11
12 System. out.println("zookeeper.getState()1: "+ zookeeper.getState());
13
14 try {
15 downLatch.await();// Before the counter is reset to zero, all threads wait
16} catch (Exception e) {
17 e.printStackTrace();
18 }
19
20 System.out.println("zookeeper.getState()2: "+ zookeeper.getState());
21
22 zookeeper.create("/cyx", "ccc".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
23
24 zookeeper.getData("/cyx", true, null);
25
26 span> // First time setting
27 Stat stat = zookeeper.setData("/cyx", "456".getBytes(), -1);
28 System.out.println(stat.getCzxid() + "," + stat.getMzxid() + "," + stat.getVersion());
29
30 // Second setting
31 Stat stat2 = zookeeper.setData("/cyx", "789".getBytes(), -1);
32 System.out.println(stat2.getCzxid() + "," + stat2.getMzxid() + "," + stat2.getVersion());
< span style="color: #008080">33

34 // Get the first setting to get the version and update it
35 try {
36 < br />37 zookeeper.setData("/cyx", "123".getBytes(), stat.getVersion ());
38
39} < span style="color: #0000ff">catch
(Exception e) {
40 e.printStackTrace();
41 }
42
43 span> }
44
45 @Override
46 public void< /span> process(WatchedEvent event) {
47
48 System.out.println("receive watched event: "+ event);
< span style="color: #008080">49

50 if (KeeperState.SyncConnected == event.getState()) {
51 < br />52 if (EventType.None == event.getType() && null == event.getPath()) {
53 downLatch.countDown();// counter-1
54 }
55 }
56 }
57 }

zookeeper.getState()1< span style="color: #000000">: CONNECTING
receive watched event: WatchedEvent state:SyncConnected type:None path:null< span style="color: #000000">
zookeeper.getState()2: CONNECTED
receive watched event: WatchedEvent state:SyncConnected type :NodeDataChanged path:
/cyx
197568501464, 197568501465, 1
197568501464, 197568501466, 2
org.apache.zookeeper.KeeperExcep tion$BadVersionException: KeeperErrorCode
= BadVersion for /cyx

Leave a Comment

Your email address will not be published.