CuratorFramework introduction

CuratorFramework is an open source set of Zookeeper client framework from Netflix. As an excellent open source tool of Zookeeper client, CuratorFramework mainly provides connection management and connection retry mechanism from client to service, as well as some extended functions. It takes care of many of the very low-level details of the ZooKeeper client development.

The main features include: Reconnection, repeated registration of Watcher and NodeExistsException, etc., has become a top-level project of Apache and is one of the most widely used ZooKeeper clients in the world. Patrick Hunt, the core submitter of ZooKeeper code, begins with the phrase “Guava is to Java what Curator is to ZooKeeper”. Just as the Guava toolset is for the Java platform, it is highly praised.

In addition, abstract encapsulation of ZooKeeper’s various application scenarios (Recipe, such as shared lock service, Master election mechanism, distributed counters, etc.) is provided in Exhibit EXHIBIT.

CuratorFramework programming features

In addition to encapsulating some low-level details that developers don’t need to pay special attention to, Exhibit also wraps around ZooKeeper’s native API to provide a Fluent style client-side API framework that is easier to use and read.

CuratorFramework project components

  • Recipes: Implementations of typical Zookeeper application scenarios based on the Co-curator Framework.
  • Framework: High-level encapsulation of the Zookeeper API, simplifying Zookeeper client programming, adding Zookeeper connection management, retry mechanism, etc.
  • Utilities: Various Utilities provided for Zookeeper.
  • Client: Encapsulates the Zookeeper Client. It replaces the native Zookeeper Client (Zookeeper class) and provides some useful Client features.
  • Errors: how to handle Errors, connection problems, recoverable exceptions, etc.

Official resources

  • The official documentation
  • Version of the list
  • The official article

Maven dependency Description

Composed of the following artifacts, but in most cases simply introduce toco-recipes.

CuratorFramework simple to use

CuratorFramework jars can be found in the Maven repository center. Using Maven, Gradle, Ant, etc., it is easy and simple to include a Curator in a project.

Many users will want to use some of Curtor’s pre-compiled tools, so Curator offers co-recipes, and if you just want to use the simple wrappers of Zooeeper, including link management and retry mechanisms, then the co-co-framework is sufficient.

Maven dependency Configuration

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.12.0</version>
</dependency>
Copy the code

Create a session

Create a client using two static methods of the Factory class CuratorFrameworkFactory:

static CuratorFramework newClient(String connectString, RetryPolicy retryPolicy);
static CuratorFramework newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy);
Copy the code
Construct the parameters in the method

  • ConnectString: indicates the ZK server address. Multiple servers are separated by commas (,)

  • ConnectionTimeoutMs: indicates the connection timeout duration. The value is 30 seconds. The default value is 15 seconds

  • SessionTimeoutMs: session timeout duration. The value is 50s, and 60s by default

  • RetryPolicy: retryPolicy for failures

Session Session timeout

This method configures retryPolicy and sessionTimeoutMs. Reconnection means that when the connection between the client and ZooKeeper is abnormal, such as network fluctuations and disconnection, reconnection is supported. Session validity is related to the node property. So what are the node properties of ZooKeeper?

Retry strategy

The CuratorFramework uses an interface, RetryPolicy, to allow users to implement custom retry policies. In RetryPolicy, users are allowed to implement custom retry policies. There is a method defined in the RetryPolicy interface:

boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)
Copy the code
RetryPolicy Indicates the interface parameter

The following implementation is provided by default, ExponentialBackoffRetry, BoundedExponentialBackoffRetry respectively, RetryForever, RetryNTimes, RetryOneTime, RetryUntilElapsed.

Start the session by calling the start() method in the CuratorFramework.

Obtain the Zookeeper connection session

The Curator link instance (CuratorFrameworkFactory) is obtained by the CuratorFrameworkFactory and for a Zk cluster only one CuratorFramework instance is required:

RetryPolicy retryPolicy  = new ExponentialBackoffRetry(1000.3);
CuratorFramework Client = CuratorFrameworkFactory.builder()
            .connectString("ip:2181,ip2:2181,ip3:2181")
            .sessionTimeoutMs(3000)
            .connectionTimeoutMs(5000)
            .retryPolicy(retryPolicy)
            .build();
client.start();
client.blockUntilConnected();
Copy the code

This will create a link to the ZK cluster using the default value. The only special single parameter to specify is the retry mechanism. For example, you need to use:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000.3); 
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();
Copy the code

A obtained CuratorFramework instance needs to call its start method before it can be used, and it needs to call its close method when it cannot be used.

In the example program above, we first created a retry policy called ExponentialBackoffRetry, which is one of several retry policies provided by default by Curator and is constructed as follows:

ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries);
ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs);
Copy the code

ExponentialBackoffRetry constructor argument:

