一、配置
1.1 引入maven
<dependency>
<groupId></groupId>
<artifactId>redisson</artifactId>
<version>3.17.0</version>
</dependency>
1.2 配置文件
=0
=
=3000
#sentinel/cluster/single
=single
#连接池配置
-idle=16
-idle=8
-active=8
-wait=3000
-timeout=3000
-timeout=3000
=10
#单机配置
=192.168.60.23:6379
#集群配置
-interval=1000
=
-mode=SLAVE
-attempts=3
-attempts=3
-connection-pool-size=64
-connection-pool-size=64
-interval=1500
#哨兵配置
=business-master
=
-onlyWrite=true
-max=3
1.3 配置文件读取
/**
* @Description: 配置文件读取
*/
@ConfigurationProperties(prefix="", ignoreUnknownFields = false)
@Data
@ToString
public class RedisProperties {
private int database;
/**
* 等待节点回复命令的时间。该时间从命令发送成功时开始计时
*/
private int timeout;
private String password;
private String mode;
/**
* 池配置
*/
private RedisPoolProperties pool;
/**
* 单机信息配置
*/
private RedisSingleProperties single;
/**
* 集群 信息配置
*/
private RedisClusterProperties cluster;
/**
* 哨兵配置
*
*/
private RedisSentinelProperties sentinel;
}
/**
* @Description: redis 池配置
*/
@Data
@ToString
public class RedisPoolProperties {
private int maxIdle;
private int minIdle;
private int maxActive;
private int maxWait;
private int connTimeout;
private int soTimeout;
/**
* 池大小
*/
private int size;
}
/**
* @Description: 单节点配置
*/
@Data
@ToString
public class RedisSingleProperties {
private String address;
}
/**
* @Description: 集群配置
*/
@Data
@ToString
public class RedisClusterProperties {
/**
* 集群状态扫描间隔时间,单位是毫秒
*/
private int scanInterval;
/**
* 集群节点
*/
private String nodes;
/**
* 默认值: SLAVE(只在从服务节点里读取)设置读取操作选择节点的模式。 可用值为: SLAVE - 只在从服务节点里读取。
* MASTER - 只在主服务节点里读取。 MASTER_SLAVE - 在主从服务节点里都可以读取
*/
private String readMode;
/**
* (从节点连接池大小) 默认值:64
*/
private int slaveConnectionPoolSize;
/**
* 主节点连接池大小)默认值:64
*/
private int masterConnectionPoolSize;
/**
* (命令失败重试次数) 默认值:3
*/
private int retryAttempts;
/**
*命令重试发送时间间隔,单位:毫秒 默认值:1500
*/
private int retryInterval;
/**
* 执行失败最大次数默认值:3
*/
private int failedAttempts;
}
/**
* @Description: 哨兵配置
*/
@Data
@ToString
public class RedisSentinelProperties {
/**
* 哨兵master 名称
*/
private String master;
/**
* 哨兵节点
*/
private String nodes;
/**
* 哨兵配置
*/
private boolean masterOnlyWrite;
/**
*
*/
private int failMax;
}
1.4 CacheConfiguration
import ;
import ;
import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
/**
* @Description:
*/
@Configuration
@EnableConfigurationProperties()
public class CacheConfiguration {
@Autowired
private RedisProperties redisProperties;
@Configuration
@ConditionalOnClass({})
@ConditionalOnExpression("'${}'=='single' or '${}'=='cluster' or '${}'=='sentinel'")
protected class RedissonSingleClientConfiguration {
/**
* 单机模式 redisson 客户端
*/
@Bean
@ConditionalOnProperty(name="", havingValue="single")
public RedissonClient redissonSingle() {
Config config = new Config();
String node = ().getAddress();
node = ("redis://") ? node : "redis://" + node;
SingleServerConfig serverConfig = ()
.setAddress(node)
.setTimeout(().getConnTimeout())
.setConnectionPoolSize(().getSize())
.setConnectionMinimumIdleSize(().getMinIdle());
if(!(())) {
(());
}
return (config);
}
/**
* 集群模式的 redisson 客户端
*
* @return
*/
@Bean
@ConditionalOnProperty(name = "", havingValue = "cluster")
public RedissonClient redissonCluster() {
("cluster redisProperties:" + ());
Config config = new Config();
String[] nodes = ().getNodes().split(",");
List<String> newNodes = new ArrayList<>();
(nodes).forEach((index) -> (
("redis://") ? index : "redis://" + index)
);
ClusterServersConfig serverConfig = ()
.addNodeAddress((new String[0])
).setScanInterval(
().getScanInterval()
).setIdleConnectionTimeout(
().getSoTimeout()
).setConnectTimeout(
().getConnTimeout()
).setRetryAttempts(
().getRetryAttempts()
).setRetryInterval(
().getRetryInterval()
).setMasterConnectionPoolSize(
().getMasterConnectionPoolSize()
).setSlaveConnectionPoolSize(
().getSlaveConnectionPoolSize()
).setTimeout(
()
);
if (!(())) {
(());
}
return (config);
}
/**
* 哨兵模式 redisson 客户端
* @return
*/
@Bean
@ConditionalOnProperty(name = "", havingValue = "sentinel")
public RedissonClient redissonSentinel() {
("sentinel redisProperties:" + ());
Config config = new Config();
String[] nodes = ().getNodes().split(",");
List<String> newNodes = new ArrayList<>();
(nodes).forEach((index) -> (
("redis://") ? index : "redis://" + index)
);
SentinelServersConfig serverConfig = ()
.addSentinelAddress((new String[0]))
.setMasterName(().getMaster())
.setReadMode()
.setTimeout(())
.setMasterConnectionPoolSize(().getSize())
.setSlaveConnectionPoolSize(().getSize());
if (!(())) {
(());
}
return (config);
}
}
}
二、Redisson工具类
import .*;
import ;
import ;
import ;
import ;
/**
* @Description:
*/
@Component
public class RedisUtils {
/**
* 默认缓存时间
*/
private static final Long DEFAULT_EXPIRED = 32000L;
/**
* 自动装配redisson client对象
*/
@Resource
private RedissonClient redissonClient;
/**
* 用于操作key
* @return RKeys 对象
*/
public RKeys getKeys() {
return ();
}
/**
* 移除缓存
*
* @param key
*/
public void delete(String key) {
(key).delete();
}
/**
* 获取getBuckets 对象
*
* @return RBuckets 对象
*/
public RBuckets getBuckets() {
return ();
}
/**
* 读取缓存中的字符串,永久有效
*
* @param key 缓存key
* @return 字符串
*/
public String getStr(String key) {
RBucket<String> bucket = (key);
return ();
}
/**
* 缓存字符串
*
* @param key
* @param value
*/
public void setStr(String key, String value) {
RBucket<String> bucket = (key);
(value);
}
/**
* 缓存带过期时间的字符串
*
* @param key 缓存key
* @param value 缓存值
* @param expired 缓存过期时间,long类型,必须传值
*/
public void setStr(String key, String value, long expired) {
RBucket<String> bucket = (key, );
(value, expired <= 0L ? DEFAULT_EXPIRED : expired, );
}
/**
* string 操作,如果不存在则写入缓存(string方式,不带有redisson的格式信息)
*
* @param key 缓存key
* @param value 缓存值
* @param expired 缓存过期时间
*/
public Boolean setIfAbsent(String key, String value, long expired) {
RBucket<String> bucket = (key, );
return (value, expired <= 0L ? DEFAULT_EXPIRED : expired, );
}
/**
* 如果不存在则写入缓存(string方式,不带有redisson的格式信息),永久保存
*
* @param key 缓存key
* @param value 缓存值
*/
public Boolean setIfAbsent(String key, String value) {
RBucket<String> bucket = (key, );
return (value);
}
/**
* 判断缓存是否存在
*
* @param key
* @return true 存在
*/
public Boolean isExists(String key) {
return (key).isExists();
}
/**
* 获取RList对象
*
* @param key RList的key
* @return RList对象
*/
public <T> RList<T> getList(String key) {
return (key);
}
/**
* 获取RMapCache对象
*
* @param key
* @return RMapCache对象
*/
public <K, V> RMapCache<K, V> getMap(String key) {
return (key);
}
/**
* 获取RSET对象
*
* @param key
* @return RSET对象
*/
public <T> RSet<T> getSet(String key) {
return (key);
}
/**
* 获取RScoredSortedSet对象
*
* @param key
* @param <T>
* @return RScoredSortedSet对象
*/
public <T> RScoredSortedSet<T> getScoredSortedSet(String key) {
return (key);
}
}
三、常用RKeys的API操作
每个Redisson对象实例都会有一个与之对应的Redis数据实例,可以通过调用getName方法来取得redis数据实例的名称(key),所有于Redis key相关的操作都归纳在RKeys这个接口里。
RKeys keys = ();
//获取所有key值
Iterable<String> allKeys = ();
//模糊查询所有包含关键字key的值
Iterable<String> foundedKeys = ("key");
//删除多个key值
long numOfDeletedKeys = ("obj1", "obj2", "obj3");
//模糊删除key值
long deletedKeysAmount = ("test?");
//随机获取key
String randomKey = ();
//查询当前有多少个key
long keysAmount = ();
具体demo
private void getKeys() {
RKeys keys = ();
Iterable<String> allKeys = ();
StringBuilder sb = new StringBuilder();
for (String key : allKeys) {
sb = (key).append(",");
}
("所有的key:{}", (0, () - 1));
// 模糊查询以 map 打头的所有 key
allKeys = ("map*");
sb = new StringBuilder();
for (String key : allKeys) {
sb = (key).append(",");
}
("模糊匹配到的key:{}", (0, () - 1));
}
其中,getKeysByPattern是基于redis的scan命令实现。
四、通用对象桶Object Bucket
Redisson的分布式RBucket Java对象是一种通用对象桶,可以用来存放任意类型的对象。除了同步接口外,还提供异步(Async)、反射式(Reactive)和RxJava2标准的接口。还可以通过RBuckets接口实现批量操作多个RBucket对象。
/**
* String 数据类型
*/
private void strDemo() {
(DEMO_STR, "Hello, String.");
("String 测试数据:{}", (DEMO_STR));
("myBucket", "myBucketIsXxx");
RBuckets buckets = ();
Map<String, String> foundBuckets = ("myBucket*");
Map<String, Object> map = new HashMap<>();
("myBucket1", "value1");
("myBucket2", 30L);
// 同时保存全部通用对象桶。
(map);
Map<String, String> loadedBuckets = ("myBucket1", "myBucket2", "myBucket3");
("跨桶String 测试数据:{}", loadedBuckets);
("myBucket3", 320L);
}
五、散列 Hash
基于Redisson的分布式映射结构的RMap Java对象实现了和接口,与HashMap不同的是,RMap 保持了元素的插入顺序。该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/**
* Hash类型
*/
private void hashDemo() {
RMap<Object, Object> map = ("mapDemo");
("demoId1", "123");
("demoId100", "13000");
Object demoId1Obj = ("demoId1");
("Hash 测试数据:{}", demoId1Obj);
}
六、集合 Set
基于Redisson的分布式Set结构的RSet Java对象实现了接口,通过元素的互相状态比较保证了每个元素的唯一性,该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/**
* Set 测试
*/
private void setDemo() {
RSet<String> set = ("setKey");
("value777");
("Set 测试数据");
Iterator<String> iterator = ();
while (()) {
String next = ();
(next);
}
}
七、列表 List
基于Redisson的分布式列表 List 结构的RList Java对象在实现了接口的同时,确保了元素插入时的顺序,该对象的最大容量受Redis限制,最大元素数量是4294967295个。
/**
* List数据类型
*/
private void listDemo() {
RList<String> list = ("listDemo");
("listValue1");
("listValue2");
("List 测试数据:{}", (1));
}
综合示例
将上述demo放入一个API中,快速测试:
import .slf4j.Slf4j;
import .*;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
@Slf4j
@RestController
@RequestMapping(value = "/redisson", method = )
public class StudyRedissonController {
@Resource
private RedisUtils redisUtils;
private static String DEMO_STR = "demoStr";
@PostMapping("/learnRedisson")
public void learnRedisson() {
//三种数据结构使用示例
strDemo();
hashDemo();
listDemo();
setDemo();
getKeys();
}
private void getKeys() {
RKeys keys = ();
Iterable<String> allKeys = ();
StringBuilder sb = new StringBuilder();
for (String key : allKeys) {
sb = (key).append(",");
}
("所有的key:{}", (0, () - 1));
// 模糊查询以 map 打头的所有 key
allKeys = ("map*");
sb = new StringBuilder();
for (String key : allKeys) {
sb = (key).append(",");
}
("模糊匹配到的key:{}", (0, () - 1));
}
/**
* Hash类型
*/
private void hashDemo() {
RMap<Object, Object> map = ("mapDemo");
("demoId1", "123");
("demoId100", "13000");
Object demoId1Obj = ("demoId1");
("Hash 测试数据:{}", demoId1Obj);
}
/**
* String 数据类型
*/
private void strDemo() {
(DEMO_STR, "Hello, String.");
("String 测试数据:{}", (DEMO_STR));
("myBucket", "myBucketIsXxx");
RBuckets buckets = ();
Map<String, String> foundBuckets = ("myBucket*");
Map<String, Object> map = new HashMap<>();
("myBucket1", "value1");
("myBucket2", 30L);
// 同时保存全部通用对象桶。
(map);
Map<String, String> loadedBuckets = ("myBucket1", "myBucket2", "myBucket3");
("跨桶String 测试数据:{}", loadedBuckets);
("myBucket3", 320L);
}
/**
* List数据类型
*/
private void listDemo() {
RList<String> list = ("listDemo");
("listValue1");
("listValue2");
("List 测试数据:{}", (1));
}
/**
* Set 测试
*/
private void setDemo() {
RSet<String> set = ("setKey");
("value777");
("Set 测试数据");
Iterator<String> iterator = ();
while (()) {
String next = ();
(next);
}
}
}