Zk (zookeeper) implementation of distributed locks

Zk (zookeeper) implementation of distributed locks

Like it and look again, develop a habit, search on WeChat [San Tai Zi Ao Bing] to follow this Internet tool man.
This article has been included on GitHub https://github.com/JavaFamily , with the complete test sites, materials and my series of articles for interviews with major companies.

Preface

I don’t think I need to say too much about the lock, everyone knows what’s going on, right?

In a multi-threaded environment, due to context switching, data may be inconsistent or polluted. We need to ensure data security, so we thought of locking.

The so-called locking mechanism is that when a thread accesses a certain data of this type, it is protected, and other threads cannot access it. Other threads can not use it until the thread has read it.

Remember I said before that Redis needs to lock data with concurrent contention when it is distributed. Husbands are very puzzled. Is Redis single-threaded? Why do we need to lock it?

It seems that the husbands are still young, and the situation you said does not need to be locked is this:
Zk (zookeeper) implementation of distributed locks

When a single service accesses Redis, it is true that Redis itself is single-threaded so that thread safety does not need to be considered. However, which company is still stand-alone now? They must be distributed clusters.

Husbands, see if there is a problem with this scene:

Don’t you often say spikes, if you get the inventory judgment, the wife tells you that there will be problems with the distributed situation.
Zk (zookeeper) implementation of distributed locks

In order to reduce the pressure on DB, we preheated the inventory to KV. Now the inventory of KV is 1.

  1. Service A goes to Redis and finds that the inventory is 1, which means I can grab this item, right? Then I am going to reduce it by one, but it has not been reduced yet.
  2. At the same time, Service B also went to get it and found that it was also 1. Then I grabbed it, so I also reduced it.
    C is the same.
  3. After all the services are judged, you find out, how come it has become -2, it's oversold, it's over.
  4. Husbands have discovered the problem? This requires the intervention of distributed locks. I will introduce the three implementations of distributed locks (Zookeeper, Redis, MySQL) in three chapters, and tell their advantages and disadvantages. And the practice scenes of general large factories.

text

A sulky interviewer walked in without taking anything. You see, this is not your wife. When you are about to call him, you find that he has a serious face and the dead ghost pretends to be serious. Let me release the water.

Zk (zookeeper) implementation of distributed locks
Ahem, let's not say anything, let's start today's interview.
What are the mechanisms for normal thread process synchronization?

  • Mutual exclusion: The mechanism of mutual exclusion ensures that only one thread can operate shared resources synchronized, Lock, etc. at the same time.
  • Critical value: let multi-threaded serial call access resources
  • Event notification: through event notification to ensure that everyone accesses shared resources in an orderly manner
  • Semaphore: access to multiple tasks at the same time, while limiting the number, such as the starting gun CDL, Semaphore, etc.

What do you know about distributed locks?

The implementation of distributed locks is mainly based on Zookeeper (hereinafter referred to as zk), Redis, and MySQL.

Then let me talk about zk first, can you talk about his common usage scenarios?

His main application scenarios are as follows:

  • Service registration and subscription (shared node)
  • Distributed notification (monitoring znode)
  • Service naming (znode feature)
  • Data subscription and release (watcher)
  • Distributed lock (temporary node)

What is zk?

He is a database, file storage system, and has a monitoring notification mechanism (observer mode)

Save the file system, what did he save?

node

There are 4 types of zk nodes

  • Persistent node (the zk disconnected node is still there)
  • Persistent sequence number directory node
  • Temporary directory node (the node is deleted after the client is disconnected)
  • Temporary Directory Number Directory Node

The node names are all unique.

How to create a node?

Am I special, do you ask? But I only looked at distributed locks in the interview, I have to think about it! ! !

Fortunately, I set up a zk cluster on my own server before, and I just happened to recall a wave with you.

create /test laogong // 创建永久节点 

Zk (zookeeper) implementation of distributed locks

What about temporary nodes?

create -e /test laogong // 创建临时节点

Zk (zookeeper) implementation of distributed locks
The temporary node was created successfully. If I disconnect this link, the node will naturally disappear. This is one of my zk management tools, and the directory may be clearer.
Zk (zookeeper) implementation of distributed locks

How to create sequential nodes?

create -s /test // 创建顺序节点

Zk (zookeeper) implementation of distributed locks

What about temporary sequence nodes?

I think a smart husband will answer

create -e -s /test  // 创建临时顺序节点

Zk (zookeeper) implementation of distributed locks
After logging out, I reconnected and found that all the temporary nodes I just created were gone.
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks

There are so many demos at the beginning. I just want to show you the general operation process and data structure of zk. I will not talk about the construction and other skills involved. Let’s focus on his implementation in distributed locks. .

zk implements various distributed locks based on nodes.

Take the scene at the beginning, how should zk ensure thread safety in distributed situations? How does he control concurrent competition?

In order to simulate the situation of concurrent competition, I wrote some pseudo-code, you can take a look first
Zk (zookeeper) implementation of distributed locks

I defined an inventory with an inventory value of 1, and also used a CountDownLatch starting gun, and deducted the inventory together after 10 threads were ready.

Is it like 10 machines to get the inventory together, and then deduct the inventory?

All the machines were taken together, and found that they were all 1, so everyone thought they had grabbed them, and they all did a minus one operation, but when everyone finished executing, and then set the value, they found that they were actually oversold. I will print it out for everyone to see.
Zk (zookeeper) implementation of distributed locks

Yes, this is not a problem of one or two oversolds. There are 7 oversolds. The code clearly judges that the inventory is greater than 0 before reducing it. I explained what happened at the beginning.

