In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
Redis in how to achieve a distributed folder lock, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.
Thinking and research
There are three common ways to realize distributed lock: database, zookeeper/etcd (temporary ordered node) and redis (setnx/lua script), each of which has its own advantages.
Database implementation of distributed Lock
The principle is simple and easy to implement. Create a lock table to store locked resources, lock objects, acquire locked resources, acquire lock time, etc. When acquiring a lock, query whether there is a record of the resource. If it exists and does not pass the expiration time, it fails to acquire the lock. If it does not exist, insert a piece of data and acquire the lock successfully. It is easier to release the lock and delete the lock data.
Shortcoming
Deadlock occurs when the lock is released and the data is deleted
Advantages
Easy to implement
Implementation of distributed Lock with zookeeper/etcd
For details, please see zookeeper Summary.
Implementation of distributed Lock with redis
For details, please see Redis Summary.
Implementation process of distributed folder lock
Based on the circumstances listed in the opening, it is difficult to cover all the complexities, but it is necessary to implement basic folder locking, so the redis+lua script is selected as follows
Java acquisition lock tool class / * redis tool class * / public class RedisLockUtils {static final Long SUCCESS = 1L; static final String LOCKED_HASH = "cs:lockedHashKey"; static final String GET_LOCK_LUA_RESOURCE = "/ lua/getFileLock.lua"; static final String RELEASE_LOCK_LUA_RESOURCE = "/ lua/releaseFileLock.lua"; static final Logger LOG = LoggerFactory.getLogger (RedisLockUtils.class) / * * obtain folder lock * @ param redisTemplate * @ param lockProjectId * @ param lockKey * @ param requestValue * @ param expireTime unit: second * @ return * / public static boolean getFileLock (RedisTemplate redisTemplate, Long lockProjectId, String lockKey, String requestValue, Integer expireTime) {LOG.info ("start run lua script, {{} start request lock", lockKey); long start = System.currentTimeMillis () DefaultRedisScript luaScript = new DefaultRedisScript (); luaScript.setLocation (new ClassPathResource (GET_LOCK_LUA_RESOURCE)); luaScript.setResultType (String.class) Object result = redisTemplate.execute (luaScript, Arrays.asList (lockKey, LOCKED_HASH + lockProjectId), requestValue, String.valueOf (expireTime), String.valueOf (System.currentTimeMillis ()); boolean getLockStatus = SUCCESS.equals (result) LOG.info ("{{}} cost time {} ms,request lock result: {}", lockKey, (System.currentTimeMillis ()-start), getLockStatus); return getLockStatus } / * release folder lock * @ param redisTemplate * @ param lockProjectId * @ param lockKey * @ param requestValue * @ return * / public static boolean releaseFileLock (RedisTemplate redisTemplate, Long lockProjectId, String lockKey, String requestValue) {DefaultRedisScript luaScript = new DefaultRedisScript (); luaScript.setLocation (new ClassPathResource (RELEASE_LOCK_LUA_RESOURCE)); luaScript.setResultType (String.class) Object result = redisTemplate.execute (luaScript, Arrays.asList (lockKey, LOCKED_HASH + lockProjectId), requestValue); boolean releaseLockStatus = SUCCESS.equals (result); LOG.info ("{{} release lock result: {}", lockKey, releaseLockStatus); return releaseLockStatus;}} lua script to get folder lock parameter description
RequestKey is the path of the request lock, requestValue is the value of the request lock, and should be the UUID generated when the lock is requested. Make sure that the unlock can only be the lock person, and lockedKeys is the key of the hash table storing all locks. Here, the constant plus item id is used to ensure that all locks of a project are stored in a hash table, expireTime is the expiration time of the lock, and nowTime is the current time. Because getting the current time in the lua script consumes performance and gets the current time on the redis server, it may not be accurate.
Train of thought explanation
First of all, use GET key to determine whether someone is operating this folder. If someone is operating, return 0 directly (failed to acquire lock), otherwise get all the key in the hash table storing the project lock, traverse all key, and compare the key and the requested key through the string.find function of the lua script. If there is an include relationship and does not expire, return 0 (failed to acquire lock). Otherwise, you can acquire the lock, set the key and expiration time and store it in the hash table (the key and request time of the request lock are stored in the hash table), and finally return 1 (the lock was acquired successfully).
For example, request the lock of the C folder under the project in the figure above. The request path is: project / An A/C/D C. When another person wants to operate the D folder, the request path is: project / A/C/D. At this time, the hash table storing all the locked key of this project is queried, which contains the project / An A/C/D C key. The two key find that the project / A/C/D contains the project / A hand C through the lua function string.find. If the expiration time is not reached, the acquisition of the lock fails, otherwise the acquisition is successful.
Local requestKey=KEYS [1] local lockedKeys=KEYS [2] local requestValue=ARGV [1] local expireTime=ARGV [2] local nowTime=ARGV [3] if redis.call ('get',requestKey) then return 0endlocal lockedHash = redis.call (' hkeys',lockedKeys) for iTunes 1, # lockedHash do if string.find (requestKey,lockedHash [I]) or string.find (lockedHash [I], requestKey) then local lockTime = redis.call ('hget',lockedKeys) LockedHash [I]) if (nowTime-lockTime) > = expireTime * 1000 then redis.call ('hdel',lockedKeys,lockedHash [I]) else return 0 end endendredis.call (' set',requestKey,requestValue) redis.call ('expire',requestKey,expireTime) redis.call (' hset',lockedKeys,requestKey,nowTime) return 1 release folder lock in parameter description
RequestKey is the path of the request lock, and requestValue is the value of the request lock, which should be the UUID generated when the lock is requested. Make sure that the unlocker can only be the locker, and lockedKeys is the key of the hash table storing all locks. Here, the constant plus item id is used to ensure that all locks of a project are stored in a hash table.
Local requestKey=KEYS [1] local lockedKeys=KEYS [2] local requestValue=ARGV [1] if redis.call ('get', requestKey) = = requestValuethen redis.call (' hdel', lockedKeys,requestKey) return redis.call ('del',requestKey) else return 0end advantages
Flexible, locking range can vary with requestKey
The performance is good. It takes a long time to cache the lua script except for the first time, and the request result can be obtained around 10ms after the second time.
Shortcoming
Reliability depends on redis
Not a reentrant lock
The maintenance cost is high, and you need to be familiar with redis's five data structures and lua scripts.
Is it helpful for you to read the above content? If you want to know more about the relevant knowledge or read more related articles, please follow the industry information channel, thank you for your support.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.