http://colobu.com/2014/12/12/zookeeper-recipes-by-example-1/
Zookeeper officials have given several uses for the use of zookeeper.
- Leader election
- Barriers
- Queues
- Locks
- Two-phased Commit
- Other applications such as name Service, Configuration, Group membership
In the actual use of zookeeper development, our most commonly used is the Apache curator. It was contributed by Netflix to Apache, the current version of 2.7.0.
I believe you in the use of ZK API development will encounter a few problems, ZK connection management, session failure and other abnormal problems, curator for us to solve these problems, through the ZK connection state monitoring to make corresponding reconnection and other operations, and trigger events.
The better part is that curator provides a very good implementation for some of the ZK scenarios, and there are many extensions that are consistent with the ZK usage specification.
Its main components are:
- Recipes, zookeeper series recipe implementation, based on the curator Framework.
- The Framework, encapsulating a large number of Zookeeper common API operations, reduces the use of difficulty, based on zookeeper added some new features, the management of zookeeper links, the loss of links automatically re-link.
- Utilities, some zookeeper operating tool classes including ZK's cluster test tool path generation are very useful, under the Curator-client package org.apache.curator.utils.
- Client, ZooKeeper, is an alternative to the official ZooKeeper class, which solves some cumbersome and low-level processing and provides some tool classes.
- Errors, exception handling, connection exceptions, etc.
- Extensions, the expansion of the Curator-recipes implementation, split into Curator-:stuck_out_tongue_closed_eyes:iscovery and Curator-:stuck_out _tongue_closed_eyes:iscovery-server provides restful-based recipes Web services.
Recipe
A dictionary means a recipe, recipe, food recipe, cooking method , extension usage: a plan or step to obtain a predetermined result . In the computer field there is no suitable Chinese correspondence, if the zookeeper as a dish, recipe is equivalent to recipes, such as Mapo tofu, Kung Pao chicken.
Because the content is more, will be divided into several articles to introduce. The specific chapters are shown above.
In addition to the recipe of ZK's "two-phased Commit", curator provided all the recipe of ZK and classified it in more detail. This article will introduce these recipe as an example. Once you understand these recipe, you can use the power of zookeeper very well in your project.
Leader elections
In distributed computing, leader election is an important feature of this election process: Assign a process as the organizer and distribute the task to each node. Before the task starts, which node does not know who is leader or coordinator. When the election algorithm starts executing, each node will eventually get a unique node as the task leader.
In addition, the election will often occur in the case of leader unplanned outages, the new leader to be elected.
Curator there are two kinds of election recipe, you can choose the right one according to your needs.
Leader latch
First, let's look at an LeaderLatch
example of using classes to elect.
Its constructor is as follows:
12 |
Public Leaderlatch (curatorframework client, String latchpath) Public Leaderlatch (curatorframework Client, String latchpath, string id) |
Leaderlatch must be started:leaderLatch.start();
Once activated, Leaderlatch will negotiate with other leaderlatch that use the same latch path and randomly select one of them as the leader. You can always see if a given instance is leader:
1 |
Public Boolean hasleadership () |
Like JDK Countdownlatch, Leaderlatch has a block method when it requests to be leadership:
123456789 |
Public void await () throws interruptedexception, this instance acquires leadershipunless the Thread is interrupted or closed. Public Boolean await (long timeout, Timeunit unit) throws interruptedexception |
Once the leaderlatch is not used, the method must be called close
. If it is leader, the leadership will be released and the other participants will elect a leader.
Exception handling
Leaderlatch instances can increase Connectionstatelistener to listen for network connectivity issues. When SUSPENDED or LOST, leader no longer consider himself or leader. When the LOST connection is reconnected, Reconnected,leaderlatch deletes the previous Znode and then re-creates one.
Leaderlatch users must consider connectivity issues that cause Leadershi to be lost. It is highly recommended that you use Connectionstatelistener.
Let's look at the example below:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 666768 |
PackageCom.colobu.zkrecipe.leaderelection;ImportJava.io.BufferedReader;ImportJava.io.IOException;ImportJava.io.InputStreamReader;ImportJava.util.List;ImportJava.util.concurrent.TimeUnit;ImportOrg.apache.curator.framework.CuratorFramework;ImportOrg.apache.curator.framework.CuratorFrameworkFactory;ImportOrg.apache.curator.framework.recipes.leader.LeaderLatch;ImportOrg.apache.curator.retry.ExponentialBackoffRetry;ImportOrg.apache.curator.test.TestingServer;ImportOrg.apache.curator.utils.CloseableUtils;Importcom.google.common.collect.Lists; Public class leaderlatchexample {Private Static Final intClient_qty =Ten;Private Static FinalString PATH ="/examples/leader";Public static void main(string[] args) throws Exception{list<curatorframework> clients = Lists.newarraylist (); list<leaderlatch> examples = Lists.newarraylist (); TestingServer Server =NewTestingServer ();Try{ for(inti =0; i < Client_qty; ++i) {Curatorframework client = Curatorframeworkfactory.newclient (Server.getconnectstring (),NewExponentialbackoffretry ( +,3)); Clients.add (client); leaderlatch example =NewLeaderlatch (client, PATH,"Client #"+ i); Examples.add (example); Client.start (); Example.start ();} Thread.Sleep (20000); Leaderlatch Currentleader =NULL; for(inti =0; i < Client_qty; ++i) {Leaderlatch example = Examples.get (i);if(Example.hasleadership ()) Currentleader = example;} System.out.println ("Current Leader"+ Currentleader.getid ()); System.out.println ("Release the leader"+ Currentleader.getid ()); Currentleader.close (); Examples.get (0). Await (2, timeunit.seconds); System.out.println ("Client #0 Maybe is elected as the leader or not although it want to be"); System.out.println ("The new leader is"+ Examples.get (0). Getleader (). GetId ()); System.out.println ("Press Enter/return to quit\n");NewBufferedReader (NewInputStreamReader (system.in)). ReadLine ();}Catch(Exception e) {E.printstacktrace ();}finally{System.out.println ("Shutting down ..."); for(Leaderlatch exampleclient:examples) {closeableutils.closequietly (exampleclient);} for(Curatorframework client:clients) {closeableutils.closequietly (client);} closeableutils.closequietly (server);}}} |
First we created 10 Leaderlatch, and one of them will be elected as leader after launch. Since the election will take some time, the leader cannot be obtained immediately after start.
hasLeadership
returns True by checking if you are leader, if yes.
.getLeader().getId()
the ID of the current leader can be obtained by the.
Only by close
releasing the current leadership.
await
is a blocking method, trying to acquire leader status, but may not be able to upper.
Leader election
Curator also provides another way of voting.
Note the following four classes are involved:
- Leaderselector
- Leaderselectorlistener
- Leaderselectorlisteneradapter
- Cancelleadershipexception
The important thing is the Leaderselector class, whose constructor is:
12 |
Public Leaderselector (curatorframework client, String Mutexpath,leaderselectorlistener listener) Public Leaderselector (curatorframework client, String Mutexpath, Threadfactory threadfactory, Executor Executor, Leaderselectorlistener Listener) |
Similar to Leaderlatch, you must start
:leaderSelector.start();
Once started, your listener method is called when the instance gets the lead. The takeLeadership()
takeleadership () method returns only if the leadership is released.
When you no longer use an Leaderselector instance, you should call its Close method.
Exception handling
The Leaderselectorlistener class inherits connectionstatelistener.leaderselector must be careful of the connection state changes. If the instance becomes leader, it should suspended or LOST accordingly. When the SUSPENDED state occurs, the instance must assume that it may no longer be leader until the reconnection succeeds. If the lost state appears, the instance is no longer leader, and the Takeleadership method returns.
Important : The recommended approach is to throw a Cancelleadershipexception exception when you receive suspended or lost. This causes the Leaderselector instance to break and cancel the exception that executes the Takeleadership method. This is very important and you have to consider extending the leaderselectorlisteneradapter. The Leaderselectorlisteneradapter provides the recommended processing logic.
This example is excerpted from the official.
First, create a Exampleclient class that inherits Leaderselectorlisteneradapter, which implements the Takeleadership method:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546 |
PackageCom.colobu.zkrecipe.leaderelection;ImportOrg.apache.curator.framework.CuratorFramework;ImportOrg.apache.curator.framework.recipes.leader.LeaderSelectorListenerAdapter;ImportOrg.apache.curator.framework.recipes.leader.LeaderSelector;Importjava.io.Closeable;ImportJava.io.IOException;ImportJava.util.concurrent.TimeUnit;ImportJava.util.concurrent.atomic.AtomicInteger; Public class exampleclient extends leaderselectorlisteneradapter Implements closeable {Private FinalString name;Private FinalLeaderselector Leaderselector;Private FinalAtomicinteger Leadercount =NewAtomicinteger ();Public exampleclient(curatorframework Client, string path, string name) { This. Name = Name;leaderselector =NewLeaderselector (client, PATH, This); Leaderselector.autorequeue ();}Public void start() throws IOException{Leaderselector.start ();}@OverridePublic void close() throws IOException{Leaderselector.close ();}@OverridePublic void takeleadership(curatorframework client) throws Exception{Final intWaitseconds = (int) (5* Math.random ()) +1; SYSTEM.OUT.PRINTLN (name +"is now the leader. Waiting "+ Waitseconds +"seconds ..."); SYSTEM.OUT.PRINTLN (name +"has been leader"+ leadercount.getandincrement () +"Time (s) before.");Try{Thread.Sleep (TimeUnit.SECONDS.toMillis (Waitseconds));}Catch(Interruptedexception e) {SYSTEM.ERR.PRINTLN (name +"was interrupted."); Thread.CurrentThread (). interrupt ();}finally{SYSTEM.OUT.PRINTLN (name +"Relinquishing leadership.\n");}}} |
You can assign tasks in takeleadership and so on, and do not return, if you want this instance to be leader, you can add a dead loop.
leaderSelector.autoRequeue();
It is also possible to gain leadership after this instance releases leadership.
Here we use Atomicinteger to record the number of times this client has gained leadership, which is "fair" and each client has equal access to leadership.
Test code:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
PackageCom.colobu.zkrecipe.leaderelection;ImportJava.io.BufferedReader;ImportJava.io.InputStreamReader;ImportJava.util.List;ImportOrg.apache.curator.framework.CuratorFramework;ImportOrg.apache.curator.framework.CuratorFrameworkFactory;ImportOrg.apache.curator.framework.recipes.leader.LeaderSelector;ImportOrg.apache.curator.retry.ExponentialBackoffRetry;ImportOrg.apache.curator.test.TestingServer;ImportOrg.apache.curator.utils.CloseableUtils;Importcom.google.common.collect.Lists; Public class leaderselectorexample {Private Static Final intClient_qty =Ten;Private Static FinalString PATH ="/examples/leader";Public static void main(string[] args) throws Exception{list<curatorframework> clients = Lists.newarraylist (); list<exampleclient> examples = Lists.newarraylist (); TestingServer Server =NewTestingServer ();Try{ for(inti =0; i < Client_qty; ++i) {Curatorframework client = Curatorframeworkfactory.newclient (Server.getconnectstring (),NewExponentialbackoffretry ( +,3)); Clients.add (client); exampleclient example =NewExampleclient (client, PATH,"Client #"+ i); Examples.add (example); Client.start (); Example.start ();} System.out.println ("Press Enter/return to quit\n");NewBufferedReader (NewInputStreamReader (system.in)). ReadLine ();}finally{System.out.println ("Shutting down ..."); for(Exampleclient exampleclient:examples) {closeableutils.closequietly (exampleclient);} for(Curatorframework client:clients) {closeableutils.closequietly (client);} closeableutils.closequietly (server);}}} |
With Leaderlatch, LeaderSelectorListener
it is possible to control the leadership and release leadership at the right time so that each node is likely to gain leadership. and leaderlatch a tendon to death, unless the Close method is called, it will not release the leadership.
Follow the example to learn zookeeper usage: Leader election