Redisson与分布式锁

一. Redis的常用客户端:

  1. Jedis:和命令最相似,API全面。缺点:多线程不安全(多线程可以使用连接池,安全使用Jedis)
  2. SpringData:线程安全的,底层基于Netty(异步的支持)
  3. Redisson:线程安全的,底层基于Netty,提供很多的分布式服务(分布式锁,分布式集合,分布式下的JUC的封装,延时队列)

二. Redis实现分布式锁
分布式锁和本地锁本质是一样的,都是将并行的操作转换为串行的操作。

  • 实现过程:
    • 利用setnx互斥性
    • 加入TTL防止死锁问题
    • 注意使用LUA脚本确保原子性
    • 加入看门狗,防止业务拿锁时间过长导致的锁失效问题(业务拿锁时间>TTL)

如果担心应用先释放锁,再加锁,再释放锁,这样做
释放锁时候,要判断只有持有锁的线程才能释放锁,需要通过本地存储的唯一性ID和redis中写入的ID。那么有两步,拿redis里ID,然后判断,所以需要使用LUA脚本保证原子性。

三. Redisson实现分布式锁
Redisson的分布式锁默认有看门狗,必须无参数方法(lock.lock()方式,这种redis的TTL默认30秒,默认10秒运行一次)。
有time参数的方法这个看门狗会失效,因为看门狗本身是一个定时任务。
如果加了参数的方法,可以判断处理业务的时间,如果>time,则可以回滚抛出异常,因为业务处理异常了。

RLock lock = redisson.getLock("myLock");
// traditional lock method
lock.lock();
// or acquire lock and automatically unlock it after 10 seconds
lock.lock(10, TimeUnit.SECONDS);
// or wait for lock aquisition up to 100 seconds 
// and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);if (res) {
   try {
     ...
   } finally {
       lock.unlock();
   }
}

另外:
批量+多线程容易死锁,可以用redis的set集合,做交集

四. Redis常见的解决方案:

  1. 可以做分布式限流。
    实现:
    a.写一个lua脚本,如果key不存在,则incr +ttl 60s
    b.如果key存在,则只执行incr
    c.再写一个判断,是否被限制的lua脚本,获取value,get value >200,返回false,否则返回true
    d.Redisson中提供了一个RateLimiter专门做限流
  2. Redis可以做信号量+分布式锁
posted @ 2024-09-25 22:17  二十四桥冷月夜  阅读(43)  评论(0)    收藏  举报