How to solve this problem?

Sync and lock can only guarantee the thread safety of your current machine, so distributed access is still problematic.
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks

The zk node mentioned above can solve this problem.

The unique feature of the zk node is that we have created this node. If you create a zk again, an error will be reported. Then we will use its uniqueness to achieve it.
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks

How to achieve it?

Aren’t there 10 threads on it?

Let's create them all. The first one that is successfully created returns true and he can continue the following deduction operations. Subsequent node visits will all report errors, and the deduction will fail. We put them in a queue to queue.

How to release the lock?

Delete the node, delete it and notify other people to come and lock it, and so on.

Let's realize the scenario of zk locking.
Zk (zookeeper) implementation of distributed locks

Isn't it? Only the first thread can successfully deduct, and the others fail.

But you find that the problem is not there. You have added the lock and you have to release it. If you don't release the following error, you won't try again.

That's simple, the delete lock is released, and the Lock is unLock in finally. Now we are finally deleting the node.

We know that creating a node is enough for locking, but you have to achieve a blocking effect, what's the matter?

Endless loop, recursively keep trying until it succeeds, a disguised blocking effect.

How do you know that the previous brother deleted the node?

Monitor node deletion event
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks
Zk (zookeeper) implementation of distributed locks

But did you find any problems with this?

Yes, there will be deadlocks.

The first one is successfully locked. When the code is executed, the machine is down. Can the node be deleted?

You have to pretend to be contemplative, ask and answer yourself, sometimes look at the distance, sometimes look at the interviewer, and pretend you don't know anything.

Oh, I remember, just create a temporary node. Once the client connection is disconnected, other changes can be monitored.

Hmm, it's not bad, so do you find any other problems?

It seems that this monitoring mechanism is not good.

What's wrong?

As you can see, monitoring means that all services monitor a node. The release of the node will also notify all servers. What if it is 900 servers?

This is a big challenge for the server. A release message is like a shepherd dog has entered the flock. Everyone is scattered and may kill the machine at any time, which will occupy service resources, network bandwidth and so on.

This is the herd effect.
Zk (zookeeper) implementation of distributed locks

How to solve this problem?

Continue pretending to be contemplative, ah, ah, so hard, my head. . . .

Don't pretend you TM, OK?

Okay, the temporary sequence node can solve this problem smoothly.

How to realize your husband, don't look down, think for yourself first.

I said before that it is a big problem to listen to one node. Then we will listen to our previous node. Because it is sequential, it is easy to find before and after ourselves.
Zk (zookeeper) implementation of distributed locks

The difference from the previous monitoring of a permanent node is that each node here only monitors its previous node. Of course, the release is also released one by one, and there will be no herd effect.
Zk (zookeeper) implementation of distributed locks

I will open source all the above code to my https://github.com/AobingJava/Thanos. Actually, there are still flaws in the above. You can pull it down and change it and submit the pr. I will pass the appropriate one.

You have said so much, which is pretty good. Can you talk about some shortcomings of ZK's practice in distributed locks?

Zk performance may not be as high as the cache service.

Because each time in the process of creating and releasing locks, instantaneous nodes must be dynamically created and destroyed to realize the lock function.

The creation and deletion of nodes in ZK can only be performed through the Leader server, and then the data is synchronized to all Follower machines. (The knowledge of zk cluster is involved here, I won't expand it, and I will talk to my husband in detail in the zk chapter)

Anymore?

Using Zookeeper may also bring concurrency problems, but it is not common.

Due to network jitter, the session connection of the client can be disconnected from the ZK cluster. Then zk thinks that the client is hung up, and will delete the temporary node. At this time, other clients can obtain the distributed lock.

Concurrency problems may occur. This problem is not common because zk has a retry mechanism. Once the zk cluster fails to detect the client's heartbeat, it will retry. The Curator client supports multiple retry strategies.

The temporary node will be deleted if it fails after several retries.

Tip: Therefore, it is also important to choose a suitable retry strategy. It is necessary to find a balance between lock granularity and concurrency.

Is there a better implementation?

Redis-based distributed lock

Can you talk to me?

I looked at the watch in my hand, my husband, it's getting late today, and you have finished all the questions. Why should I add more articles?

It's really late, so you go home and do the housework, right?

I? ? ? ?
Zk (zookeeper) implementation of distributed locks

to sum up

Zk solves the deadlock problem through temporary nodes. Once the client suddenly hangs up after acquiring the lock (Session connection is disconnected), then this temporary node will be automatically deleted, and other clients will automatically acquire the lock.

Zk also realizes the principle of blocking through the mechanism of node queue monitoring, which is actually a process of recursively waiting infinitely for the release of the smallest node.

I did not implement lock reentrancy above, but it is also very easy to implement. You can bring thread information or unique identifiers such as machine information. Please judge when you get it.

The zk cluster is also highly available, as long as more than half of the clusters can provide external services.

This week, I will finish writing distributed locks for Redis and databases. Husbands wait.

I'm Ao Bing, a tool man who has survived on the Internet.

The best relationship is mutual achievement. The "three consecutive" of my husbands is the greatest motivation for Bingbing's creation. See you in the next issue!

Note: If there are any mistakes or suggestions in this blog, you are welcome to leave a message, husband, please say something!

The article is continuously updated. You can search for "San Taizi Ao Bing" on WeChat to read it as soon as possible. I have prepared interview materials and resume templates for first-line companies. This article has been included on GitHub https://github.com/JavaFamily , and the interviews with major companies are complete. Test site, welcome Star.

The more you know, the more you don’t know

Guess you like

Origin blog.51cto.com/14689292/2546555