Redis分布式锁原理及性能优化

分布式锁是什么

在单体架构中,系统只有一个,系统所用的内存和进程也只有一个,多个线程可以共享同一份数据。这样只要使用java提供的锁机制就可以解决并发访问带来的问题,但是分布式系统中,系统是多个,并且所使用的内存也是不同的,每个系统也都有独立的进程,这样Java提供的锁就没办法解决分布式系统中的并发访问问题。因此就需要引入分布式锁来解决分布式系统中共享资源访问的问题。

分布式锁的特性

  • 要保证同一时刻内,只有一个服务获取到这个锁
  • 这把锁要能重入,在某些业务下会出现同一把锁的重入
  • 具备锁续命,保证高并发下不会因锁的时效问题引起数据错误
  • 具有非阻塞式获取锁,在获取锁失败后立刻返回

基于Redisson实现的分布式锁

分布式锁失效问题

当主从或集群机构的主节点挂掉后,该节点存储的分布式锁信息可能会丢失。而当从节点选举成新节点后,其它线程又可以对新的主节点进行添加分布式锁信息,这就会引起并发安全问题。

  • 为了解决这个问题,就引入了redlock。

    redlock的逻辑就是向多个节点写入加锁的信息,如果写入成功,加代表加锁成功。但是如果写入的节点丢失了锁的信息,仍然是会出现分布式锁失效问题。
    还有一点就是性能问题,我们使用redis就是为了它的高性能,但是使用redlock后每次加锁都要写入多个节点,这就会降低redis性能,这样还不如使用zookeeper。

Redisson实现分布式锁源码剖析

  • 加锁核心逻辑
  • 加锁成功后的锁续命逻辑

  • 其它线程加锁失败后的逻辑:
  • 解锁核心逻辑:

分布式锁的优化

  • 对于读多写少的业务,可以使用readwirte锁:
public Product update(Product product) {
    Product productResult = null;
    // 获取分布式锁
    RReadWriteLock readWriteLock = redisson.getReadWriteLock(LOCK_PRODUCT_UPDATE_PREFIX + product.getId());
    // 写锁
    RLock writeLock = readWriteLock.writeLock();
    // 加锁
    writeLock.lock();
    try {
        productResult = productDao.update(product);
        // 设置过期时间
        redisUtil.set(productResult.getId(), JSON.toJSONString(productResult),
                genProductCacheTimeout(), TimeUnit.SECONDS);
    } finally {
        // 释放锁
        writeLock.unlock();
    }
    return productResult;
}

redisson实现的读写锁,大体上和上面的分布式锁逻辑相同,只是加了一个mode,用于区分是读还是写。对于读读而言,就等于是锁的重入,不会阻塞;对于读写、写写操作,就会阻塞保证并发的安全。

缓存问题

  • 什么是缓存击穿?

    当同一时刻有大量的缓存失效,就会导致大量的请求打到数据库,会造成数据库压力过大甚至宕机。

    解决办法:在给缓存数据设置过期时间时,增加一个随机的扰动因子,避免让大量的缓存数据都同一时刻失效。

  • 什么是缓存穿透?

    缓存层和数据库都没有数据,每次请求都会落到数据库,如果是高并发场景下,就会引起数据的压力剧增,甚至宕机。

    解决办法:
    1、对于不存在的数据,可以在缓存层面设置对应key的空值
    2、布隆过滤器,向布隆过滤器中添加key时,会先使用多个hash函数进行运算,然后定位到布隆过滤器的数组中某个下标。当某个key查询布隆过滤器数据时,会同样使用多个hash函数进行运算,然后得到数组中的下标位置。

  • 什么是缓存雪崩?

    缓存层的作用就是分担数据库层面的压力,如果缓存层宕机,大量的请求就直接打到数据库,高并发下数据库有可能宕机。

    解决办法:
    1、确保缓存层的高可用,比如搭建集群、主从架构
    2、在后端应用上设置限流或服务降级

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值