https://aperise.iteye.com/blog/2396196
https://blog.csdn.net/l1028386804/article/details/73523810
Redisson 中包含大量的分布式线程调度组件,其多数实现依靠String(int)+LUA+发布/订阅 结构完成。
Redisson 实现的与JDK的AQS有异曲同工之妙。这里用int作为核心控制标志,LUA保证原子性CAS等操作,发布/订阅 完成AQS中双端队列的唤醒功能
官方中文文档
https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
RedissonClient
@Bean
public RedissonClient getRedisson(){
Config config = new Config();
config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);
//添加主从配置
// config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
return Redisson.create(config);
}
RLock
是可重入锁实现,通过LUA保证复合指令原子性操作。并且通过定时任务更新所持锁的TTL
RCountDownLatch
看源码底层实现是通过 String(int)+LUA+发布/订阅
RCountDownLatch latch = redissonClient.getCountDownLatch("key");
boolean a=latch.trySetCount(1); //只有一个线程能成功,可以代替自旋锁
latch.await();
// 在其他线程或其他JVM里
RCountDownLatch latch = redissonClient.getCountDownLatch("key");
latch.countDown();
//代替自旋锁,防止缓存击穿
while(true){
if(getCache()){
return
}
//同时只有一个线程能成功trySetCount
if (rCountDownLatch .trySetCount(1)){
try{
//成功
if(getCache()){
//二次检查
return
}
updateCache();
return
} finally {
//解锁+唤醒其他进程/线程
rCountDowbLatch.countDown();
}
}else{
//没有trySetCount成功的线程等待唤醒,减少忙自旋
rCountDownLatch.await();
}
}
latch.trySetCount(1)方法底层LUA脚本,可看到当对应的CountDownLatch已经存在时,是不会重复SetCount
if redis.call('exists', KEYS[1]) == 0 then
redis.call('set', KEYS[1], ARGV[2]);
redis.call('publish', KEYS[2], ARGV[1]);
return 1
else
return 0
end
latch.countDown()方法底层LUA脚本
local v = redis.call('decr', KEYS[1]);
if v <= 0 then redis.call('del', KEYS[1]) end;
if v == 0 then redis.call('publish', KEYS[2], ARGV[1]) end;
分布式集合
官网文档:https://github.com/redisson/redisson/wiki/7.-%E5%88%86%E5%B8%83%E5%BC%8F%E9%9B%86%E5%90%88
坑:
1、rmap导致内存泄漏:https://blog.csdn.net/peterinor_/article/details/90169315
事务
https://github.com/redisson/redisson/wiki/10.-%E9%A2%9D%E5%A4%96%E5%8A%9F%E8%83%BD
Redisson为RMap
、RMapCache
、RLocalCachedMap
、RSet
、RSetCache
和RBucket
这样的对象提供了具有ACID属性的事务功能。Redisson事务通过分布式锁保证了连续写入的原子性,同时在内部通过操作指令队列实现了Redis原本没有的提交
与滚回
功能。当提交
与滚回
遇到问题的时候,将通过org.redisson.transaction.TransactionException
告知用户。