Many of you have used Zookeeper at some point or another and know that it does two things

  • The configuration center implements unified configuration and management of table sharding rules
  • Registration center, to achieve sharding-proxy node service address registration

So what exactly is Zookeeper? And why can achieve this function? Let’s take a look at Zookeeper.

Zookeeper’s past and present lives

Apache ZooKeeper is a highly reliable distributed coordination middleware. It is an open source implementation of Google Chubby, so what problems does it mainly solve? Get to know Google Chubby first

Google Chubby is a coarse-grained distributed lock service from Google that addresses distributed consistency issues.

Distributed consistency problem

What is a distributed consistency problem? In simple terms, in a distributed system, there are multiple nodes, each node will make a request, but only one request can be confirmed among all nodes. The passage requires the agreement of all nodes, so the so-called consistency is the ability to select the final definitive request among all requests proposed. And once the request is selected, all nodes need to know about it.

This is the classic Byzantine general problem

The Byzantine generals problem was that the generals of the Byzantine Army had to vote unanimously to decide whether to attack a particular country. But these generals are separated in the field position, and there are traitors among the generals. A traitor can achieve his goal by acting at will:

  1. Duped some generals into taking offensive action

  2. To prompt a decision that is not agreed upon by all generals, such as generals who do not wish to attack, but a traitor can prompt an attack

  3. Confuse the generals so that they can’t make a decision

If the renegade achieves any of its objectives, the mission will fail. The attack can only succeed if there is complete agreement

The essence of the Byzantine problem is that because of unreliable network communication, there may be message loss, or network latency. How to agree on a request in this context.

To solve this problem, various protocols have been proposed, such as the well-known Paxos; This means that in an untrusted network environment, the PaxOS protocol can be used to agree on a proposal.

So, the essence of distributed consistency is, in a distributed system, how do multiple nodes agree on a proposal

What does this have to do with Google Chubby

Google has a GFS(Google File System) and they have a requirement to select a master server from multiple GFS servers. This is a typical consistency problem, 5 servers distributed on different nodes, need to determine a master server, and their consistency goal is to determine a node as the master, and all nodes must agree.

The GFS uses Chubby to solve this problem.

The implementation principle is as follows: All servers use the communication protocol provided by Chubby to create the same file on the Chubby Server. Eventually, of course, only one server is allowed to create the file. This server becomes the master and writes its address to the file. So that other servers can read the file and know the address of the selected master.

Distributed lock service

On another level, Chubby provides a coarse-grained distributed lock service. Chubby provides the lock function by creating a file. Creating a file to Chubby means that the server has locked the file.

Since Chubby was not open source, Yahoo! Developed a similar distributed coordination component called Zookeeper based on Chubby’s ideas, which it later donated to Apache.

Therefore, it is important to understand that ZooKeeper is not designed as a registry, it is designed as a distributed lock, and the registry is only one of the functions it can implement.

Installation and deployment of Zookeeper

The installation

Zookeeper can be run in cluster mode or click mode.

Download the zookeeper installation package: mirrors.bfsu.edu.cn/apache/zook…

The download is complete. Decompress the file using tar -zxvf

Common commands

  1. Start the ZK service:

bin/zkServer.sh start

  1. View ZK service status:

bin/zkServer.sh status

  1. Stop ZK service:

bin/zkServer.sh stop

  1. Restart the ZK service:

bin/zkServer.sh restart

  1. Connecting to the server

zkCli.sh -timeout 0 -r -server ip:port

Installation in a single-machine environment

In general, in the development test environment, without so many resources, and also does not need a particularly good stability of the premise, we can use stand-alone deployment;

When using ZooKeeper for the first time, copy the zoo_sample. CFG file in the conf directory and rename it zoo.cfg

Modify the dataDir directory, which indicates the directory where the log files are stored (additional configuration information about zoo.cfg will be covered later)

Cluster environment installation (more on this later)

In a ZooKeeper cluster, each node has three roles: leader, Follower, and Observer

