Redis分布式锁

8 篇文章 0 订阅
1 篇文章 0 订阅

Redis分布式锁 (jedis)

1.针对场景

分布式集群,例如MR 多个节点上的不同jvm。 传统的多线程仅针对同一jvm下的操作。如果跨节点的数据锁问题需要另外的支持分布式锁的库来处理。例如zookeeper 或 redis 天生对分布式场景有良好的适性。

2.业务需求

一般用于一些统计业务,需要求取每个节点上的数据总和。分布式场景带来的并发问题需要利用redis分布式锁处理。

3.核心代码

private static String key="monitorESErrorCount";
private static int count=0;

/**
 * 
 * 功能: 利用redis分布式锁 做数据统计
 * @param lockName  可以为共享变量名,也可以为方法名,主要是用于模拟锁信息
 * @return
 */
public boolean lock(String lockName) {
    Long result = redisDao.setNx(lockName, String.valueOf(System.currentTimeMillis() + 5000));
    // jedisCluster.setnx(key, value)
    // 使用jedis接口 获取值 当且仅当key存在 赋予值 并返回1 否则不错任何操作 返回0
    if (result != null && result.intValue() == 1) {
        // 运行至此 说明已经有人抢到了这把锁 而其他人不会进入此处
        System.out.println(Thread.currentThread() + "加锁成功!");
        // 设置该锁过期时间 5s 防止redis崩坏造成死锁 只需要比业务逻辑代码执行时间稍长一点即可
        redisDao.expire(lockName, 5);
        // 此处开始处理业务逻辑 示例为获取随机数 累和
        if (redisDao.get(key) != null) {
            // 获取redis中的缓存值
            Long errorCount = Long.parseLong(redisDao.get(key));
            int n = (int) (Math.random() * 1000);
            errorCount += n;
            count += n;
            // 删除之前的key
            redisDao.del(key);
            // 重新赋予key的值
            redisDao.setNx(key, "" + errorCount);
        } else {
            // 当redis中还没有开始计数时
            int n = (int) (Math.random() * 1000);
            count += n;
            redisDao.setNx(key, "" + n);
        }
        // 全部执行完毕后 删除锁
        redisDao.del(lockName);
        return true;
    } else {
        return false;
    }
}

其中redisDao为自己封装的redis连接池 用于控制连接数等其他 实现了最基础的 expire setNx get 等方法 (即直接调用jedis内api) 在此就不贴出连接池相关代码。

4.原理解释

在每次做合并的时候将值根据redis内的缓存值进行累加,其内置的分布式锁可确保每次只有一个人获取到这把锁,其余人等待。 只要redis中还存在lock对应key value 则其他人无法处理业务涉及的值。删除lock 后其他人才能够继续获取。 对于MR来说,只需要在reduce最后阶段 while(lock(“DistributionLock”)) 即可,将全局变量count累和存入redis中并避免了分布式造成的并发问题。

5.缺点

每次锁的确认相当于请求了一次redis,需要对请求控制,例如100ms内只做一次request 避免高频访问给redis带来压力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值