日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

读《分布式一致性原理》JAVA客户端API操作3

發布時間:2024/10/12 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读《分布式一致性原理》JAVA客户端API操作3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

更新數據

客戶端可以通過zookeeper的API來更新一個節點的數據內容,有如下兩個接口:

?

public Stat setData(final String path, byte data[], int version)public void setData(final String path, byte data[], int version,StatCallback cb, Object ctx)

?

更新數據的接口較為簡單明了。我們重點來看下方法中的version參數。version參數是指定節點的數據版本。表明本次更新是針對指定版本進行的。

《java并發編程實踐》一書提到,在現代的絕大數計算機處理器體系架構中,都實現了對CAS指令支持,

通俗的將,CAS的意思是“對于值V,每次更新都會對其值是否是值是否是預期值A,只有符合預期,才會將A原子化的更新為B”。zookeeper中setData接口中的version參數正是由CAS原理演化而來的。

具體來說,假如有個客戶端想要進行更新操作,那么肯定會攜帶上次獲取的version值進行更新。如果在這段時間,該數據恰好被其他客戶端更新了,那么其數據版本一定也發生了變化,因此肯定與客戶端攜帶的version無法匹配,于是便無法更新成功。可以有效的避免分布式更新的并發問題。

?

使用同步API更新節點數據內容