Cluster mode We simulated three machines to build zooKeeper cluster. Copy the installation package to each of the three machines, unpack it, and copy a copy of zoo.cfg.

  1. Modifying a Configuration File

    1. Modify the port
    2. Server. 1=IP1:2888:3888 [2888: port to access ZooKeeper; 3888: port to re-elect the leader]
    3. Server. 2 = IP2.2888:3888
    4. Server. 3 = IP3.2888:2888
  2. Server.A=B: C: D: middle

    1. A is A number that indicates the server number;
    2. B is the IP address of the server;
    3. C represents the port through which the server exchanges information with the Leader server in the cluster.
    4. D indicates that in case the Leader server in the cluster fails, a port is needed to re-elect a new Leader, and this port is used to communicate with each other during the election. In the pseudo-cluster configuration mode, different Zookeeper instances cannot communicate with the same port number because B is the same. Therefore, they need to be assigned different port numbers.
    5. In cluster mode, each machine in a cluster needs to know which machines comprise the entire cluster. In the configuration file, each line represents a machine configuration according to the format server.id=host:port:port. Id: Indicates the server ID, which identifies the serial number of the server in the cluster
  3. Create a new datadir directory and set myID

    On each ZooKeeper machine, we need to create a myID file under the dataDir. This file contains only one line, corresponding to the Server ID number of each machine. For example, the myID file of server.1 is 1. [Make sure that the number in myID file of each server is different, and the id value is the same as that in zoo.cfg of your own machine. The ID value ranges from 1 to 255.]

  4. Start the zookeeper

Data model for Zookeeper

If we regard ZooKeeper as an in-memory database, then CRUD is to add, delete, change and check the zooKeeper in-memory database. What is the data structure of ZooKeeper? As shown in Figure 9-4, the view structure of ZooKeeper is similar to that of a standard file system. Each node is called a ZNode and is the smallest unit of ZooKeeper. Each ZNode can store data and mount child nodes to form a hierarchical tree structure

The node type

Zookeeper contains four types of nodes, described as follows:

Persistent node

Persistent nodes can be subdivided into two types:

  • PERSISTENT: PERSISTENT, which is not automatically deleted when a client is disconnected. The default type is PERSISTENT, as shown in Figure 9-5

    Figure 9 to 5

  • PERSISTENT_SEQUENTIAL: Sequential persistence, with a monotonically increasing number appended to the name of a Znode, as shown in Figure 9-6

Temporary node

  • EPHEMERAL: the EPHEMERAL node is automatically deleted when the Client is disconnected. As shown in Figure 9-6, if the Client created /Server1 and /Server2 nodes, after the session of the Client is disconnected, the two nodes are automatically deleted by Zookeeper.

    Figure 9-6

  • EPHEMERAL_SEQUENTIAL: A temporary node with a sequential number. The name of a Znode is appended by a monotonically increasing number, as shown in Figure 9-7

Note that temporary nodes cannot have child nodes

The Container node

CONTAINER: The CONTAINER node is a special purpose node. It is designed for Leader and Lock operations. When the last child node of the CONTAINER node is deleted, the CONTAINER node will be marked and deleted after a period of time.

Because the container node this feature, so that when we create a child node under the container node, the need to capture KeeperException NoNodeException abnormalities, if catch exceptions to this, you need to create a container node.

TTL node

