美文网首页
Redis 分布式锁

Redis 分布式锁

作者: Ludwigvan | 来源:发表于2018-11-21 14:08 被阅读9次

    Redis 分布式锁

    前言

    分布式锁一般有三种实现方式:1. 数据库乐观锁;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。虽然网上已经有各种介绍Redis分布式锁实现的博客,然而他们的实现却有着各种各样的问题,为了避免误人子弟,本篇博客将详细介绍如何正确地实现Redis分布式锁。

    可靠性

    首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:

    互斥性。在任意时刻,只有一个客户端能持有锁。
    不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
    具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
    解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

    代码实现

       /**
         * 最终加强分布式锁
         *
         * @param key key值
         * @return 是否获取到
         */
         
        public static final String LOCK_PREFIX = "redis_lock";
         
        public boolean lock(String key) {
            String lock = LOCK_PREFIX + key;
            // 利用lambda表达式
            return (Boolean) redisTemplate.execute(new RedisCallback<Object>() {
                @Override
                public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                    long expireAt = System.currentTimeMillis() + LOCK_EXPIRE + 1;
                    Boolean acquire = redisConnection.setNX(lock.getBytes(), String.valueOf(expireAt).getBytes());
                    if (acquire) {
                        return true;
                    } else {
                        byte[] value = redisConnection.get(lock.getBytes());
                        if (Objects.nonNull(value) && value.length > 0) {
                            long expireTime = Long.parseLong(new String(value));
                            if (expireTime < System.currentTimeMillis()) {
                                // 如果锁已经过期
                                byte[] oldValue = redisConnection.getSet(lock.getBytes(), String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE + 1).getBytes());
                                // 防止死锁
                                return Long.parseLong(new String(oldValue)) < System.currentTimeMillis();
                            }
                        }
                    }
                    return false;
                }
            });
        }
    

    如果你的项目中Redis是多机部署的,那么可以尝试使用Redisson实现分布式锁,这是Redis官方提供的Java组件。

    相关文章

      网友评论

          本文标题:Redis 分布式锁

          本文链接:https://www.haomeiwen.com/subject/pdqcqqtx.html