REDIS学习总结(二)Java操作redis集群
REDIS学习总结(一)单机集群搭建
一、操作方式概述
方法一、Jedis操作
方式二、RedisTemplate操作
Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplate是SpringDataRedis中对JedisApi的高度封装。SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache
二、代码实例
1.IDEA下创建工程的目录结构
2.各配置文件及类文件
pom.xml文件
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.2.RELEASE
com.jupiter.redis.test
redis-learn
0.0.1-SNAPSHOT
redis-learn
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-starter-data-redis
com.alibaba
fastjson
1.2.54
redis.clients
jedis
3.0.1
org.springframework.boot
spring-boot-starter-data-redis-reactive
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
RedisConfig.java
package com.jupiter.redis.commons;
import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
/*
* @author Jupiter
* @date 2019/1/20-23:41
* @description redis配置
*/
@Component
@PropertySource("classpath:redis.properties")
public class RedisConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${redis.cache.timeout}")
private int timeout;
@Value("${redis.pool.max-idle}")
private int maxIdle;
@Value("${redis.pool.max-wait}")
private long maxWaitMillis;
@Value("${redis.cache.commandTimeout}")
private int commandTimeout;
@Bean
public RedisSerializer fastJson2JsonRedisSerializer(){
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
return new FastJson2RedisJsonSerializer
FastJson2RedisJsonSerializer.java
package com.jupiter.redis.commons;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/*
* @author Jupiter
* @date 2019/1/20-22:57
* @description 使用FastJson序列化(redisTemplate序列化默认使用的jdkSerializeable,存储二进制字节码,导致key会出现乱码,所以自定义)
*/
public class FastJson2RedisJsonSerializer implements RedisSerializer {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class clazz;
public FastJson2RedisJsonSerializer(Class clazz) {
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null)
return new byte[0];
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
}
RedisLearnApplication.java
package com.jupiter.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisLearnApplication {
public static void main(String[] args) {
SpringApplication.run(RedisLearnApplication.class, args);
}
}
redis.properties
# Redis服务器连接密码(默认为空)
redis.password=
# 连接池最大连接数(使用负值表示没有限制)
redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
redis.pool.max-wait=-1
# 连接池中的最大空闲连接
redis.pool.max-idle=8
# 连接池中的最小空闲连接
redis.pool.min-idle=0
# 连接超时时间(毫秒)
redis.cache.timeout=0
redis.cache.commandTimeout=5000
# redis.cluster
spring.redis.cluster.nodes=192.168.31.132:27001,192.168.31.132:27002,192.168.31.132:27003,192.168.31.132:27004,192.168.31.132:27005,192.168.31.132:27006,192.168.31.132:27007,192.168.31.132:27008
RedisLearnApplicationTests.java测试类
package com.jupiter.redis;
import com.jupiter.redis.commons.RedisConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.SortingParams;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisLearnApplicationTests {
@Resource
private RedisConfig redis;
private JedisCluster jedis;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
public StringRedisTemplate stringRedisTemplate;
//private JedisClusterConnection jedisClusterConnection;
@Before
public void getJedis() {
this.jedis = redis.getJedisCluster();
//拿到RedisConnectionFactory
// RedisConnectionFactory factory = redis.connectionFactory();
// this.redisTemplate = redis.redisTemplate();
}
@Test
public void testRedisConfig(){
jedis.setex("sex", 13, "man");
System.out.println(jedis.get("sex"));
}
@Test
public void testRedisBasicOperation(){
JedisCluster jedis = redis.getJedisCluster();
}
@Test
public void testKey() throws InterruptedException {
jedis.del("age");
jedis.del("username");
jedis.del("sortedList");
jedis.del("password");
jedis.del("collections");
jedis.del("name");
System.out.println("判断某个键是否存在:"+jedis.exists("username"));
System.out.println("新增<'username','wukong'>的键值对:"+jedis.set("username", "wukong"));
System.out.println("是否存在:"+jedis.exists("name"));
System.out.println("新增<'password','password'>的键值对:"+jedis.set("password", "password"));
Set keys = redisTemplate.keys("*");//jedis单节点可以
System.out.println("系统中所有的键如下:"+keys);
System.out.println("删除键password:"+jedis.del("password"));
System.out.println("判断键password是否存在:"+jedis.exists("password"));
System.out.println("设置键username的过期时间为5s:"+jedis.expire("username", 5));
TimeUnit.SECONDS.sleep(2);
System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
System.out.println("移除键username的生存时间:"+jedis.persist("username"));
System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
System.out.println("查看键username所存储的值的类型:"+jedis.type("username"));
}
/***
* 字符串操作
* memcached和redis同样有append的操作,但是memcached有prepend的操作,redis中并没有。
*/
@Test
public void testString() throws InterruptedException {
System.out.println("===========增加数据===========");
System.out.println(jedis.set("key1","value1"));
System.out.println(jedis.set("key2","value2"));
System.out.println(jedis.set("key3", "value3"));
System.out.println("删除键key2:"+jedis.del("key2"));
System.out.println("获取键key2:"+jedis.get("key2"));
System.out.println("修改key1:"+jedis.set("key1", "value1Changed"));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("在key3后面加入值:"+jedis.append("key3", "End"));
System.out.println("key3的值:"+jedis.get("key3"));
Map maps = new HashMap<>();
maps.put("key01", "value01");
maps.put("key02", "value02");
maps.put("key03", "value03");
redisTemplate.opsForValue().multiSet(maps);
System.out.println("获取键值对:"+jedis.get("key01"));
System.out.println("增加多个键值对成功");
// System.out.println("增加多个键值对:"+jedis.mset("key01","value01","key02","value02","key03","value03"));
// System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
// System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03","key04"));
// System.out.println("删除多个键值对:"+jedis.del(new String[]{"key01","key02"}));
// System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
System.out.println("===========新增键值对防止覆盖原先值==============");
System.out.println(jedis.setnx("key1", "value1"));
System.out.println(jedis.setnx("key2", "value2"));
System.out.println(jedis.setnx("key2", "value2-new"));
System.out.println(jedis.get("key1"));
System.out.println(jedis.get("key2"));
System.out.println("===========新增键值对并设置有效时间=============");
System.out.println(jedis.setex("key3", 2, "value3"));
System.out.println(jedis.get("key3"));
TimeUnit.SECONDS.sleep(3);
System.out.println(jedis.get("key3"));
System.out.println("===========获取原值,更新为新值==========");//GETSET is an atomic set this value and return the old value command.
System.out.println(jedis.getSet("key2", "key2GetSet"));
System.out.println(jedis.get("key2"));
System.out.println("获得key2的值的字串:"+jedis.getrange("key2", 2, 4));
}
/***
* 整数和浮点数
*/
@Test
public void testNumber() {
jedis.set("key1", "1");
jedis.set("key2", "2");
jedis.set("key3", "2.3");
System.out.println("key1的值:"+jedis.get("key1"));
System.out.println("key2的值:"+jedis.get("key2"));
System.out.println("key1的值加1:"+jedis.incr("key1"));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("key2的值减1:"+jedis.decr("key2"));
System.out.println("获取key2的值:"+jedis.get("key2"));
System.out.println("将key1的值加上整数5:"+jedis.incrBy("key1", 5));
System.out.println("获取key1的值:"+jedis.get("key1"));
System.out.println("将key2的值减去整数5:"+jedis.decrBy("key2", 5));
System.out.println("获取key2的值:"+jedis.get("key2"));
}
/***
* 列表
*/
@Test
public void testList() {
System.out.println("===========添加一个list===========");
//从左到右依次先放
jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashMap");
jedis.lpush("collections", "HashSet");
jedis.lpush("collections", "TreeSet");
jedis.lpush("collections", "TreeMap");
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));//-1代表倒数第一个元素,-2代表倒数第二个元素
System.out.println("collections区间0-3的元素:"+jedis.lrange("collections",0,3));
System.out.println("===============================");
// 删除列表指定的值 ,第二个参数为删除的个数(有重复时),后add进去的值先被删,类似于出栈
System.out.println("删除指定元素个数:"+jedis.lrem("collections", 2, "HashMap"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("删除下表0-3区间之外的元素:"+jedis.ltrim("collections", 0, 3));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections列表出栈(左端):"+jedis.lpop("collections"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections添加元素,从列表右端,与lpush相对应:"+jedis.rpush("collections", "EnumMap"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("collections列表出栈(右端):"+jedis.rpop("collections"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("修改collections指定下标1的内容:"+jedis.lset("collections", 1, "LinkedArrayList"));
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
System.out.println("===============================");
System.out.println("collections的长度:"+jedis.llen("collections"));
System.out.println("获取collections下标为2的元素:"+jedis.lindex("collections", 2));
System.out.println("===============================");
jedis.lpush("sortedList", "3","6","2","0","7","4");
System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0, -1));
System.out.println(jedis.sort("sortedList"));
//排序前排序后一样,要想输出排好序的List,用jedis.sort("sortedList")即可
System.out.println("sortedList排序后:"+jedis.lrange("sortedList", 0, -1));
}
/***
* set集合
*/
@Test
public void testSet() {
System.out.println("============向集合中添加元素============");
System.out.println(jedis.sadd("eleSet", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("eleSet", "e6"));
System.out.println(jedis.sadd("eleSet", "e6"));//集合元素唯一性
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("删除一个元素e0:"+jedis.srem("eleSet", "e0"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("删除两个元素e7和e6:"+jedis.srem("eleSet", "e7","e6"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
System.out.println("eleSet中包含元素的个数:"+jedis.scard("eleSet"));
System.out.println("e3是否在eleSet中:"+jedis.sismember("eleSet", "e3"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e1"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e5"));
System.out.println("=================================");
System.out.println(jedis.sadd("eleSet1", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("eleSet2", "e1","e2","e4","e3","e0","e8"));
//redisTemplate不会创建新的SET集合,而jedis操作集群有报错No way to dispatch this command to Redis Cluster because keys have different slots.
//解决方法, redis集群下的multiCommands:https://www.cnblogs.com/Finley/p/8595506.html
// System.out.println("将eleSet1中删除e1并存入eleSet3中:"+redisTemplate.opsForSet().move("eleSet1", "e1", "eleSet3"));
// System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e1"));
// System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("eleSet1", "e7", "eleSet2"));
// System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e2"));
// System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
// System.out.println("eleSet3中的元素:"+jedis.smembers("eleSet3"));
// System.out.println("============集合运算=================");
// System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
// System.out.println("eleSet2中的元素:"+jedis.smembers("eleSet2"));
// System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("eleSet1","eleSet2"));
// System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("eleSet1","eleSet2"));
// System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("eleSet1","eleSet2"));//eleSet1中有,eleSet2中没有
}
@Test
public void setMove(){
System.out.println("eleSet1中是否含有e7元素:"+stringRedisTemplate.opsForSet().members("{eleSet}1"));
System.out.println("eleSet1中是否含有e7元素:"+redisTemplate.opsForSet().members("{eleSet}1"));
System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("{eleSet}1", "e7", "{eleSet}2"));
}
/***
* 加入HashTag后的set集合(redis 集群下的相关操作)
*/
@Test
public void testHashTagSet() {
System.out.println("============向集合中添加元素============");
System.out.println(jedis.sadd("{eleSet}", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("{eleSet}", "e6"));
System.out.println(jedis.sadd("{eleSet}", "e6"));//集合元素唯一性
System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
System.out.println("删除一个元素e0:"+jedis.srem("{eleSet}", "e0"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
System.out.println("删除两个元素e7和e6:"+jedis.srem("{eleSet}", "e7","e6"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("{eleSet}"));
System.out.println("随机的移除集合中的一个元素:"+jedis.spop("{eleSet}"));
System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
System.out.println("eleSet中包含元素的个数:"+jedis.scard("{eleSet}"));
System.out.println("e3是否在eleSet中:"+jedis.sismember("{eleSet}", "e3"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("{eleSet}", "e1"));
System.out.println("e1是否在eleSet中:"+jedis.sismember("{eleSet}", "e5"));
System.out.println("=================================");
System.out.println(jedis.sadd("{eleSet}1", "e1","e2","e4","e3","e0","e8","e7","e5"));
System.out.println(jedis.sadd("{eleSet}2", "e1","e2","e4","e3","e0","e8"));
//jedis操作集群有报错No way to dispatch this command to Redis Cluster because keys have different slots.
//解决方法, redis集群下的multiCommands:https://www.cnblogs.com/Finley/p/8595506.html
System.out.println("将eleSet1中删除e1并存入eleSet3中:"+redisTemplate.opsForSet().move("{eleSet}1", "e1", "{eleSet}3"));
System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("{eleSet}1", "{eleSet}3", "e1"));
System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("{eleSet}1", "e7", "{eleSet}2"));
System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("{eleSet}1", "{eleSet}3", "e2"));
System.out.println("eleSet1中的元素:"+jedis.smembers("{eleSet}1"));
System.out.println("eleSet3中的元素:"+jedis.smembers("{eleSet}3"));
System.out.println("============集合运算=================");
System.out.println("eleSet1中的元素:"+jedis.smembers("{eleSet}1"));
System.out.println("eleSet2中的元素:"+jedis.smembers("{eleSet}2"));
System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("{eleSet}1","{eleSet}2"));
System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("{eleSet}1","{eleSet}2"));
System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("{eleSet}1","{eleSet}2"));//eleSet1中有,eleSet2中没有
}
/***
* 散列
*/
@Test
public void testHash() {
Map map = new HashMap();
map.put("key1","value1");
map.put("key2","value2");
map.put("key3","value3");
map.put("key4","value4");
jedis.hmset("hash",map);
jedis.hset("hash", "key5", "value5");
System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));//return Map
System.out.println("散列hash的所有键为:"+jedis.hkeys("hash"));//return Set
System.out.println("散列hash的所有值为:"+jedis.hvals("hash"));//return List
System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 6));
System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 3));
System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
System.out.println("删除一个或者多个键值对:"+jedis.hdel("hash", "key2"));
System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
System.out.println("散列hash中键值对的个数:"+jedis.hlen("hash"));
System.out.println("判断hash中是否存在key2:"+jedis.hexists("hash","key2"));
System.out.println("判断hash中是否存在key3:"+jedis.hexists("hash","key3"));
System.out.println("获取hash中的值:"+jedis.hmget("hash","key3"));
System.out.println("获取hash中的值:"+jedis.hmget("hash","key3","key4"));
}
/**
* 有序集合
*/
@Test
public void testSortedSet() {
Map map = new HashMap();
map.put("key2",1.2);
map.put("key3",4.0);
map.put("key4",5.0);
map.put("key5",0.2);
System.out.println(jedis.zadd("zset", 3,"key1"));
System.out.println(jedis.zadd("zset",map));
System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
System.out.println("zset中的所有元素:"+jedis.zrangeWithScores("zset", 0, -1));
System.out.println("zset中的所有元素:"+jedis.zrangeByScore("zset", 0,100));
System.out.println("zset中的所有元素:"+jedis.zrangeByScoreWithScores("zset", 0,100));
System.out.println("zset中key2的分值:"+jedis.zscore("zset", "key2"));
System.out.println("zset中key2的排名:"+jedis.zrank("zset", "key2"));
System.out.println("删除zset中的元素key3:"+jedis.zrem("zset", "key3"));
System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
System.out.println("zset中元素的个数:"+jedis.zcard("zset"));
System.out.println("zset中分值在1-4之间的元素的个数:"+jedis.zcount("zset", 1, 4));
System.out.println("key2的分值加上5:"+jedis.zincrby("zset", 5, "key2"));
System.out.println("key3的分值加上4:"+jedis.zincrby("zset", 4, "key3"));
System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
}
/**
* 排序
*/
@Test
public void testSort()
{
jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashMap");
System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
SortingParams sortedParameters = new SortingParams();
System.out.println(jedis.sort("collections",sortedParameters.alpha()));
System.out.println("===============================");
jedis.lpush("sortedList", "3","6","2","0","7","4");
System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0, -1));
System.out.println("升序:"+jedis.sort("sortedList", sortedParameters.asc()));
System.out.println("降序:"+jedis.sort("sortedList", sortedParameters.desc()));
}
}
3.更多SpringBoot操作REDIS的文章推荐:
链接:springboot之使用redistemplate优雅地操作redis
链接:使用RedisTemplate访问Redis数据结构API大全
三、实践遇到的问题
问题一:错误TypeMismatchException: Failed to convert property value of type [java.lang原因与解决
原因:配置文件并没有被spring容器加载到,所以导致这样的错误
解决:
链接:TypeMismatchException: Failed to convert property value of type [java.lang解决与原因
链接:Springboot导入自定义properties配置文件 和 SpringBoot自定义配置文件(xxx.properties)
链接:SpringBoot四种读取properties文件的方式
问题二:redis.clients.jedis.exceptions.JedisClusterOperationException: No way to dispatch this command to Redis Cluster because keys have different slots.
原因:哈希槽(hash slot)是Redis Cluster的概念,哈希槽是一个key的集合,Redis集群共有16384个哈希槽,每个key通过CRC16散列然后对16384进行取模来决定该key应当被放到哪个槽中,集群中的每个节点负责一部分哈希槽。这里需要注意的是需要组成并集的各个集合的key必须是对应到redis集群中的同一个slot上,否则将会出现异常:No way to dispatch this command to Redis Cluster because keys have different slots或者CROSSSLOT Keys in request don’t hash to the same slot。所以redis提供了一种特定的标签{},这个{}内的字符串才参与计算hash slot.例如:{user}:aaa与{user}:bbb 这两个集合可以确保在同一个slot上,可以使用zunionstore求它们的并集。如果是在redis集群环境下,需要特别注意。
解决:
在操作redis集群之前先想好后期是否会涉及对集群中存的数据进行批操作,如果只是做缓存,单个K-V存取可以不考虑key在一个hash slot中,这样也有利于数据均匀散列到不通的槽中。
链接:Redis集群
链接:zunionstore异常:CROSSSLOT Keys in request don't hash to the same slot
问题三:redisTemplate.opsForSet().members 反序列化失败
原因:StringRedisTemplate与RedisTemplate区别点:两者的关系是StringRedisTemplate继承RedisTemplate。两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。两者之间的区别主要在于他们使用的序列化类:RedisTemplate使用的是JdkSerializationRedisSerializer:存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 StringRedisTemplate使用的是StringRedisSerializer
解决:
当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可。
但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。
链接:StringRedisTemplate操作redis数据
问题四:Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value
原因:jedis方法与redis服务器中存储数据的类型存在冲突。例如:数据库中有一个key的数据存储的是Hash类型的,但是你使用jedis执行数据操作的时候却使用了非Hash的操作方法。
解决:
链接: Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value 解决处理
四、参考文献
1.redis学习系列(二)--spring boot整合Redis集群
2.Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
3.IntelliJ IDEA lombok插件的安装和使用
4.Caused by: java.lang.NoClassDefFoundError: redis/clients/util/Pool
5.JedisCluster模式尝试进行批量操作
6.springboot配置文件代码提示
7.Redis: Jedis和RedisTemplate有何区别?