This article is from: Le Byte
Access to ZooKeeper video tutorials and source documents can pay attention to the public number “Le Byte” send: 999
Secrets of client sessions
The word session, or the concept session, is useful in many ways. In ZK, a session refers to the creation of a session between two different machines after they have established a network connection. ZK session has the concept of timeout, when the session timeout, the server will take the initiative to close, of course, the client can also take the initiative to request the server to close the session. You might ask, why bother with this, just connect the two sides and keep using it? The purpose of the session concept is to prevent some clients from being used infrequently after the connection has been established. Closing the connection early saves resources.
1.1 Chicken is too beautiful a day
I found my long time no cue chicken too beautiful, this time let him again C a debut.
After getting up every day, our Jitaimei sends microblogs, broadcasts live, dances and plays basketball. She has to go to the office to handle many affairs.
So the first thing to do is to go to the office and ask Magogo (let’s say Magogo is an office for now) to use the office (make a connection, create a session)
Ma Guoguo will create an ID for Jitamei, which is the session ID. This ID (I assume 19980802) will be bound to Jitamei, and Jitamei will also have to tell Ma Guoguo how long its maximum timeout is when it is applying for Jitamei, which I assume is 6000 milliseconds.
And the Magogogo side will record:
When Magogo opened, it had a session check interval of its own, the tickTime option in zoo.cfg, which I’m assuming is 3000 milliseconds. Magogo will calculate a timeline at the start of the business, the time interval of this timeline is fixed and will not change.
Magogo will then calculate a Chitamei session timeout point by using Chitamei 6000 and the current timestamp combined with the timeline
And then it’s written down:
After recording, even if the chicken is too beautiful session created successfully.
Ma Guoguo, on the other hand, will periodically check the conversation by following the node of this timeline, assuming that the current time has reached a point in time when the chicken is too good
Magogo will retrieve all the sessions at this point in time (remember we said above, it can be multiple?).
It then finds the corresponding villagers based on their ID information and notifies them one by one that the session is closed.
Now, you might say because the chicken is so beautiful, the timeout is 6000, and the mago check is 3000, which is exactly an integer multiple, what if the timeout is not an integer multiple? Not to mention our comrade Ma Guoguo is eager to learn, he has long thought of it, so designed an algorithm, no matter what the villagers’ timeout is, will be down to find the checkpoint set by Ma Guoguo.
Let’s say the chicken is too good for 5,900
Another example is that chicken is so beautiful that the timeout is 6500
So you can see, taking Maggogo 3000 as an example, anything less than 3000 will be counted as 0, anything less than 6000 will be counted as 3000, anything less than 9000 will be counted as 6000, and so on. So as long as Maggogo’s own inspection interval is determined, Whichever villager sets any timeout can be rounded down to the nearest unified checkpoint. In this way, when the Ma Guoguo checks, there will not be too much burden, and the overtime time of the villagers can be checked uniformly.
However, this will certainly result in an incorrect (usually slightly shorter) timeout on the client side. One way to reduce this error is to reduce the tickTime parameter by decreasing the tickTime interval (the default is 2000, which is sufficient in my opinion).
And Ma Guoguo’s session management will not be the only one. Let’s see what the session management page looks like with multiple villagers
You can see that three hashes are used to record these mappings, and the timeline looks something like this
So when the time goes up to 25317,000, three villagers are out of time, and the other two villagers are out of time at 25320,000.
I should also mention that the session ID will be initialized to a base based on the current timestamp and myID when the Magogo office opens. For example, it will be 123456789 or something like that, and then every villager who comes to assign the session ID just incremutes the number by one. So there won’t be any random numbers. The numbers in the picture are just my personal meme habit and don’t match the actual situation
But isn’t that 6,000 milliseconds over every time the chicken is so beautiful? Of course, this is not possible, because every random operation of the villagers will refresh the timeout stamp. How to do this? Let’s take a look at this. Suppose the red arrow is the timeout calculated by Maguoguotai at the time the session was created. Suppose any action is performed by Maguotai at the place where the green arrow timestamp is.
The new timeout will be recalculated based on the current timestamp (green arrow) and the timeout that was set before the chicken was too beautiful (6000) :
Then I modify the data in the session management page. I still use the example of several villagers to explain
Before the update:
After the update:
This process of updating can be referred to as session activation.
1.2 Heartbeat Detection
In addition to refreshing the timeout every time the client operates normally, the client still needs a mechanism to maintain the session. This mechanism is the heartbeat detection mechanism we usually hear about. The principle is that each time the client starts up, it also sets a heartbeat detection interval. In the background, it always checks whether the last timestamp and the current time exceeded the interval of the heartbeat detection. If it did, it sends a request called PING. Since we just said that any operation on the client can refresh the timeout, PING is no exception. With this heartbeat mechanism, the client can maintain the session state with the server. The server receives a PING and simply replies a PING to the client except for the refresh timeout. The client receives a PING and simply discards it without doing anything else.
Let’s take the Java client as an example
Assuming the timeout is set to 12,000 milliseconds, the client’s heartbeat interval is 4000 milliseconds. The calculation is as follows
So whenever the client is idle for more than 4000 milliseconds, a PING will be sent to the server, and if the client timeout is set to a very large amount, such as half an hour, a PING will also be forced every 10 seconds (10 seconds is the Java client’s dead-written logic).
So much for the conversation between the client and the server, let’s talk about the conversation between the server.
Secrets of server sessions
If the village has multiple offices at the same time (I’m assuming two here), the situation is different.
Suppose Ma Xiaoyun, a Follower, is found by Jitaimei when he first connects:
Followers cannot handle non-read requests on their own, so this time Ma Xiaoyun will assign an ID to Jitailimei and forward the session creation operation to Ma Guoguo. This is just like Jitailimei finding Ma Guoguo. The process is the same as above and is noted down in the session management page.
And Ma Xiaoyun herself will also simply maintain a mapping relationship between session ID and timeout time, taking several villagers as an example, every time they receive a request, they will record it
Now jitamei is connected to ma xiaoyun office (including sending each heartbeat), but the global session management data is in ma guoguo, how can the session state be maintained in this way?
Here we need to talk about how the server heartbeat works.
The server side has one important configuration, tickTime (the default is 2000), and another important configuration, SYNClimit (the default is 5). I’ll use these two defaults as an example:
First, the Leader will PING each Follower at a rate of 1000 (tickTime / 2) milliseconds. Each time, the Leader will check whether the timeout of the PING returned by the followers is more than 10000 (tickTime *) SynClimit) to close the socket connection to the Follower after this time when no ACK response is received from the Follower
The Follower receives the PING message and replies a PING to the Leader and sends the recorded session mapping along with it
It also immediately empties its own local mapping!
Then, after receiving the PING response from the followers, the Leader can activate the session ID and timeout in the same way as in the previous example, since all the client session management data actually resides with the Leader. Through the PING between the servers, not only the heartbeat detection between the servers can be completed, but also the client session can be activated, and once again eat two fish at a time.
Session is an important concept in ZK, the state of the session will affect, the server to the client request each operation of the client will extend the session timeout, and the client will actively initiate PING request to keep the session, The client session data is stored on the Leader side to avoid being closed by the server during idle session timeout. The followers simply record the mapping relationship between the session ID and the timeout time at each operation. The heartbeat PING between the servers is initiated by the Leader to the followers. After receiving the PING, the followers will send the saved session mapping data to the followers After receiving the PING response from the followers, the Leader activates the session data sent. Now that we know the concept of a session, we can talk about temporary nodes.
3. Temporary nodes
Let’s look at the temporary node creation code first
This creation is no different from any other persistent node creation. You write a record in the little red book, and in this record there is a field called EphemeralOwner which is 0 when the node is persistent, but which is the session ID that holds the node when the node is temporary.
In addition to creating records in the small red book, since it is a temporary node, it needs to be recorded in a special place. Suppose there are three temporary nodes created again:
When the chitamei session timeouts, either the session really timeouts (which is unlikely due to the heartbeat mechanism) or the session is closed by chitamei voluntarily.
Ma Guoguo will take out the path of the corresponding temporary node from the place where the temporary node is recorded according to the session ID of Jitaimei, and then delete it according to the path. The effect is the same as the active deletion of Jitaimei. In this way, when the client is closed, the corresponding temporary node will be automatically cleared. This temporary node feature is used when ZK implements the distributed lock, preventing the client from being able to execute the lock release logic due to the unexpected exit!
The other thing I haven’t mentioned is ZK’s agreement.
As we know, ZK is the application of a client-server architecture, a client and the server, then so will the need for network communication, and not just between the client and the server, the service also requires communication between client and server, the network communication is inseparable from the agreement, but the protocol is the most important thing, is also the most unimportant things.
The most important reason is that ZK itself is based on this protocol to communicate, no matter between the client or the server. The various codes I mentioned before, such as: Request, ACK, COMMIT, PING, etc. Belong to a field in the protocol that distinguishes different messages. The protocol forms the basis of the entire ZK communication, and only the communication can complete the function of the whole component. The least important reason is that, unless you want to develop a ZK client and actively request the ZK server, even if you don’t know the specific format of the protocol at all, it will not affect your understanding of the whole principle of ZK. Moreover, the introduction of the protocol is very boring and useless, which is easy to persuade you to quit. So I’ve left this concept to the end, and I’m not going to go into what the protocol for different requests looks like in ZK. This time I will simply introduce the protocol from a different perspective.
First of all, I introduce the ZK is a Java program, both the client and the server, so is the nature of the agreement provides how to convert Java objects to the byte stream, convenient in the network transmission, and the one who get the byte stream, how to translate the word throttling back to Java objects, it is the process of serialization and deserialization. In order to facilitate serialization, various objects defined in ZK, such as XXXRequest, XXXResponse, XXXPacket, etc., usually have several field types: int, long, String, byte, List, Boolean and other nested types.
4.1 int, long, Boolean
The simplest of the three types is to write directly to the output stream. The difference is that one is 4 bytes, one is 8 bytes, and one is 1 byte
4.2 the String, byte 
If the field is empty, write a -1. If it is not empty, write an int to indicate the length, followed by byte to indicate the data
4.3 Nesting Type, List
If it is empty, write -1. If it is not empty, write -1. If it is not empty, write -1. If it is not empty, write -1.
ZK’s serialization protocol uses a compact way to write the final byte stream according to different field types.
Thank you for your recognition and support, Xiaobian will continue to forward “Le Byte” quality articles