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
告知用戶。