First meet Zookeeper
Zookeeper is a sub project under the Apache Hadoop project. It is a tree directory service. The zoo keeper is used to manage Hadoop, Hive, Pig and other animals. Zookeeper is a distributed, open source, distributed application coordination service.
The most commonly used functions: configuration management, distributed lock and cluster management.
(personal feeling is similar to that of Nacos)
Installing Zookeeper
ZooKeeper installation configuration - ZooKeeper tutorial ™ (yiibai.com)
Zookeeper cluster setup - Windows - Nuggets (juejin.cn)
zookeeper cluster construction - YSOcean - blog Park (cnblogs.com)
Operate Zookeeper
data model
zookeeper has a hierarchical tree structure
Each node is called ZNode, and each node will save its own data and node information.
A node can have child nodes and a small amount (1MB) of data storage is allowed.
Nodes can be divided into four categories:
- PERSISTENT node: session disconnection and server restart are still in progress; child nodes can be created, which can be temporary or PERSISTENT; they cannot have the same name.
- Temporary node (EPHEMERAL) - e: session is lost when the link is broken; cannot create child nodes; cannot have the same name.
- PERSISTENT_SEQUENTIAL - s: session disconnection and server restart are still in progress; child nodes can be created, which can be temporary or persistent; nodes with the same name will be added with sequence numbers later.
- Temporary sequential node (EPHEMERAL_SEQUENTIAL) - es: the session link is broken and disappears; child nodes cannot be created; nodes with the same name will be added with sequence numbers (benefits of using distributed locks)
command
Server command
./zkServer.sh start/status/stop/restart
Client commands
./zkCli.sh -server localhost:2181
create -e/-s/-es [node] [child node] [data]
get [node] = [data]
set node data
delete node sub node
deleteall node
ls -s [node]
...
Java API operations
Curator simplifies development
Common commands:
Link, add, delete and modify query, Watch event monitoring, distributed lock
To carry this big man:
https://gitee.com/gaozhihong/Zookpper_HM
pom file required
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.cl</groupId> <artifactId>CuratorApi</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.7</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.6.0</version> <type>jar</type> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.10</version> <type>jar</type> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.6.0</version> <type>jar</type> </dependency> </dependencies> </project>
link
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.retry.ExponentialBackoffRetry; /** * Title: get Zookeeper connection object * Author: where is the return journey * Time: April 16, 2020 - 15:41 */ public class CuratorConnection { public static void main(String[] args) { // Create connection object CuratorFramework client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("create") // Building connection objects .build(); // open a connection client.start(); System.out.println(client.isStarted()); // Close connection client.close(); } }
New node
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooDefs; import org.apache.zookeeper.data.ACL; import org.apache.zookeeper.data.Id; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * Title: new node * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorCreate { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("create") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: add node * @Author: Gao Zhihong */ @Test public void create1() throws Exception { String path = client.create() // Type of node .withMode(CreateMode.PERSISTENT) // Permission list of node world:anyone:cdrwa .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) // First parameter: node name // The second parameter: node data .forPath("/node1", "node1".getBytes()); System.out.println(path); } /** * @Function: create node and customize permission list * @Author: Gao Zhihong */ @Test public void create2() throws Exception { // Permission list List<ACL> acls = new ArrayList<>(); // Authorization mode and object Id id = new Id("ip", "39.98.67.88"); acls.add(new ACL(ZooDefs.Perms.ALL, id)); String path = client.create() .withMode(CreateMode.PERSISTENT) .withACL(acls) .forPath("/node2", "node2".getBytes()); System.out.println(path); } /** * @Function: create node tree recursively * @Author: Gao Zhihong */ @Test public void create3() throws Exception { String path = client.create() // Support the creation of recursive nodes .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT) .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) .forPath("/node3/node31", "node31".getBytes()); System.out.println(path); } /** * @Function: create node asynchronously * @Author: Gao Zhihong */ @Test public void create4() throws Exception { client.create() .creatingParentsIfNeeded() .withMode(CreateMode.PERSISTENT) .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { // Path of node System.out.println(curatorEvent.getPath()); // Event type System.out.println(curatorEvent.getType()); } }) .forPath("/node4", "node4".getBytes()); TimeUnit.SECONDS.sleep(1); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Delete node
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: delete node * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorDelete { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("delete") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: delete node * @Author: Gao Zhihong */ @Test public void delete1() throws Exception { client.delete() // First parameter: node path .forPath("/node1"); System.out.println("Deleted!"); } /** * @Function: delete nodes and perform version detection * @Author: Gao Zhihong */ @Test public void delete2() throws Exception { client.setData() // Version number - 1 identifies the ignored version number .withVersion(0) .forPath("/node1"); System.out.println("Deleted"); } /** * @Function: delete nodes containing child nodes * @Author: Gao Zhihong */ @Test public void delete3() throws Exception { client.delete() // If there are child nodes, they will be deleted together .deletingChildrenIfNeeded() .withVersion(-1) .forPath("/node1"); System.out.println("Deleted"); } /** * @Function: delete node asynchronously * @Author: Gao Zhihong */ @Test public void delete4() throws Exception { client.delete() .deletingChildrenIfNeeded() .withVersion(0) .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { System.out.println(curatorEvent.getPath()); System.out.println(curatorEvent.getType()); } }) .forPath("/node1"); TimeUnit.SECONDS.sleep(1); System.out.println("Deleted"); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Query node
import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.data.Stat; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: query node * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorGet { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("get") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: query node content * @Author: Gao Zhihong */ @Test public void get1() throws Exception { byte[] bytes = client.getData() // First parameter: node path .forPath("/node1"); System.out.println(new String(bytes)); } /** * @Function: query node attributes * @Author: Gao Zhihong */ @Test public void get2() throws Exception { Stat stat = new Stat(); client.getData() // read attribute .storingStatIn(stat) .forPath("/node1"); System.out.println(stat); } /** * @Function: asynchronous query node * @Author: Gao Zhihong */ @Test public void get3() throws Exception { client.getData() .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { System.out.println(curatorEvent.getPath()); System.out.println(curatorEvent.getType()); System.out.println(new String(curatorEvent.getData())); } }) .forPath("/node1"); TimeUnit.SECONDS.sleep(1); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Query child node
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.List; import java.util.concurrent.TimeUnit; /** * Title: query child nodes * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorGetChildren { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Building connection objects .build(); // open a connection client.start(); } /** * @Function: query child node content * @Author: Gao Zhihong */ @Test public void getChildren1() throws Exception { List<String> childrens = client.getChildren() // First parameter: node path .forPath("/get"); childrens.forEach(System.out::println); } /** * @Function: asynchronously query child nodes * @Author: Gao Zhihong */ @Test public void getChildren2() throws Exception { client.getChildren() .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { curatorEvent.getChildren().forEach(System.out::println); } }) .forPath("/get"); TimeUnit.SECONDS.sleep(3); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Query whether the node exists
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.data.Stat; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: check whether the node exists * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorExists { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("get") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: judge whether a node exists * @Author: Gao Zhihong */ @Test public void exists1() throws Exception { Stat stat = client.checkExists() // First parameter: node path .forPath("/node2"); System.out.println(stat); } /** * @Function: determine whether a node exists asynchronously * @Author: Gao Zhihong */ @Test public void exists2() throws Exception { client.checkExists() .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { System.out.println(curatorEvent.getPath()); System.out.println(curatorEvent.getType()); System.out.println(curatorEvent.getStat()); } }) .forPath("/node1"); TimeUnit.SECONDS.sleep(3); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Modify node
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.BackgroundCallback; import org.apache.curator.framework.api.CuratorEvent; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.data.Stat; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: modifying nodes * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorSet { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("set") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: update nodes * @Author: Gao Zhihong */ @Test public void set1() throws Exception { Stat stat = client.setData() // First parameter: node path // Second parameter: node data .forPath("/node1", "hello".getBytes()); System.out.println(stat); } /** * @Function: update nodes and perform version detection * @Author: Gao Zhihong */ @Test public void set2() throws Exception { Stat stat = client.setData() // Version number - 1 identifies the ignored version number .withVersion(1) .forPath("/node1", "world".getBytes()); System.out.println(stat); } /** * @Function: modify nodes asynchronously * @Author: Gao Zhihong */ @Test public void set3() throws Exception { client.setData() .withVersion(2) .inBackground(new BackgroundCallback() { @Override public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception { System.out.println(curatorEvent.getPath()); System.out.println(curatorEvent.getType()); } }) .forPath("/node1", "Ha ha ha".getBytes()); TimeUnit.SECONDS.sleep(1); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
event listeners
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.cache.*; import org.apache.curator.retry.ExponentialBackoffRetry; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: event listening mechanism * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorWatcher { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Building connection objects .build(); // open a connection client.start(); } /** * @Function: monitor the data change of a node * @Author: Gao Zhihong */ @Test public void watcher1() throws Exception { // Parameter 1: connection object // Parameter 2: monitored node path final NodeCache nodeCache = new NodeCache(client, "/watcher1"); // Launch interpreter object nodeCache.start(); nodeCache.getListenable().addListener(new NodeCacheListener() { // Method of callback when node changes @Override public void nodeChanged() throws Exception { System.out.println(nodeCache.getCurrentData().getPath()); System.out.println(new String(nodeCache.getCurrentData().getData())); System.out.println(nodeCache.getCurrentData().getStat()); } }); TimeUnit.SECONDS.sleep(30); // Close monitor object nodeCache.close(); } /** * @Function: monitor the data change of a child node * @Author: Gao Zhihong */ @Test public void watcher2() throws Exception { // Parameter 1: connection object // Parameter 2: monitored node path // Parameter 3: whether node data can be obtained in the event final PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/watcher1", true); // Launch interpreter object pathChildrenCache.start(); pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() { // The method of callback when the child node method changes @Override public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception { // Event type of node System.out.println(pathChildrenCacheEvent.getType()); // Path of node System.out.println(pathChildrenCacheEvent.getData().getPath()); // Node data System.out.println(new String(pathChildrenCacheEvent.getData().getData())); } }); TimeUnit.SECONDS.sleep(30); // Close monitor object pathChildrenCache.close(); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
affair
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.api.transaction.CuratorTransactionResult; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.ZooDefs; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.Collection; /** * Title: transaction * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorTransaction { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Namespace .namespace("create") // Building connection objects .build(); // open a connection client.start(); } /** * @Function: transaction * @Author: Gao Zhihong */ @Test public void transaction1() throws Exception { // Open transaction Collection<CuratorTransactionResult> collection = client.inTransaction() .create() .withMode(CreateMode.PERSISTENT) .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) .forPath("/node1", "node1".getBytes()) .and() .create().forPath("/node2", "node2".getBytes()) .and() // Commit transaction .commit(); System.out.println(collection); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Distributed lock
package cn.cl; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.locks.InterProcessLock; import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock; import org.apache.curator.retry.ExponentialBackoffRetry; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Title: distributed lock * Author: where is the return journey * Time: April 16, 2020 - 18:07 */ public class CuratorLock { CuratorFramework client; /** * @Function: get connection * @Author: Gao Zhihong */ @Before public void before() { // Create connection object client = CuratorFrameworkFactory .builder() // IP address port number .connectString("39.98.67.88:2181,39.98.67.88:2182,39.98.67.88:2183") // Session timeout .sessionTimeoutMs(5000) // Reconnection mechanism // new RetryOneTime(3000): reconnect once every three seconds, only once // new RetryNTimes(3, 3000): reconnection every three seconds, 3 times in total // new RetryUntilElapsed(10000, 3000): reconnect every three seconds, and stop the reconnect after 10 seconds // New exponential backoffretry (1000, 3): reconnect three times, and the interval between reconnections will be longer and longer .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // Building connection objects .build(); // open a connection client.start(); } /** * @Function: exclusive lock * @Author: Gao Zhihong */ @Test public void lock1() throws Exception { // Parameter 1: connection object // Parameter 2: node path InterProcessLock interProcessLock = new InterProcessMutex(client, "/lock1"); System.out.println("Waiting to acquire lock object"); // Acquire lock interProcessLock.acquire(); for (int i = 0; i < 5; i++) { TimeUnit.SECONDS.sleep(1); System.out.println(i); } System.out.println("Waiting to release the lock"); // Release lock interProcessLock.release(); } /** * @Function: read / write lock - read lock * @Author: Gao Zhihong */ @Test public void lock2() throws Exception { // Read write lock InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, "/lock1"); // Get read lock object InterProcessMutex interProcessMutex = readWriteLock.readLock(); System.out.println("Waiting to acquire lock object"); // Acquire lock interProcessMutex.acquire(); for (int i = 0; i < 10; i++) { TimeUnit.SECONDS.sleep(1); System.out.println(i); } System.out.println("Waiting to release the lock"); // Release lock interProcessMutex.release(); } /** * @Function: read / write lock - write lock * @Author: Gao Zhihong */ @Test public void lock3() throws Exception { // Read write lock InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, "/lock1"); // Get read lock object InterProcessMutex interProcessMutex = readWriteLock.writeLock(); System.out.println("Waiting to acquire lock object"); // Acquire lock interProcessMutex.acquire(); for (int i = 0; i < 10; i++) { TimeUnit.SECONDS.sleep(1); System.out.println(i); } System.out.println("Waiting to release the lock"); // Release lock interProcessMutex.release(); } /** * @Function: close connection * @Author: Gao Zhihong */ @After public void after() { if (client != null) { client.close(); } } }
Zookeeper cluster installation
Step 1: configure JAVA environment and verify environment: java -version
Step 2: Download and unzip zookeeper
# cd /usr/local # wget http://mirror.bit.edu.cn/apache/zookeeper/stable/zookeeper-3.4.12.tar.gz # tar -zxvf zookeeper-3.4.12.tar.gz # cd zookeeper-3.4.12
Step 3: Rename zoo_sample.cfg file
# cp conf/zoo_sample.cfg conf/zoo-1.cfg
Step 4: modify the configuration file zoo-1 CFG, some in the original configuration file are modified to the following values, and those without are added
# vim conf/zoo-1.cfg dataDir=/tmp/zookeeper-1 clientPort=2181 server.1=127.0.0.1:2888:3888 server.2=127.0.0.1:2889:3889 server.3=127.0.0.1:2890:3890
Configuration description
- tickTime: this time is used as the time interval between Zookeeper servers or between clients and servers to maintain heartbeat, that is, a heartbeat will be sent every tickTime.
- initLimit: this configuration item is used to configure the maximum number of heartbeat intervals that the Zookeeper receiving client (the client mentioned here is not the client that the user connects to the Zookeeper server, but the Follower server connected to the Leader in the Zookeeper server cluster) can endure when initializing the connection. When the time has exceeded 10 heartbeats The Zookeeper server has not received the return information from the client after the length of (that is, tickTime), which indicates that the client connection failed. The total length of time is 10 * 2000 = 20 seconds
- syncLimit: this configuration item identifies the length of message sending, request and response time between Leader and Follower. The maximum length of time can not exceed the length of tickTime. The total length of time is 5 * 2000 = 10 seconds
- dataDir: as the name suggests, it is the directory where Zookeeper saves data. By default, Zookeeper also saves the log files that write data in this directory.
- clientPort: this port is the port where the client connects to the zookeeper server. Zookeeper will listen to this port and accept the client's access requests.
- server.A=B: C: D: where a is a number, indicating the server number; B is the ip address of the server; C represents the port where the server exchanges information with the Leader server in the cluster; D means that in case the Leader server in the cluster hangs up, a port is needed to re elect and select a new Leader, and this port is the port used to communicate with each other during the election. In case of pseudo cluster configuration, since B is the same, the communication port numbers of different Zookeeper instances cannot be the same, so they should be assigned different port numbers.
Step 5: identify Server ID
Create three folders / tmp/zookeeper-1, / tmp/zookeeper-2, / tmp/zookeeper-2, create the file myid file in each directory, and write the server id of the current instance, i.e. 1.2 3.
# cd /tmp/zookeeper-1 # vim myid 1 # cd /tmp/zookeeper-2 # vim myid 2 # cd /tmp/zookeeper-3 # vim myid 3
Step 6: start three zookeeper instances
# bin/zkServer.sh start conf/zoo-1.cfg # bin/zkServer.sh start conf/zoo-2.cfg # bin/zkServer.sh start conf/zoo-3.cfg
Step7: to detect the cluster status, you can also directly use the command "zkCli.sh -server IP:PORT" to connect to the zookeeper server for detection
How Zookeeper works
Zookeeper introduction read this article is enough_ Technology sharing
Detailed explanation of zookeeper principle - Zhihu (zhihu.com)
What can we do with zookeeper
ZooKeeper interview questions (2020 latest edition)
5 minutes to let you understand the function and principle of ZooKeeper
Detailed explanation of ZooKeeper concept, the most complete arrangement_ salutary influence of education