使用Redisson操作redis基础记录
redissonredis
·
maven依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.9.1</version>
</dependency>
基本配置
/**
* @author ZhuRuiLin
* @description TODO
* @date 2022/9/25 16:40
**/
@Configuration
@Slf4j
public class GetConfigFromYaml {
@Bean
public RedissonClient config() {
try {
Config config = Config.fromYAML(GetConfigFromYaml.class.getClassLoader().getResource("redisson-config.yaml"));
return Redisson.create(config);
} catch (IOException e) {
log.error("从application.yaml获取Redisson配置出错");
}
return null;
}
}
放在resource文件夹下的redisson-config.yaml文件:
---
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: xxxx
subscriptionsPerConnection: 5
clientName: springcloud-learn
address: "redis://xxxx:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> { }
"transportMode": "NIO"
代码demo
RedissonClient.getKeys()方法可以得到当前指定的database的所有key,不指定database默认为db0,并不会跨库查询:
/**
* 得到某个database下的所有key
*
* @return
*/
public RKeys getAllKeys() {
return client.getKeys();
}
getKeysByPattern(String pattern)方法可以模糊查询多个key
public Iterable<String> getKeysByPattern() {
return getAllKeys().getKeysByPattern("string*");// 也会查询到key=string
}
删除多个key的方法:
public long deleteByPattern() {
long rows0 = getAllKeys().deleteByPattern("two*");
long rows1 = getAllKeys().deleteByPattern("three?");// 这个pattern我本地没有删除成功,但是在git的wiki上是这么写的
long rows2 = getAllKeys().delete("string0", "string1");
log.info("rows0={}", rows0);
log.info("rows1={}", rows1);
log.info("rows2={}", rows2);
return rows2;
}
Redisson的分布式RBucketJava对象是一种通用对象桶可以用来存放任类型的对象
public void setValue() {
RBucket<String> strBucket = client.getBucket("strBucket");
strBucket.set("这是一个字符串");
strBucket.set("更新一个字符串", 5, TimeUnit.SECONDS);
strBucket.set("再次更新一个字符串");
List<String> strList = new ArrayList<>();
strList.add("周一");
strList.add("周二");
strList.add("周三");
RList<String> listBucket = client.getList("listBucket");
boolean saveListResult = listBucket.addAll(strList);
log.info("listBucket存储成功={}", saveListResult);
if (saveListResult) {
RList<Object> dataList = client.getList("listBucket");
List<String> newList = dataList.stream().map(data -> (String) data).collect(Collectors.toList());
newList.stream().forEach(System.out::println);
}
Map<String, String> map = new HashMap<>();
map.put("monday", "周一");
map.put("friday", "周五");
RMap<String, String> mapBucket = client.getMap("mapBucket");
mapBucket.putAll(map);
Map<String, String> dataMap = new HashMap<>(client.getMap("mapBucket"));
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
log.info("key={},value={}", entry.getKey(), entry.getValue());
}
}
还可以通过RBuckets接口实现批量操作多个RBucket对象:
RBuckets buckets = client.getBuckets();
Map<String, String> map = buckets.get("string1", "string2");
for (Map.Entry<String, String> entry : map.entrySet()) {
entry.setValue(entry.getValue() + "再次更新");
}
buckets.set(map);
Redisson的分布式话题:
RTopic topic = client.getTopic("testTopic0926");
topic.addListener(TestTopicBean.class, new MessageListener() {
@Override
public void onMessage(CharSequence charSequence, Object o) {
log.info("charSequence={},o={}", charSequence.toString(), o.toString());
}
});
TimeUnit.SECONDS.sleep(5);
RTopic setTopic = client.getTopic("testTopic0926");
TestTopicBean ttb = new TestTopicBean();
ttb.setName("测试");
long result = setTopic.publish(ttb);
log.info("public方法的返回值是={}", result);
判断是否存在和设置过期时间
RBucket<String> week = client.getBucket("week");
// 判断是否存在
if (week.isExists()) {
log.info("week对应的key已经存在");
} else {
log.info("week对应的key不存在");
}
// 设置时间自动过期
week.set("临时存储", 10, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(5);
RBucket<String> after5 = client.getBucket("week");
log.info("after5={}", after5);
TimeUnit.SECONDS.sleep(7);
RBucket<String> after12 = client.getBucket("week");
if (after12.isExists()) {
log.info("after12对应的key仍然存在");
} else {
log.info("after12对应的key不存在");
}
基于Redis的Redisson分布式整长型累加器(LongAdder)采用了与java.util.concurrent.atomic.LongAdder类似的接口。通过利用客户端内置的LongAdder对象,为分布式环境下递增和递减操作提供了很高得性能。据统计其性能最高比分布式AtomicLong对象快 12000 倍。完美适用于分布式统计计量场景。
// sum()方法就是返回当前值
log.info("初始化的值是{}", rla.sum());
rla.add(10);
log.info("add(10)之后的值{}", rla.sum());
rla.reset();
log.info("调用reset()方法之后的值是{}", rla.sum());// 调用reset()方法之后的值是0
rla.increment();
rla.increment();
rla.decrement();
log.info("自增两次,减少一次之后的值是{}", rla.sum());
rla.reset();
rla.add(10);
log.info("sum()方法的返回值是{}", rla.sum());
rla.sumAsync(1, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(2);
log.info("调用sum(long,TimeUnit)之后的值是{}", rla.sum()); //调用sum(long,TimeUnit)之后的值是10
rla.reset();
rla.add(100);
rla.delete();
log.info("调用delete()方法之后的值{}", rla.sum()); //调用delete()方法之后的值100
// 当不再使用整长型累加器对象的时候应该自行手动销毁,如果Redisson对象被关闭(shutdown)了,则不用手动销毁。
rla.destroy();
log.info("调用destroy之后的值是{}", rla == null ? "null" : rla.sum()); // 调用destroy之后的值是0
如果负责储存这个分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。
另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
// 加锁以后10秒钟自动解锁
// 无需调用unlock方法手动解锁
lock.lock(10, TimeUnit.SECONDS);
// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
...
} finally {
lock.unlock();
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)