The constructor takes three arguments, ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)

  • BaseSleepTimeMs: the initial sleep time, which is used to calculate the sleep time of each subsequent retry. The formula is as follows: Max (1, random. NextInt (1<<(retryCount+1)))

  • MaxRetries: indicates the maximum number of retries

  • MaxSleepMs: The maximum sleep time. If the current sleep calculated above is larger than this, the sleep uses this time

Org. Apache. Curator. RetryPolicy interface

  • Start () starts creating a session.

  • BlockUntilConnected () until the connection is successful or times out.

ExponentialBackoffRetry retry policy

Given an initial sleep time baseSleepTimeMs, based on this and retry times, the following formula is used to calculate the current sleep time: Max (1, random. NextInt (1 << (retryCount + 1)))

As the number of retries increases, the calculated sleep time increases. If the sleep time is within the maxSleepMs range, then the sleep time is used, otherwise maxSleepMs is used. In addition, the maxRetries parameter controls the maximum number of retries to avoid unlimited retries.

After creating a client Instance of the CuratorFramework, the CuratorFrameworkFactory factory does not essentially complete the creation of the session. Instead, it calls the Start () method of the CuratorFramework to complete the session creation.

Create a node whose initial content is empty

Once you have an instance of the CuratorFramework, you can call Zookeeper directly, which is similar to the native Zookeeper object provided in the ZK release,

client.create().forPath(path);
Copy the code
Create a node that contains content
client.create().forPath(path,"Data Day".getBytes());
Copy the code
Create temporary nodes and recursively create parent nodes
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
Copy the code

Here, like ZkClient, a recursive parent is encapsulated. When a parent is created recursively, the parent is a persistent node.

client.create().forPath("/my/path", myData)
Copy the code

Remove nodes

Delete a child node
client.delete().forPath(path);
Copy the code
Delete the node and recursively delete its children
client.delete().deletingChildrenIfNeeded().forPath(path);
Copy the code
Specify the version to delete
client.delete().withVersion(1).forPath(path);
Copy the code

// If the version does not exist, delete the exception with the following information:

org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for
Copy the code
A node is forcibly guaranteed to be deleted
client.delete().guaranteed().forPath(path);
Copy the code

Read the data

The reading node data content API is fairly simple. A method for passing in a Stat that is the current Stat of the node is replaced by the current Stat of the node. After the query method is executed, the Stat reference has executed the current Stat of the node.

Common query
client.getData().forPath(path);
Copy the code
Include status query
Stat stat = new Stat();
client.getData().storingStatIn(stat()).forPath(path);
Copy the code

Update the data

Update data, updating the current latest version if no version parameter is passed, updating the specified version if version is passed, and throwing an exception if version has changed.

Regular updates
client.setData().forPath(path,"New content".getBytes());
Copy the code
Specified version update
client.setData().withVersion(1).forPath(path);
Copy the code

Update error, inconsistent version exception:

org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for
Copy the code

The asynchronous interface

When using the node-specific operation apis above, we see that each interface has an inBackground() method to call. This interface is the asynchronous invocation entry provided by Curator. The corresponding asynchronous processing interface is BackgroundCallback. This interface refers to a processResult method that handles the result of the callback. GetType () in the parameter event of processResult contains various event types, and getResultCode() contains various response codes.

To highlight the following interfaces for inBackground:

public T inBackground(BackgroundCallback callback, Executor executor);
// This interface allows you to pass in an Executor instance and use a dedicated thread pool to process the business logic after the result is returned.
/** * Asynchronously create nodes ** Note: If you specify a thread pool, the corresponding operations will be performed in the thread pool, if not, the events will be sequentially processed using the Zookeeper EventThread thread ** /
client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
        System.out.println("Current thread:" + Thread.currentThread().getName() + ",code:"
                        + event.getResultCode() + ",type:" + event.getType());
        }
    }, Executors.newFixedThreadPool(10)).forPath("/async-node01");
client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
        System.out.println("Current thread:" + Thread.currentThread().getName() + ",code:" 
                           + event.getResultCode() + ",type:" + event.getType());
        }
    }).forPath("/async-node02");
Copy the code

Create a session with an isolated namespace

The benefit of using Curator is that Curator helps us manage client links to ZK and will perform the specified retry mechanism in case of network link problems. To isolate different ZooKeeper services, each service is assigned an independent namespace, that is, a ZooKeeper root path.

The following code snippet defines a client’s independent namespace as /base, so that any operations performed by the client on the data node on ZooKeeper are based on this relative directory:

CuratorFrameworkFactory.builder().connectString("domain1.book.zookeeper:2181")
	.sessionTimeoutMs(5000).retryPolicy(retryPolicy).namespace("base").build();
Copy the code

The resources

www.cnblogs.com/a-du/p/9892…