High-level ZooKeeper API
Project description
The zc.zk package provides some high-level interfaces to the low-level zookeeper extension. It’s not complete, in that it doesn’t try, at this time, to be a complete high-level interface. Rather, it provides facilities we need to use Zookeeeper to services together:
ZODB database clients and servers
HTTP-based clients and services
Load balencers
The current (initial) use cases are:
Register a server providing a service.
Get the addresses of servers providing a service.
Get abd set service configuration data.
This package makes no effort to support Windows. (Patches to support Windows might be accepted if they don’t add much complexity.)
Installation
You can install this as you would any other distribution. Note, however, that you must also install the Python ZooKeeper binding provided with ZooKeeper. Because this binding is packaged a number of different ways, it isn’t listed as a distribution requirement.
An easy way to get the Python zookeeper binding is by installing zc-zookeeper-static, whch is a self-contained statically building distribution.
Instantiating a ZooKeeper helper
To use the helper API, create a ZooKeeper instance:
>>> import zc.zk >>> zk = zc.zk.ZooKeeper('zookeeper.example.com:2181')
The ZooKeeper constructor takes a ZooKeeper connection string, which is a comma-separated list of addresses of the form HOST:PORT. It defaults to ‘127.0.0.1:2181’, which is convenient during development.
Register a server providing a service.
To register a server, use the register_server method, which takes a service path and the address a server is listing on
>>> zk.register_server('/fooservice/servers', ('192.168.0.42', 8080))
register_server creates a read-only ephemeral ZooKeeper node as a child of the given service path. The name of the new node is the given address. This allows clients to get the list of addresses by just getting the list of the names of children of the service path.
Ephemeral nodes have the useful property that they’re automatically removed when a ZooKeeper session is closed or when the process containing it dies. De-deregistration is automatic.
When registering a server, you can optionally provide server (node) data as additional keyword arguments to register_server. By default, the process id is set as the pid server key. This is useful to tracking down the server process.
Get the addresses of servers providing a service.
Getting the adresses providing a service is accomplished by getting the children of a service node.
>>> addresses = zk.children('/fooservice/servers') >>> sorted(addresses) ['192.168.0.42:8080']
The children method returns an iterable of names of child nodes of the node specified by the given path. The iterable is automatically updated when new servers are registered:
>>> zk.register_server('/fooservice/servers', ('192.168.0.42', 8081)) >>> sorted(addresses) ['192.168.0.42:8080', '192.168.0.42:8081']
You can call the iterable with a callback function that is called whenenever the list of children changes:
>>> @zk.children('/fooservice/servers') ... def addresses_updated(addresses): ... print 'addresses changed' ... print sorted(addresses) addresses changed ['192.168.0.42:8080', '192.168.0.42:8081']
The callback is called immediately with the children. When we add another child, it’ll be called again:
>>> zk.register_server('/fooservice/servers', ('192.168.0.42', 8082)) addresses changed ['192.168.0.42:8080', '192.168.0.42:8081', '192.168.0.42:8082']
Get service configuration data.
You get service configuration data by getting data associated with a ZooKeeper node. The interface for getting data is similar to the interface for getting children:
>>> data = zk.properties('/fooservice') >>> data['database'] u'/databases/foomain' >>> data['threads'] 1
The properties method returns a mapping object that provides access to node data. (ZooKeeper only stores string data for nodes. zc.zk provides a higher-level data interface by storing JSON strings.)
The properties objects can be called with callback functions and used as function decorators to get update notification:
>>> @zk.properties('/fooservice') ... def data_updated(data): ... print 'data updated' ... for item in sorted(data.items()): ... print '%s: %r' % item data updated database: u'/databases/foomain' favorite_color: u'red' threads: 1
The callback is called immediately. It’ll also be called when data are updated.
Updating node data
You can’t set data properties, but you can update data by calling it’s update method:
>>> data.update(threads=2, secret='123') data updated database: u'/databases/foomain' favorite_color: u'red' secret: u'123' threads: 2
or by calling it’s set method, which removes keys not listed:
>>> data.set(threads=3, secret='1234') data updated secret: u'1234' threads: 3
ZooKeeper Session Management
zc.zk takes care of ZooKeeper session management for you. It establishes and, if necessary, reestablishes sessions for you. In particular, it takes care of reestablishing ZooKeeper watches when a session is reestablished.
ZooKeeper logging
zc.zk bridges the low-level ZooKeeper logging API and the Python logging API. ZooKeeper log messages are forwarded to the Python 'ZooKeeper' logger.
zc.zk.ZooKeeper
- zc.zk.ZooKeeper(connection_string)
Return a new instance given a ZooKeeper connection string.
- children(path)
Return a zc.zk.Children for the path.
- properties(path)
Return a zc.zk.Properties for the path.
- handle
The ZooKeeper session handle
This attribute can be used to call the lower-level API provided by the zookeeper extension.
- register_server(path, address, **data)
Register a server at a path with the address.
An ephemeral child node of path will be created with name equal to the string representation (HOST:PORT) of the given address.
address must be a host and port tuple.
Optional node properties can be provided as keyword arguments.
- close()
Close the ZooKeeper session.
This should be called when cleanly shutting down servers to more quickly remove ephemeral nodes.
zc.zk.Children
- __iter__()
Return an iterator over the child names.
- __call__(callable)
Register a callback to be called whenever a child node is added or removed.
The callback is passed the children instance when a child node is added or removed.
zc.zk.Properties
Properties objects provide the usual read-only mapping methods, __getitem__, __len__, etc..
- set(**properties)
Set the properties for the node, replacing existing data.
- update(**properties)
Update the properties for the node.
- __call__(callable)
Register a callback to be called whenever a node’s properties are changed.
The callback is passed the properties instance when properties are changed.
Node deletion
If a node is deleted and Children or Properties instances have been created for it, the instances’ data will be cleared. Attempts to update properties will fail. If callbacks have been registered, they will be called without arguments, if possible. It would be bad, in practice, to remove a node that processes are watching.
Changes
0.1.0 (2011-11-27)
Initial release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.