以前在公司因爲業務須要,對zookeeper進行了一些知識點的梳理進行分享,對一些剛剛接觸zookeeper的小夥伴來講,或許能夠借鑑一下
java
簡介
Zookeeper致力於提供一個高性能、高可用,且具有嚴格的順序訪問控制能力的分佈式協調服務。node
設計目標apache
應用場景服務器
會話(session):客戶端與服務端的一次會話鏈接,本質是TCP長鏈接,經過會話能夠進行心跳檢測和數據傳輸;session
數據節點(znode)數據結構
對於持久節點和臨時節點,同一個znode下,節點的名稱是惟一的:[center red 20px]
Watcher 事件監聽器:客戶端能夠在節點上註冊監聽器,當特定的事件發生後,zk會通知到感興趣的客戶端。
EventType: NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChange負載均衡
ACL:Zk採用ACL(access control lists)策略來控制權限
權限類型:create,read,write,delete,admin分佈式
ACL:ide
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.12.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.12.0</version> </dependency>
public class App { public static void main(String[] args) throws Exception { String connectString = "211.159.174.226:2181"; RetryPolicy retryPolicy = getRetryPolicy(); CuratorFramework client = CuratorFrameworkFactory.newClient(connectString, 5000, 5000, retryPolicy); client.start(); //增刪改查 client.create().withMode(CreateMode.PERSISTENT).forPath("/test-Curator-PERSISTENT-nodata"); client.create().withMode(CreateMode.PERSISTENT).forPath("/test-Curator-PERSISTENT-data", "test-Curator-PERSISTENT-data".getBytes()); client.create().withMode(CreateMode.EPHEMERAL).forPath("/test-Curator-EPHEMERAL-nodata"); client.create().withMode(CreateMode.EPHEMERAL).forPath("/test-Curator-EPHEMERAL-data", "/test-Curator-EPHEMERAL-data".getBytes()); for (int i = 0; i < 5; i++) { client.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath("/test-Curator-PERSISTENT_SEQUENTIAL-nodata"); } byte[] bytes = client.getData().forPath("/test-Curator-PERSISTENT-data"); System.out.println("----------zk節點數據:" + new String(bytes) + "------------"); client.create().withMode(CreateMode.PERSISTENT).forPath("/test-listener", "test-listener".getBytes()); final NodeCache nodeCache = new NodeCache(client, "/test-listener"); nodeCache.start(); NodeCacheListener listener = new NodeCacheListener() { @Override public void nodeChanged() throws Exception { System.out.println("node changed : " + nodeCache.getCurrentData()); } }; nodeCache.getListenable().addListener(listener); client.setData().forPath("/test-listener", "/test-listener-change".getBytes()); } /** * RetryOneTime: 只重連一次. * RetryNTime: 指定重連的次數N. * RetryUtilElapsed: 指定最大重連超時時間和重連時間間隔,間歇性重連直到超時或者連接成功. * ExponentialBackoffRetry: 基於"backoff"方式重連,和RetryUtilElapsed的區別是重連的時間間隔是動態的 * BoundedExponentialBackoffRetry: 同ExponentialBackoffRetry,增長了最大重試次數的控制. */ public static RetryPolicy getRetryPolicy() { return new ExponentialBackoffRetry(1000, 3); } }
public class ZookeeperLock { private final String lockPath = "/distributed-lock"; private String connectString; private RetryPolicy retry; private CuratorFramework client; private InterProcessLock interProcessMutex; public void init() throws Exception { connectString = "211.159.174.226:2181"; retry = new ExponentialBackoffRetry(1000, 3); client = CuratorFrameworkFactory.newClient(connectString, 60000, 15000, retry); client.start(); //共享可重入鎖 interProcessMutex = new InterProcessMutex(client,lockPath); } public void lock(){ try { interProcessMutex.acquire(); } catch (Exception e) { System.out.println("鎖失敗了,真慘"); } } public void unlock(){ try { interProcessMutex.release(); } catch (Exception e) { System.out.println("釋放失敗了,更慘"); } } public static void main(String[] args) throws Exception { final ZookeeperLock zookeeperLock = new ZookeeperLock(); zookeeperLock.init(); Executor executor = Executors.newFixedThreadPool(5); for (int i = 0;i<50;i++) { executor.execute(new Runnable() { @Override public void run() { zookeeperLock.lock(); Long time = System.nanoTime(); System.out.println(time); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(time); zookeeperLock.unlock(); } }); } while (true){ } } }
ZAB協議所定義的三種節點狀態性能
崩潰恢復
消息廣播(相似2P提交):
更多文章關注博客:https://www.zplxjj.com和公衆號