SoFunction
Updated on 2025-04-14

Detailed tutorial on using Curator for ZooKeeper operation in Java

1. Brief description

Apache CuratorIt is a Java client library based on ZooKeeper, which greatly simplifies the development work using ZooKeeper. Curator provides a high-level API that encapsulates many complex ZooKeeper operations, such as connection management, distributed locking, Leader elections, etc.

In distributed systems, ZooKeeper is often used as a coordination service, while Curator provides us with a simpler and easier-to-use interface, reducing the complexity of development. This article will introduce the core functions and practical examples of Curator.

2. Core functions

Apache Curator is a relatively complete ZooKeeper client framework, which simplifies the operation of ZooKeeper through a packaged set of advanced APIs. Curator mainly solves three types of problems:

  • Encapsulate the connection processing between ZooKeeper client and ZooKeeper server
  • Provides a set of Fluent-style operation API
  • Provides abstract encapsulation of various application scenarios of ZooKeeper (recipes, such as: distributed lock services, cluster leadership elections, shared counters, cache mechanisms, distributed queues, etc.)

Curator provides the following core components:

2.1 CuratorFramework

CuratorFramework is the core class of Curator, used to interact with ZooKeeper services.

2.2 Recipes

Curator provides implementations of a variety of common distributed modes, including:

  • Distributed lock (InterProcessMutex)
  • Distributed Queue (DistributedQueue)
  • Leader election (LeaderSelector)
  • Node cache (NodeCache)
  • Path cache (PathChildrenCache)
  • Tree cache (TreeCache)

3. Sample Practice

Curator provides abstract encapsulation of various application scenarios of Zookeeper (Recipe, such as shared lock services, Master election mechanisms, distributed calculators, etc.).

3.1 Dependency introduction

Before using Curator, you need to introduce relevant dependencies into your project:

<!-- zookeepersupport -->
<dependency>
   <groupId></groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.6.4</version>
</dependency>
<!-- curator-recipes -->
<dependency>
   <groupId></groupId>
   <artifactId>curator-recipes</artifactId>
   <version>5.5.0</version>
</dependency>
<!-- curator-framework -->
<dependency>
   <groupId></groupId>
   <artifactId>curator-framework</artifactId>
   <version>5.5.0</version>
</dependency>

3.2 Initialize CuratorFramework

The following code shows how to initialize the CuratorFramework:

import ;
import ;
import ;

public class CuratorExample {
    public static void main(String[] args) {
        // Create a CuratorFramework instance        CuratorFramework client = ()
                .connectString("127.0.0.1:2181") // ZooKeeper Address                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(3000)
                .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                .build();

        // Start the client        ();

        ("CuratorFramework started");

        // Close the client        ();
    }
}

3.3 Distributed lock

Distributed locks are an important function in distributed systems that coordinate access between multiple processes/threads.

import ;
import ;
import ;
import ;

import ;

public class DistributedLockExample {
    public static void main(String[] args) throws Exception {
        // Initialize CuratorFramework        CuratorFramework client = ()
                .connectString("127.0.0.1:2181")
                .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                .build();
        ();

        // Create a distributed lock        InterProcessMutex lock = new InterProcessMutex(client, "/distributed-lock");

        // Try to acquire the lock        if ((10, )) {
            try {
                ("Successfully acquire the lock, execute the task...");
                (5000); // Simulation tasks            } finally {
                ();
                ("Lock released");
            }
        } else {
            ("Failed to acquire the lock");
        }

        ();
    }
}

3.4 Leader Election

Curator'sLeaderSelectorProvides simple and easy-to-use Leader election functions.

import ;
import ;
import ;
import ;
import ;

public class LeaderElectionExample {
    public static void main(String[] args) throws InterruptedException {
        CuratorFramework client = ()
                .connectString("127.0.0.1:2181")
                .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                .build();
        ();

        // Create LeaderSelector        LeaderSelector leaderSelector = new LeaderSelector(client, "/leader-election", new LeaderSelectorListenerAdapter() {
            @Override
            public void takeLeadership(CuratorFramework client) throws Exception {
                ("Become a Leader, perform tasks...");
                (3000); // Simulation tasks                ("Task completed, release Leader permissions");
            }
        });

        (); // Automatically re-queuing to participate in the election        ();

        (Integer.MAX_VALUE); // Keep the main thread running        ();
    }
}

3.5 Node Cache

NodeCacheUsed to listen for data changes to specific nodes.

import ;
import ;
import ;
import ;

public class NodeCacheExample {
    public static void main(String[] args) throws Exception {
        CuratorFramework client = ()
                .connectString("127.0.0.1:2181")
                .retryPolicy(new ExponentialBackoffRetry(1000, 3))
                .build();
        ();

        // Create NodeCache        NodeCache nodeCache = new NodeCache(client, "/test-node");
        ().addListener(() -> {
            ("Node data is changed, the new data is:" + new String(().getData()));
        });

        ();

        // Create nodes and modify data        ().orSetData().forPath("/test-node", "initial-data".getBytes());
        (1000);
        ().forPath("/test-node", "updated-data".getBytes());

        (5000); // Keep running observation results        ();
    }
}

4. Summary

Curator provides powerful ZooKeeper packaging capabilities, greatly simplifying the development process. In a distributed system, Curator can implement functions such as distributed locking, Leader election and node monitoring to help developers quickly build stable distributed services.

The above is the detailed tutorial on using Curator to perform ZooKeeper operation. For more information about Java Curator performing ZooKeeper operation, please follow my other related articles!