很多情况下,不是使用单机redis,而是使用集群,在集群模式下,如何存储对象呢,我们通过这篇文章一一介绍。
创建工程
先在网站上https://start.spring.io/创建一个Gradle工程,相关依赖导入如下:
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-redis')
compile('org.springframework.boot:spring-boot-configuration-processor')
compile('redis.clients:jedis')
compile('org.projectlombok:lombok')
compile('com.alibaba:fastjson:1.2.47')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-test')
}
application.yml配置
server:
port: 8081
spring:
redis:
host: 127.0.0.1
#password:
timeout: 1000
database: 0 #默认有16个db(集群模式下无多db概念,取而代之是hash槽),默认是第0个
pool:
max-active: 8 #最大连接数(使用负值表示没有限制) 默认 8
max-wait: -1 #最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-idle: 8 #最大空闲连接 默认 8
min-idle: 0
cluster:
nodes:
- 172.19.165.222:9001
- 172.19.165.222:9002
- 172.19.165.222:9003
- 172.19.165.222:9004
- 172.19.165.222:9005
- 172.19.165.222:9006
RedisCluster
从配置文件获取nodes信息,如下:
RedisClusterProperties.java
@Configuration
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class RedisClusterProperties {
//cluster nodes
private List nodes=new ArrayList<>();
public List getNodes() {
return nodes;
}
public void setNodes(List nodes) {
this.nodes = nodes;
}
}
接着从获取的nodes信息中配置JedisCluster实例
@Configuration
@ConditionalOnClass(RedisClusterConfig.class)
@EnableConfigurationProperties(RedisClusterProperties.class)
public class RedisClusterConfig {
@Resource
private RedisClusterProperties redisClusterProperties;
@Bean
public JedisCluster redisCluster(){
Set nodes = new HashSet<>();
for (String node:redisClusterProperties.getNodes()){
String[] parts= StringUtils.split(node,":");
Assert.state(parts.length==2, "redis node shoule be defined as 'host:port', not '" + Arrays.toString(parts) + "'");
nodes.add(new HostAndPort(parts[0], Integer.valueOf(parts[1])));
}
return new JedisCluster(nodes);
}
}
配置完成后,就可以注入并使用JedisCluster实例了。
下面编写序列化的工具类,可以以json字符串或二进制方式存储,如下:
public class SerializeUtil {
/*
* 序列化
* */
public static byte[] serizlize(Object object) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);) {
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/*
* 反序列化
* */
public static Object deserialize(byte[] bytes) {
try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);) {
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* json序列化
* @param object
* @return
*/
public static String serizlizeJson(Object object) {
return JSON.toJSONString(object);
}
/**
* json反序列化-简单类型
* @param jsonstr
* @return
*/
public static T deserialize(String jsonstr, Class klass) {
T t = JSON.parseObject(jsonstr, klass);
return t;
}
/**
* json反序列化-复杂类型
* @param jsonstr
* @return
*/
public static T deserialize(String jsonstr, TypeReference typeReference) {
T t = JSON.parseObject(jsonstr, typeReference);
return t;
}
}
下面编写测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisClusterApplicationTests {
@Autowired
private JedisCluster jedisCluster;
@Test
public void set_get() {
jedisCluster.set("testkey", "testvalue");
Assert.assertEquals("testvalue", jedisCluster.get("testkey"));
jedisCluster.del("testkey");
}
@Test
public void hset_hget() {
jedisCluster.hset("webside", "google", "www.google.com");
Assert.assertEquals("www.google.com", jedisCluster.hget("webside", "google"));
jedisCluster.del("webside");
}
@Test
public void hmset_hmget() {
Map map = new HashMap<>();
map.put("google", "www.google.com");
map.put("baidu", "www.baidu.com");
jedisCluster.hmset("webside", map);
Assert.assertEquals("www.google.com", jedisCluster.hget("webside", "google"));
Assert.assertEquals(2, jedisCluster.hmget("webside", "google", "baidu").size());
jedisCluster.del("webside");
}
@Test
public void hset_json_obj() {
// 非格式化
String s = JSON.toJSONString(getStudent(),false);
jedisCluster.hset("jsonObject", "student", s);
//Student stu = JSON.parseObject(jedisCluster.hget("jsonObject", "student"), Student.class);
Student stu = SerializeUtil.deserialize(jedisCluster.hget("jsonObject", "student"), Student.class);
Assert.assertEquals("张三", stu.getName());
jedisCluster.del("jsonObject");
}
@Test
public void hset_json_obj_byte() {
jedisCluster.hset("jsonObject".getBytes(), "student".getBytes(), SerializeUtil.serizlize(getStudent()));
Student stu = (Student) SerializeUtil.deserialize(jedisCluster.hget("jsonObject".getBytes(), "student".getBytes()));
Assert.assertEquals("张三", stu.getName());
jedisCluster.del("jsonObject");
}
@Test
public void hset_json_list() {
// 非格式化
String s = JSON.toJSONString(getStudentList());
System.out.println(s);
jedisCluster.hset("jsonObjectList", "student", s);
//List stus = JSON.parseObject(jedisCluster.hget("jsonObjectList", "student"), new TypeReference>(){});
List stus = SerializeUtil.deserialize(jedisCluster.hget("jsonObjectList", "student"), new TypeReference>(){});
Assert.assertEquals(2, stus.size());
Assert.assertEquals("张三", stus.get(0).getName());
//jedisCluster.del("jsonObjectList");
}
@Test
public void hset_json_map() {
Map map = new HashMap<>();
map.put("k1", "v1");
map.put("k2", "v2");
map.put("k3", "v3");
List
通过此方式可以方便的将对象存储到rediscluster,对于一些需要高效访问的系统非常有用。