If a node is set to the TTL node type, it will be deleted after a period of time when the node is not modified and has no child nodes within the specified TTL time (milliseconds).

  • PERSISTENT_WITH_TTL: Extension type of ZooKeeper that, if a Znode has not been modified within a given TTL, will be deleted when there are no children. In a zookeeper is a must to use this type, bin/zkService. Start the zookeeper in sh Java environment set the environment variable zookeeper. ExtendedTypesEnabled = true (particular way below), Otherwise KeeperErrorCode = Unimplemented for /**.

Set the zookeeper. ExtendedTypesEnabled = true

Open a zookeeper Bin/zkServer. Sh (win is zkService. CMD), modify the start they command, and * * – Dzookeeper. ExtendedTypesEnabled = true * *, which is set an environment variable in Java.

  nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
      "-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.extendedTypesEnabled=true" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
      -XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' \
      -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
                                                                                         
Copy the code
  • PERSISTENT_SEQUENTIAL_WITH_TTL: PERSISTENT_SEQUENTIAL_WITH_TTL

Zookeeper operation commands

Create a node

create [-s] [-e] [-c] [-t ttl] path [data] [acl]
Copy the code

[-s] : sequential serialization, that is, it can be created repeatedly, with the sequence number followed by the path

[-e] : Ephemeral, ephemeral after being disconnected

[-c] : indicates a container node.

[-t TTL] : indicates TTL Nodes (Nodes with timeout).

[ACL] : a permission is created for the node. If the permission is created, only those with the permission can access the node

Remove nodes

Delete a node. -v indicates the version number to implement the optimistic lock mechanism

delete [-v version] path
Copy the code

Update the node

Assign the node value -s returns the node status

set [-s] [-v version] path data
Copy the code

Querying Node Information

Gets the value of the specified node

get [-s] [-w] path
Copy the code

Node status stat

In addition to storing data, a node stores some status information about the data node. You can run the get command to obtain details about the status information, as shown in Figure 9-8.

Versioning – Ensures atomicity of distributed data

Zookeeper introduces the concept of version for data nodes. Each data node has three versions. Any update operation on the data node will cause the version number to change

The version is somewhat similar to the optimistic lock we often use. There are two concepts here, an optimistic lock and a pessimistic lock

Pessimistic locking: is a very typical and very strict concurrency control strategy in databases. If A transaction A is processing data, the data will be locked for the entire process, during which no other transaction can update the data.

Lock: lock optimistic and pessimistic locking is just idea, it is assumed that multiple transactions will not affect each other in the process, so don’t need to lock in the process of transaction processing, if more than one transaction on the same data do change, so before the update request submission, each transaction will first check the current transaction after reading data, if there are other issues to modify data. If there are changes, the transaction is rolled back

Back to ZooKeeper, the Version attribute is the “write check” used to implement optimistic locking.

Watcher listens for node events

Zookeeper provides a publish/subscribe function for distributed data. Zookeeper allows clients to register a Watcher listener with the server. When the server triggers the Watcher, the server sends an event notification to the client. Zookeeper provides the following commands to configure listening on a specified node.

  • Get [-s] [-w] path: listens for the modification and deletion events of the specified path node. This event is also triggered once.
  get -w /node
  #Running the following command in another window triggers related events
  set /node 123
  delete /node
Copy the code
  • Ls [-s] [-w] [-r] path: monitors the add and delete events of children of a specified path.
  ls -w /node
  #Running the following command in another window triggers related events
  create /node/node1
  delete /node/node1
Copy the code

Note: The current command sets the listener to be one-time, meaning that once an event listener is triggered, subsequent events do not respond. Of course we can solve this by repeating subscriptions

  • Stat [-w] path: has the same function as get.

  • addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] – default is PERSISTENT_RECURSIVE

    AddWatch is used to add event listeners for a specified node. It supports two modes

    • PERSISTENT, PERSISTENT subscriptions, modification and deletion events for the current node, and deletion and addition events for the children of the current node.
    • PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT), PERSISTENT_RECURSIVE (PERSISTENT)

Session Session mechanism

Figure 9-10 shows the Session status mechanism of Zookeeper.

  • First, the client initiates a connection request to the Zookeeper Server in the CONNECTING state
  • After the connection is established, the Session status changes to CONNECTED, and data I/O operations can be performed.
  • If the connection between the Client and Server is lost, the Client state becomes CONNECTING
  • If the session expires or the connection is closed, the connection status is CLOSE
  • If the authentication fails, end directly

Application scenarios of Zookeeper

Configuration center

Programs always need to be configured, and if they are distributed across multiple machines, it becomes difficult to change the configuration one by one. All right, now you put these configurations on ZooKeeper, save them in a directory node of ZooKeeper, and then all the related applications listen to this directory node, and each application gets notified by ZooKeeper whenever the configuration information changes. Then get the new configuration information from Zookeeper and apply it to the system.

Service Registry

As shown in Figure 9-12, Zookeeper can be used to implement a service registry. In simple terms, Zookeeper manages the address of the target server. Before invoking the target server, the client obtains the address from Zookeeper for access.

A distributed lock

Orderly use of temporary node to realize distributed lock, as shown in figure 9-13, each App node to preempt the distributed lock, can go to the node creates a temporary orderly Zookeeper, node’s smallest said the client got a lock and other client to wait for, not get locked until get the lock of the client to remove the node or disconnect session.