package setdata;import java.io.IOException; import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat;import getdata.GetData1;public class SetData1 implements Watcher {public static CountDownLatch connectedSemaphore = new CountDownLatch(1);private static ZooKeeper zk = null;private static Stat stat = new Stat();@Overridepublic void process(WatchedEvent event) {if (KeeperState.SyncConnected==event.getState()) {if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {connectedSemaphore.countDown();}}}public static void main(String[] args) throws IOException, InterruptedException, KeeperException {String path = "/zk-book";zk = new ZooKeeper("192.168.64.60:2181", 5000, new SetData1());connectedSemaphore.await();zk.create(path, "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);Stat stat2 = zk.setData(path, "456".getBytes(), -1);System.out.println(stat.getCzxid()+"---"+stat.getMzxid()+"--"+stat.getVersion());Thread.sleep(Integer.MAX_VALUE);;}}

?

在zookeeper中,數據版本都是從0開始的,所以嚴格來講-1并不是一個數據版本,它僅僅是一個

標示符,是告訴服務器對最新版本進行更新操作。如果對zookeeper數據節點的更新操作沒有原子性要求,那么就可以使用“-1”;

?

所以用異步的API更新數據內容

package getdata;import java.io.IOException; import java.util.concurrent.CountDownLatch;import org.apache.zookeeper.AsyncCallback; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooDefs.Ids;public class GetData2 implements Watcher {public static CountDownLatch connectedSemaphore = new CountDownLatch(1);private static ZooKeeper zk = null;private static Stat stat = new Stat();@Overridepublic void process(WatchedEvent event) {if (KeeperState.SyncConnected==event.getState()) {if (EventType.None.getIntValue()==event.getState().getIntValue()&&null==event.getPath()) {connectedSemaphore.countDown();}}}public static void main(String[] args) throws IOException, InterruptedException, KeeperException {String path = "/zk-book";zk = new ZooKeeper("192.168.64.60:2181", 5000, new GetData2());connectedSemaphore.await();zk.create(path, "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL );zk.setData(path, "456".getBytes(), -1,new IDataback(),"");Thread.sleep(Integer.MAX_VALUE);;} }class IDataback implements AsyncCallback.StatCallback{@Overridepublic void processResult(int rc, String path, Object ctx, Stat stat) {if (rc==0) {System.out.println("SUCCESS");}}}

?

檢測節點是否存在

客戶端可以通過zookeeper的api來檢測一個節點

?

?

?

?該接口主要用于檢測指定節點是否存在,返回值是一個Stat對象。如果在調用接口時注冊Watcher的話,

還可以對節點是否存在進行監聽,一旦節點被創建被刪除或被更新,都會通知客戶端。

?

權限控制

在zookeeper的實際使用中,我們的做法往往是搭建一個共用的zookeeper集群,同一為若干個應用提供服務,在這種情況下,不同的應用往往是不存在共享數據的場景的。因此需要解決不同應用之間的權限問題。

zookeeper提供了多種權限控制模式(Scheme),分別是world,auth,digest,ip和super。

本節中我們主要講digest模式下是如何進行zookeeper權限控制的。

?

開發人員如果要使用zookeeper的權限控制功能,需要在zookeeper完成會話創建的時候,給該會話添加相關的權限信息(AuthInfo)。zookeeper客戶端提供了相應的API接口來進行權限信息的設置。

該接口的主要作用是為當前的zookeeper會話添加權限信息,之后范式通過該會話對zookeeper服務端進行的任何操作都會帶上該權限信息。

使用包含權限信息的zookeeper會話創建數據節點。

package auth;import java.io.IOException; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper;public class AuthInfo {final static String PATH="/zk-book-auth_test";public static void main(String[] args) throws IOException, KeeperException, InterruptedException {ZooKeeper zk = new ZooKeeper("192.168.64.60:2181", 5000, null);zk.addAuthInfo("digest", "foo:true".getBytes());zk.create(PATH, "123".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);Thread.sleep(Integer.MAX_VALUE);} }

?

?使用無權限信息的zookeeper會話訪問權限信息的數據節點。

?

package auth;import java.io.IOException; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper;public class AuthInfo2 {final static String PATH="/zk-book-auth_test";public static void main(String[] args) throws IOException, KeeperException, InterruptedException {ZooKeeper zk = new ZooKeeper("192.168.64.60:2181", 5000, null);zk.addAuthInfo("digest", "foo:true".getBytes());zk.create(PATH, "123".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);ZooKeeper zk2 = new ZooKeeper("192.168.64.60:2181", 5000, null);zk2.getData(PATH, false, null);Thread.sleep(Integer.MAX_VALUE);} }

?

?

?一旦我們對一個數據節點設置了權限信息,那么其他沒有權限設置的客戶端會話將無法訪問該數據節點。

?

對于刪除及誒單(delete)接口而言,其權限控制比較特殊。

import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper; /** * * @ClassName: AuthSample_Delete * @Description: TODO(刪除節點的權限控制) * @author RongShu * @date 2017年6月11日 下午8:41:23 * */ public class AuthSample_Delete { final static String PATH = "/zk-book-auth_test"; final static String PATH2 = "/zk-book-auth_test/child"; public static void main(String[] args) throws Exception { ZooKeeper zookeeper1 = new ZooKeeper("localhost:2181",5000,null); zookeeper1.addAuthInfo("digest", "foo:true".getBytes()); zookeeper1.create( PATH, "init".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT ); zookeeper1.create( PATH2, "init".getBytes(), Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL ); try { ZooKeeper zookeeper2 = new ZooKeeper("localhost:2181",50000,null); zookeeper2.delete( PATH2, -1 ); } catch ( Exception e ) { System.out.println( "刪除節點失敗: " + e.getMessage() ); } ZooKeeper zookeeper3 = new ZooKeeper("localhost:2181",50000,null); zookeeper3.addAuthInfo("digest", "foo:true".getBytes()); zookeeper3.delete( PATH2, -1 ); System.out.println( "成功刪除節點:" + PATH2 ); ZooKeeper zookeeper4 = new ZooKeeper("localhost:2181",50000,null); zookeeper4.delete( PATH, -1 ); System.out.println( "成功刪除節點:" + PATH ); } } 輸出 刪除節點失敗: KeeperErrorCode = NoAuth for /zk-book-auth_test/child 成功刪除節點:/zk-book-auth_test/child 成功刪除節點:/zk-book-auth_test

注意:

當客戶端對一個數據節點添加了權限信息后,對于刪除操作而言,其作用范圍是其子節點,也就是說,當我們對一個數據節點添加權限信息之后,依然可以自由的刪除這個節點,但是對于這個節點的子節點,就必須使用相應的權限信息才能夠刪掉它。

?

轉載于:https://www.cnblogs.com/duan2/p/9070011.html

總結

以上是生活随笔為你收集整理的读《分布式一致性原理》JAVA客户端API操作3的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。