Learn about Zookeeper
If you’re not familiar with Zookeeper, this is probably a good place to start
Zookeeper is a distributed coordination service that can be used for metadata management, distributed locking, distributed coordination, publishing and subscribing, service naming, and more.
For example, Kafka uses Zookeeper to store metadata related to its cluster, such as brokers, topics, partitions, and so on. At the same time, Watch monitoring mechanism based on Zookeeper can also be used to realize publishing and subscription functions.
In normal business usage scenarios, we almost exclusively use distributed locks.
Internal running mechanism of Zookeeper
The underlying storage principle of Zookeeper is similar to that of the file system in Linux. Each file in the Zookeeper file system is a Znode. Based on the hierarchical relationship between files, Zookeeper creates this file tree.
In Linux, files (nodes) are actually classified into types, such as files and directories. In Zookeeper, Znode has the same type. In Zookeeper, all node types are as follows:
- Persistent nodes
- Persistent Sequential nodes
- Ephemeral nodes
- Ephemeral Sequential nodes
A persistent node is just like creating a new file on your computer. It exists until you delete it.
In addition to inheriting the characteristics of the persistent node, the persistent sequential node also guarantees the sequence order for the child nodes created under it, and automatically adds the 10-digit auto-increment sequence number to the node name to ensure the uniqueness of the node name. This is already exemplified in subfiles above.
The life cycle of the temporary node is related to whether the client is active. If the client is disconnected, the node (which can be understood as a file) will be deleted, and the temporary node cannot create child nodes.
PS: The disconnection here is actually not the disconnection we intuitively understand. Zookeeper has its Session mechanism. When a client’s Session expires, all nodes created by the corresponding client will be deleted
Zookeeper node creation method
Let’s take a look at each of these nodes and give a few simple examples.
Creating a persistent Node
Create /node_name Full stack note of SHCopy the code
Note that all node names in the command must start with a slash (/); otherwise, the creation will fail. In Zookeeper, you cannot use relative paths, but must use absolute paths.
Create a persistent order node
Create -s /node_name Full stack note of SHCopy the code
As you can see, Zookeeper automatically adds a 10-digit suffix to the key.
Creating temporary Nodes
Create-e /test full stack note of SHCopy the code
Create temporary order nodes
Create-e -s /node_name Full stack note of SHCopy the code
The purpose of the Zookeeper
Let’s take a look at some concrete examples of how Zookeeper can be used in more detail than just as a distributed lock.
Metadata management
As we all know, Kafka relies on a Cluster of Zookeeper at runtime. Kafka manages cluster metadata using Zookeeper and elects the Leader using Zookeeper.
However, Zookeeper is no longer a required component in the upcoming Kafka 2.8 release. I haven’t had time to look at this yet, but I suspect it will be handled in much the same way RocketMQ handles its cluster metadata in Kafka itself.
A distributed lock
Zookeeper-based distributed lock process is very simple. First we need to know what is the nature of adding distributed locks?
The answer is to create temporary order nodes
When a client locks successfully, it actually successfully creates a temporary sequence node on Zookeeper. As we know, distributed locks enable only one person to access a resource at a time. This inevitably involves competing for distributed locks, so the question is, how does the current client perceive that the lock has been grabbed?
There is logic on the client side, assuming the lock key is /locks/ modify_USERS.
First, the client initiates a lock request, then creates a persistent node locks on Zookeeper, and then creates a temporary sequential node under that node. An example of creating a temporary sequential node is shown below.
When a client successfully creates a node, it also retrieves all nodes of its peer class. This is all the nodes modiFY_USERS000000000X shown above.
At this point, the client will judge whether the node created by itself is the smallest among all nodes according to the 10-digit increment sequence number. If it is the smallest, it obtains the distributed lock.
So what if I’m not the youngest, you ask? And my nodes are already created. If not, the current client did not grab the lock. As we know, if there is no contention for a distributed lock, then wait. What does the bottom of waiting do? Let’s go through this with a real example.
Assume that Zookeeper already has the following nodes.
For example, if the current client is B and modify_USERs0000000002 is the node created by B, then it is obvious that B did not grab the lock because there is already A smaller node modify_USERS0000000001 created by client A.
At this point, client B registers a listener on node modify_USERS0000000001, and any updates to the node trigger the corresponding operation.
When it is deleted, the thread of client B will be woken up. At this time, client B will judge again whether it is the node with the smallest serial numbermodify_users0000000002
Is obviously the smallest node, so client BLocking success.
To give you a more intuitive understanding of the process, I have condensed the process into the following flow chart.
Distributed coordination
As we all know, in many cases, the classical 2PC (two-stage commit) is used to ensure consistency. For example, the 2PC is used to guarantee consistency of data submitted by Redo Log and Binlog in MySQL. For details, see the MySQL crash recovery process based on Redo Log and Undo Log.
There are two roles in 2PC: Participant and Coordinator. The Coordinator schedules the execution logic of all distributed nodes ina unified manner. What is coordinated? Let me give you an example.
For example, in the Commit phase of 2PC, two participants, A and B, succeeded in committing, but unfortunately, B failed. At this point, the coordinator needs to send A the Rollback operation. Zookeeper is probably one of those roles.
Release subscription
Zookeeper has a listener (Watch) function, so publishing and subscription becomes one of Zookeeper’s applications naturally. For example, if a listener is registered on a configuration node, once the configuration changes are published, the corresponding service can sense the configuration changes in real time, so as to achieve the purpose of dynamic configuration update.
Give a simple Watch example.
The naming service
In plain English, there are two main types of naming services.
- Zookeeper simply uses the file system feature to store structured files
- Use the file feature and the sequential node feature to generate global unique identifiers
The former can be used to share specific resources on a particular business between systems, while the latter can be used to implement distributed locking.
This is the end of this blog, welcome to wechat search to follow [SH full stack notes], reply [queue] to get MQ learning materials, including basic concept analysis and RocketMQ detailed source code analysis, continue to update.
If you find this article helpful, please give it a thumbs up, a comment, a share and a comment.