Most services in a distributed environment allow partial failures and data inconsistencies, but some of the most basic services are required to be highly reliable and consistent, and these services are the basis for the operation of other distributed services, such as naming service, distributed lock, etc., which have the following requirements for distributed basic services:
- High Availability
- High consistency
- Performance
The question of how to design a service with some challenges to the CAP principle is a challenge and a good research topic, and Apache zookeeper may have given us a good answer. Zookeeper is a distributed, open-source, distributed application Coordination service that exposes a simple set of primitives that can be used by distributed applications to implement synchronization services, configure maintenance and naming services, and so on. More information about zookeeper can be found in the official documentation
Basic use of Zookeeper
A distributed zookeeper environment is relatively simple and the basic steps are as follows:
1) Install ZooKeeper on each server
After downloading the zookeeper, unzip it on each server.
Tar-xzf zookeeper-3.2.2.tar.gz
2) Configuring the cluster environment
The configuration file named Zoo.cfg is created under the Zookeeper installation directory of each server, and the contents are as follows:
[XHTML]View Plaincopy
- # The number of milliseconds of each tick
- Ticktime=
- # The number of ticks that initial
- # Synchronization phase can take
- initlimit=Ten
- # The number of ticks that can pass between
- # Sending a request and getting an acknowledgement
- synclimit=5
- # The directory where the snapshot is stored.
- Datadir=/home/admin/zookeeper-3.2.2/data
- # The port at which the clients would connect
- clientport=2181
- server.1=zoo1:2888:3888
- server.2=zoo2:2888:3888
where Zoo1 and Zoo2 respectively correspond to each server in the cluster machine name or Ip,server.1 and Server.2 1 and 2 respectively corresponding to each server's zookeeper Id,id setting method to create a file named DataDir under the myID configuration directory, and the ID as its file content, in this example is set to 1 and 2. Additional configuration details are visible in the official documentation.
3) Start the cluster environment
Run the Zookeeper startup script separately under each server
/home/admin/zookeeper-3.2.2/bin/zkserver.sh start
4) Application Zookeeper
Application zookeeper can execute commands in the shell, or you can invoke the program interface in Java or C.
To execute a command in the shell, run the following command:
Bin/zkcli.sh-server 10.20.147.35:2181
Where 10.20.147.35 is the IP or machine name of any machine in the cluster. After execution can enter the Zookeeper Operation panel, how to operate the visible official documents
In Java, the application of zookeeper through the calling program interface is more complex, need to understand the concepts such as watch and callback, but the simplest test curd do not need these, only need to use the Zookeeper class, the specific test code is as follows:
[Java]View Plaincopy
- Public static void Main (string[] args) {
- try {
- ZooKeeper ZK = new ZooKeeper ("10.20.147.35:2181", 30000, null);
- String name = Zk.create ("/company", "Alibaba". GetBytes (),
- Ids.open_acl_unsafe, createmode.persistent_sequential);
- Stat stat = new stat ();
- System.out.println (New String (Zk.getdata (name, NULL, stat)));
- Zk.setdata (name, "Taobao". GetBytes (), Stat.getversion (), null, null);
- System.out.println (New String (Zk.getdata (name, NULL, stat)));
- Stat = zk.exists (name, null);
- Zk.delete (name, Stat.getversion (), null, null);
- System.out.println (New String (Zk.getdata (name, NULL, stat)));
- } catch (Exception e) {
- E.printstacktrace ();
- }
- }
The above code is relatively simple, look at the Zookeeper API Doc will know how to use the
The realization mechanism of zookeeper
The implementation mechanism of zookeeper is the most complex of the open source framework I have seen, and its solution is the consistency problem in the distributed environment, which also determines the complexity of its implementation. Read the source code for two or three days or some can not touch the mind, some beyond my ability, but by looking at documents and other articles written by the author of the general understanding of its principles and basic structure.
1) Basic principles of Zookeeper
Zookeeper is based on the Fast Paxos algorithm, in the previous blog about a brief introduction of Paxos, and did not mention that there is a live lock Paxos the problem, that is, when there are multiple proposer staggered submissions, It is possible to repel each other so that no proposer can commit success, and fast Paxos makes some optimizations, by electing a leader, only the leader can commit propose, the specific algorithm is visible fast Paxos. So, to get zookeeper first you have to understand fast Paxos.
2) basic operation flow of zookeeper
Zookeeper has the following two main processes:
- Election leader
- Synchronizing data
There are many algorithms in the electoral leader process, but the election criteria to be met are the same:
- Leader to have the highest ZXID
- Most of the machines in the cluster are responding and follow the selected leader
Synchronizing data This process is the essence of zookeeper, and is the implementation of the Fast Paxos algorithm. A bull man drew a zookeeper data flow graph that visually describes how zookeeper synchronizes data.
The above two core processes I can not understand the essence of the moment, which I have not fully understood the fast Paxos algorithm, pending further study
Zookeeper Field of application
In the blog, Tim mentions several major scenarios that Paxos can apply, including database replication, naming service, config configuration management, access control list, and so on. This is also a few of the main scenarios that zookeeper can apply. In addition, some of the more basic distributed applications are mentioned in the official zookeeper document, which is zookeeper.
1) Distributed barrier
Barrier is a mechanism for controlling and coordinating the triggering sequence of multiple tasks, simply by making a lock on the task to be performed, and then releasing the gate when all the tasks are in a state of execution. Its mechanism can be seen in the following:
The JDK provides the Cyclicbarrier class to implement this mechanism on a single machine, but the JDK is powerless in a distributed environment. In the distributed implementation of Barrer need high consistency to do security, so zookeeper can be useful, the plan is to use a node as Barrer entity, need to be barrer task by calling exists () to detect the existence of this node, When you need to open barrier, delete the node,zookeeper watch mechanism to notify that each task can start executing.
2) Distributed Queue
Implementing a queue in a similar distributed environment with barrier requires a high degree of consistency, and zookeeper provides a simple way to zookeeper through a node to maintain a queue entity, use its children to store the contents of a queue, and The zookeeper create method provides a sequential incrementing pattern that automatically inserts a new element after the name with an incremented number. can use its children to build a queue of data structure, offer when using Create,take in accordance with the Children order to delete the first one. Zookeeper ensures that the data on each server is consistent and therefore implements a distributed Queue. The instance code for take and offer is as follows:
[Java]View Plaincopy
- /**
- * Removes the head of the queue and returns it, blocks until it succeeds.
- * @return The former head of the queue
- * @throws nosuchelementexception
- * @throws keeperexception
- * @throws interruptedexception
- */
- Public byte[] Take () throws Keeperexception, interruptedexception {
- Treemap<long,string> Orderedchildren;
- //Same as for element. Should refactor this.
- While (true) {
- Latchchildwatcher childwatcher = new Latchchildwatcher ();
- try{
- Orderedchildren = Orderedchildren (Childwatcher);
- }catch (Keeperexception.nonodeexception e) {
- Zookeeper.create (dir, new byte[0], ACL, createmode.persistent);
- continue;
- }
- if (orderedchildren.size () = = 0) {
- Childwatcher.await ();
- continue;
- }
- For (String headNode:orderedChildren.values ()) {
- String Path = dir +"/" +headnode;
- try{
- byte[] data = zookeeper.getdata (path, false, null);
- Zookeeper.delete (Path,-1);
- return data;
- }catch (Keeperexception.nonodeexception e) {
- //Another client deleted the node first.
- }
- }
- }
- }
- /**
- * Inserts data into queue.
- * @param data
- * @return True if data was successfully added
- */
- Public Boolean offer (byte[] data) throws Keeperexception, interruptedexception{
- for (;;) {
- try{
- Zookeeper.create (dir+"/" +prefix, data, ACL, createmode.persistent_sequential);
- return true;
- }catch (Keeperexception.nonodeexception e) {
- Zookeeper.create (dir, new byte[0], ACL, createmode.persistent);
- }
- }
- }
3) Distributed lock
The use of zookeeper to achieve distributed lock, mainly through a node to represent a lock, when a client to take the lock, will be under this node to create a self-increment sequence of child, and then through the GetChildren () The way to check the created child is not the most forward, if it is to get the lock, otherwise call exist () to check the second front of the child, plus watch to monitor. When the child who gets the lock returns the lock after execution, the return lock only needs to delete the child that he created, then the watch mechanism notifies all the clients that have not got the lock, and the child will compete for the lock according to the previous lock rule.
Distributed design and Development (iii)------High-consistency service zookeeper