-
Notifications
You must be signed in to change notification settings - Fork 435
Framework
The Curator Framework is a high-level API that greatly simplifies using ZooKeeper. It adds many features that build on ZooKeeper and handles the complexity of managing connections to the ZooKeeper cluster and retrying operations. Some of the features are:
- Automatic connection management:
- There are potential error cases that require ZooKeeper clients to recreate a connection and/or retry operations. Curator automatically and transparently (mostly) handles these cases.
- Cleaner API:
- simplifies the raw ZooKeeper methods, events, etc.
- provides a modern, fluent interface
- Recipe implementations (see Recipes):
- Leader election
- Shared lock
- Path cache and watcher
- Distributed Queue
- Distributed Priority Queue
- ...
CuratorFrameworks are allocated using the CuratorFrameworkFactory which provides both factory methods and a builder for creating instances. IMPORTANT: CuratorFramework instances are fully thread-safe. You should share one CuratorFramework per ZooKeeper cluster in your application.
The factory methods (newClient()) provide a simplified way of creating an instance. The Builder gives control over all parameters. Once you have a CuratorFramework instance, you must call the start() method. At the end of your application, you should call close().
The CuratorFramework uses a Fluent-style interface. Operations are constructed using builders returned by the CuratorFramework instance. When strung together, the methods form sentence-like statements. e.g.
client.create().forPath("/head", new byte[0]);
client.delete().inBackground().forPath("/head");
client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/head/child", new byte[0]);
client.getData().watched().inBackground().forPath("/test");
create() | Begins a create operation. Call additional methods (mode or background) and finalize the operation by calling forPath() |
delete() | Begins a delete operation. Call additional methods (version or background) and finalize the operation by calling forPath() |
checkExists() | Begins an operation to check that a ZNode exists. Call additional methods (watch or background) and finalize the operation by calling forPath() |
getData() | Begins an operation to get a ZNode's data. Call additional methods (watch, background or get stat) and finalize the operation by calling forPath() |
setData() | Begins an operation to set a ZNode's data. Call additional methods (version or background) and finalize the operation by calling forPath() |
getChildren() | Begins an operation to get a ZNode's list of children ZNodes. Call additional methods (watch, background or get stat) and finalize the operation by calling forPath() |
inTransaction() | Begins an atomic ZooKeeper transaction. Combine create, setData, check, and/or delete operations and then commit() as a unit. |
Notifications for background operations and watches are published via the ClientListener interface. You register listeners with the CuratorFramework instance using the addListener() method. The listener implements two methods:
eventReceived() | A background operation has completed or a watch has triggered. Examine the given event for details |
clientClosedDueToError() | An unrecoverable error has occurred. The CuratorFramework instance has been shut down |
The ClientEvent object is a super-set POJO that can hold every type of background notification and triggered watch. The useful fields of ClientEvent depend on the type of event which is exposed via the getType() method.
Event Type | Event Methods |
---|---|
CREATE | getResultCode() and getPath() |
DELETE | getResultCode() and getPath() |
EXISTS | getResultCode(), getPath() and getStat() |
GET_DATA | getResultCode(), getPath(), getStat() and getData() |
SET_DATA | getResultCode(), getPath() and getStat() |
CHILDREN | getResultCode(), getPath(), getStat(), getChildren() |
WATCHED | getWatchedEvent() |
Because a ZooKeeper cluster is a shared environment, it's vital that a namespace convention is observed so that various applications that use a given cluster don't use conflicting ZK paths.
The CuratorFramework has a concept of a "namespace". You set the namespace when creating a CuratorFramework instance (via the Builder). The CuratorFramework will then prepend the namespace to all paths when one of its APIs is called. i.e.
CuratorFramework client = CuratorFrameworkFactory.builder().namespace("MyApp") ... build();
…
client.create().forPath("/test", data);
// node was actually written to: "/MyApp/test"
For temporary connections over unreliable networks, a limited feature Temporary Framework is available.
- Curator
- Javadoc
- Coverage Report
- Getting Started
- Examples
- FAQ
- Client
- Framework
-
Recipes
- Leader Latch
- Leader Election
- Shared Reentrant Lock
- Shared Lock
- Shared Reentrant Read Write Lock
- Shared Semaphore
- Multi Shared Lock
- Distributed Queue
- Distributed Id Queue
- Distributed Priority Queue
- Distributed Delay Queue
- Simple Distributed Queue
- Barrier
- Double Barrier
- Shared counter
- Distributed Atomic Long
- Path Cache
- Node Cache
- Utilities – Test Server, Test Cluster, ZKPaths, EnsurePath, QueueSharder, Reaper, ChildReaper
- Tech Notes
- Errors
- Exhibitor Integration
- Extensions
- Logging and Tracing