Redis序列化的几种方式
1.什么是Redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
1、 字符串类型 string
2、 散列类型 hash被(string和json)取代了
3、 列表类型 list
4、 集合类型 set
5、 有序集合类型 zset
2.为什么要持久化
Redis是内存数据库。他将自己的数据库存储状态存储在内存中,如果不想方法把数据库状态保存到磁盘中,一旦服务进程退出,服务器中的数据库状态也将消失不见。
解决方法:redis提供了RDB持久化功能,这个功能将redis内存中的数据库状态保存到磁盘中,避免数据意外丢失。
3.Spring整合Redis
3.1 Spring-Data-Redis提供的几种序列化类
为了了解这几种序列化方式的特点与不同之处,通过建立测试类进行序列化的测试,
思路是模拟生成五万条数据,将其进行不同方式的序列化,通过测试序列化所需的时间和观察其在redis中具体的存储形式来进行比较,这里仅使用JdkSerializationRedisSerializer
Jackson2JsonRedisSerializer
StringRedisSerializer
三种序列化的方式
3.2 搭建maven项目
3.2.1 创建实体类User
User类实现了serializable接口,图片省略了getter和setter方法
3.2.2 搭建测试环境
3.2.3 JdkSerializationRedisSerializer序列化方式
spring-redis.xml配置文件中配置
模拟生成5万个对象,使用JdkSerializationRedisSerializer序列化方式存入Redis中
@Test
public void testJdk() {
ValueOperations<String, User> opsForValue = redisTemplate.opsForValue();
//记录开始的时间
long start = System.currentTimeMillis();
//循环生成5万个user对象,存入redis中
for (int i = 1; i <= 50000; i++) {
User user = new User();
//ID使用1-5万的顺序号
user.setId(i);
//姓名使用3个随机汉字模拟
String name = StringUtil.randomChineseString(3);
user.setName(name);
//性别在女和男两个值中随机
String [] arr = {“男”,“女”};
int j = RandomUtil.random(0, 1);
user.setSex(arr[j]);
//手机以13开头+9位随机数模拟
user.setPhone(“13”+RandomUtil.randomNumber(9));
//邮箱以3-20个随机字母 + @qq.com | @163.com | @sian.com | @gmail.com | @sohu.com | @hotmail.com | @foxmail.com模拟
String email = emailUtil.randomemail(3, 20);
user.setEmail(email);
//生日要模拟18-70岁之间,即日期从1949年到2001年之间
Calendar c1 = Calendar.getInstance();
c1.set(1949, 0, 1);
Date d1 = c1.getTime();
Calendar c2 = Calendar.getInstance();
c2.set(2001, 0, 1);
Date d2 = c2.getTime();
Date randomDate = DateUtil.randomDate(d1, d2);
DateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
String birthday = dateFormat.format(randomDate);
user.setBirthday(birthday);
opsForValue.set(“user”+i, user);
}
long end = System.currentTimeMillis();
System.out.println(“存储所需的时间是:”+(end-start)+“毫秒”);
}
测试结果
所用时间:
打开可视化工具查看数据存储方式:
值是二进制的字节码文件,可视性差
3.2.4 Jackson2JsonRedisSerializer序列化方式
spring-redis.xml配置文件中配置
模拟生成5万个对象,使用Jackson2JsonRedisSerializer序列化方式存入Redis中
@Test
public void testJson() {
ValueOperations<String, User> opsForValue = redisTemplate.opsForValue();
//记录开始的时间
long start = System.currentTimeMillis();
//循环生成5万个user对象,存入redis中
for (int i = 1; i <= 50000; i++) {
User user = new User();
//ID使用1-5万的顺序号
user.setId(i);
//姓名使用3个随机汉字模拟
String name = StringUtil.randomChineseString(3);
user.setName(name);
//性别在女和男两个值中随机
String [] arr = {“男”,“女”};
int j = RandomUtil.random(0, 1);
user.setSex(arr[j]);
//手机以13开头+9位随机数模拟
user.setPhone(“13”+RandomUtil.randomNumber(9));
//邮箱以3-20个随机字母 + @qq.com | @163.com | @sian.com | @gmail.com | @sohu.com | @hotmail.com | @foxmail.com模拟
String email = emailUtil.randomemail(3, 20);
user.setEmail(email);
//生日要模拟18-70岁之间,即日期从1949年到2001年之间
Calendar c1 = Calendar.getInstance();
c1.set(1949, 0, 1);
Date d1 = c1.getTime();
Calendar c2 = Calendar.getInstance();
c2.set(2001, 0, 1);
Date d2 = c2.getTime();
Date randomDate = DateUtil.randomDate(d1, d2);
DateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
String birthday = dateFormat.format(randomDate);
user.setBirthday(birthday);
opsForValue.set(“user”+i, user);
}
long end = System.currentTimeMillis();
System.out.println(“json序列化所需的时间是:”+(end-start)+“毫秒”);
}
测试结果
所用时间:
打开可视化工具查看数据存储方式:
值是以json字符串的形式存储,非常直观
3.2.5 StringRedisSerializer序列化方式
spring-redis.xml配置文件中配置
模拟生成5万个对象,使用StringRedisSerializer序列化方式存入Redis中
@Test
public void TestString(){
HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
//记录开始的时间
long start = System.currentTimeMillis();
//循环生成5万个user对象,存入redis中
for (int i = 1; i <= 50000; i++) {
User user = new User();
//ID使用1-5万的顺序号
user.setId(i);
//姓名使用3个随机汉字模拟
String name = StringUtil.randomChineseString(3);
user.setName(name);
//性别在女和男两个值中随机
String [] arr = {“男”,“女”};
int j = RandomUtil.random(0, 1);
user.setSex(arr[j]);
//手机以13开头+9位随机数模拟
user.setPhone(“13”+RandomUtil.randomNumber(9));
//邮箱以3-20个随机字母 + @qq.com | @163.com | @sian.com | @gmail.com | @sohu.com | @hotmail.com | @foxmail.com模拟
String email = emailUtil.randomemail(3, 20);
user.setEmail(email);
//生日要模拟18-70岁之间,即日期从1949年到2001年之间
Calendar c1 = Calendar.getInstance();
c1.set(1949, 0, 1);
Date d1 = c1.getTime();
Calendar c2 = Calendar.getInstance();
c2.set(2001, 0, 1);
Date d2 = c2.getTime();
Date randomDate = DateUtil.randomDate(d1, d2);
DateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);
String birthday = dateFormat.format(randomDate);
user.setBirthday(birthday);
opsForHash.put(“user”+i, “”+i, user.toString());
}
long end = System.currentTimeMillis();
System.out.println(“String序列化所需的时间是:”+(end-start)+“毫秒”);
}
测试结果
所用时间:
打开可视化工具查看数据存储方式:
值是以字符串的形式存储的,由于重写了toString()方法,这里的值还是较为直观的
4.结果比较
从测试结果可以看出:
Jackson2JsonRedisSerializer序列化方式用时最短,而且数据存储格式最为直观,更重要的是:如果以后想要使用这些存储的数据,就要进行反序列化操作,这个时候将json字符串转换为对象还是非常简便的
StringRedisSerializer序列化方式用时次之,数据存储格式也比较直观,麻烦的是:以后要对数据进行反序列化操作时,获取对象的属性值非常麻烦
JdkSerializationRedisSerializer序列化方式用时最长,数据的存储格式不直观,是默认的序列化方式
推荐使用Jackson2JsonRedisSerializer序列化方式