浅谈redis实现的分布式锁

/**
 * Created by BingZhong on 2017/7/29.
 *
 * 基于Redis实现的分布式锁
 */
public final class RedisLockHelper {

    private static Logger logger = LoggerFactory.getLogger(RedisLockHelper.class);

    /**
     * redis操作帮助类,可以是其他封装了redis操作的类
     */
    private RedisHelper redisHelper;

    public static final long DEFAULT_TIMEOUT = 30 * 1000;

    public static final long DEFAULT_SLEEP_TIME = 100;

    private RedisLockHelper(RedisHelper redisHelper) {
        this.redisHelper = redisHelper;
    }

    public static RedisLockHelper getInstance(RedisHelper redisHelper) {
        return new RedisLockHelper(redisHelper);
    }

    /**
     * 创建锁
     *
     * @param mutex     互斥量
     * @param timeout   锁的超时时间
     * @param sleepTime 线程自旋尝试获取锁时的休眠时间
     * @param timeUnit  时间单位
     */
    public RedisLock newLock(String mutex, long timeout, long sleepTime, TimeUnit timeUnit) {
        logger.info("创建分布式锁,互斥量为{}", mutex);
        return new RedisLock(mutex, timeout, sleepTime, timeUnit);
    }

    public RedisLock newLock(String mutex, long timeout, TimeUnit timeUnit) {
        return newLock(mutex, timeout, DEFAULT_SLEEP_TIME, timeUnit);
    }

    public RedisLock newLock(String mutex) {
        return newLock(mutex, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
    }

    public class RedisLock {
        /**
         * 用于创建redis健值对的键,相当于互斥量
         */
        private final String mutex;

        /**
         * 锁过期的绝对时间
         */
        private volatile long lockExpiresTime = 0;

        /**
         * 锁的超时时间
         */
        private final long timeout;

        /**
         * 每次循环获取锁的休眠时间
         */
        private final long sleepTime;

        /**
         * 锁的线程持有者
         */
        private volatile Thread lockHolder = null;

        private final ReentrantLock threadLock = new ReentrantLock();

        public RedisLock(String mutex, long timeout, long sleepTime, TimeUnit timeUnit) {
            this.mutex = mutex;
            this.timeout = timeUnit.toMillis(timeout);
            this.sleepTime = timeUnit.toMillis(sleepTime);
        }

        /**
         * 加锁,将会一直尝试获取锁,直到超时
         */
        public boolean lock(long acquireTimeout, TimeUnit timeUnit) throws InterruptedException {
            acquireTimeout = timeUnit.toMillis(acquireTimeout);
            long acquireTime = acquireTimeout + System.currentTimeMillis();
            threadLock.tryLock(acquireTimeout, timeUnit);
            try {
                while (true) {
                    boolean hasLock = tryLock();
                    if (hasLock) {
                        //获取锁成功
                        return true;
                    } else if (acquireTime < System.currentTimeMillis()) {
                        break;
                    }
                    Thread.sleep(sleepTime);
                }
            } finally {
                if (threadLock.isHeldByCurrentThread()) {
                    threadLock.unlock();
                }
            }

            return false;
        }

        /**
         * 尝试获取锁,无论是否获取到锁都将直接返回而不会阻塞
         * 不支持重入锁
         */
        public boolean tryLock() {
            if (lockHolder == Thread.currentThread()) {
                throw new IllegalMonitorStateException("不支持重入锁");
            }
            long currentTime = System.currentTimeMillis();
            String expires = String.valueOf(timeout + currentTime);
            //尝试设置互斥量
            if (redisHelper.setNx(mutex, expires) > 0) {
                setLockStatus(expires);
                return true;
            } else {
                String currentLockTime = redisHelper.get(mutex);
                //检查锁是否超时
                if (Objects.nonNull(currentLockTime) && Long.parseLong(currentLockTime) < currentTime) {
                    //获取旧的锁时间并设置互斥量
                    String oldLockTime = redisHelper.getSet(mutex, expires);
                    //判断获取到的旧值是否一致,不一致证明已经有另外的进程(线程)成功获取到了锁
                    if (Objects.nonNull(oldLockTime) && Objects.equals(oldLockTime, currentLockTime)) {
                        setLockStatus(expires);
                        return true;
                    }
                }

                return false;
            }
        }

        /**
         * 该锁是否被锁住
         */
        public boolean isLock() {
            String currentLockTime = redisHelper.get(mutex);
            //存在互斥量且锁还为过时即锁住
            return Objects.nonNull(currentLockTime) && Long.parseLong(currentLockTime) > System.currentTimeMillis();
        }

        public String getMutex() {
            return mutex;
        }

        /**
         * 解锁
         */
        public boolean unlock() {
            //只有锁的持有线程才能解锁
            if (lockHolder == Thread.currentThread()) {
                //判断锁是否超时,没有超时才将互斥量删除
                if (lockExpiresTime > System.currentTimeMillis()) {
                    redisHelper.del(mutex);
                    logger.info("删除互斥量[{}]", mutex);
                }
                lockHolder = null;
                logger.info("释放[{}]锁成功", mutex);

                return true;
            } else {
                throw new IllegalMonitorStateException("没有获取到锁的线程无法执行解锁操作");
            }
        }

        private void setLockStatus(String expires) {
            lockExpiresTime = Long.parseLong(expires);
            lockHolder = Thread.currentThread();
            logger.info("获取[{}]锁成功", mutex);
        }
    }
}

数据中心机房是现代信息技术的核心设施,它承载着企业的重要数据和服务,因此,其基础设计与规划至关重要。在制定这样的方案时,需要考虑的因素繁多,包括但不限于以下几点: 1. **容量规划**:必须根据业务需求预测未来几年的数据处理和存储需求,合理规划机房的规模和设备容量。这涉及到服务器的数量、存储设备的容量以及网络带宽的需求等。 2. **电力供应**:数据中心是能源消耗大户,因此电力供应设计是关键。要考虑不间断电源(UPS)、备用发电机的容量,以及高效节能的电力分配系统,确保电力的稳定供应并降低能耗。 3. **冷却系统**:由于设备密集运行,散热问题不容忽视。合理的空调布局和冷却系统设计可以有效控制机房温度,避免设备过热引发故障。 4. **物理安全**:包括防火、防盗、防震、防潮等措施。需要设计防火分区、安装烟雾探测和自动灭火系统,设置访问控制系统,确保只有授权人员能进入。 5. **网络架构**:规划高速、稳定、冗余的网络架构,考虑使用光纤、以太网等技术,构建层次化网络,保证数据传输的高效性和安全性。 6. **运维管理**:设计易于管理和维护的IT基础设施,例如模块化设计便于扩展,集中监控系统可以实时查看设备状态,及时发现并解决问题。 7. **绿色数据中心**:随着环保意识的提升,绿色数据中心成为趋势。采用节能设备,利用自然冷源,以及优化能源管理策略,实现低能耗和低碳排放。 8. **灾难恢复**:考虑备份和恢复策略,建立异地灾备中心,确保在主数据中心发生故障时,业务能够快速恢复。 9. **法规遵从**:需遵循国家和地区的相关法律法规,如信息安全、数据保护和环境保护等,确保数据中心的合法运营。 10. **扩展性**:设计时应考虑到未来的业务发展和技术进步,保证机房有充足的扩展空间和升级能力。 技术创新在数据中心机房基础设计及规划方案中扮演了重要角色。例如,采用虚拟化技术可以提高硬件资源利用率,软件定义网络(SDN)提供更灵活的网络管理,人工智能和机器学习则有助于优化能源管理和故障预测。 总结来说,一个完整且高效的数据中心机房设计及规划方案,不仅需要满足当前的技术需求和业务目标,还需要具备前瞻性和可持续性,以适应快速变化的IT环境和未来可能的技术革新。同时,也要注重经济效益,平衡投资成本与长期运营成本,实现数据中心的高效、安全和绿色运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十点摆码

有用你就打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值