Spring Data Redis提供的几种序列化的比较

本文对比了JdkSerializationRedisSerializer、OxmSerializer和Jackson2JsonRedisSerializer三种Redis序列化方式的性能与存储效率,通过实验得出JSON序列化为最优选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* redis虽然提供了对list set hash等数据类型的支持,但是没有提供对POJO对象的支持,底层都是把对象序列化后再以字符串的方式存储的。* 
Spring data提供了若干个Serializer,主要包括:

  • JdkSerializationRedisSerializer——使用Java自带的序列化机制将对象序列化为一个字符串
  • OxmSerializer——将对象序列化为xml字符串
  • Jackson2JsonRedisSerializer——将对象序列化为json字符串

下面分别测试这三种序列化,看看效果: 
实体类User——将要保存到redis的对象

@XmlAccessorType(XmlAccessType.FIELD)  
@XmlRootElement(name = "user")  
public class User implements Serializable{

    private static final long serialVersionUID = 5403379425407254942L;

     @XmlAttribute  
        private String userName;  

        @XmlAttribute  
        private int age;  

        public String getUserName() {  
            return userName;  
        }  

        public void setUserName(String userName) {  
            this.userName = userName;  
        }  

        public int getAge() {  
            return age;  
        }  

        public void setAge(int age) {  
            this.age = age;  
        }  
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

RootConfig配置类:


@Configuration
@ComponentScan(basePackages="com.redis.*")
public class RootConfig {

    /**
     * 配置redis连接工厂
     * @return
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory(){
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName("localhost");
        factory.setPort(6379);
        factory.afterPropertiesSet();
        return factory;
    }

    /**
     * Spring的RedisTemplate
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(){
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory());
        return template;
    }


    @Bean
    public OxmSerializer oxmSerializer(){
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        Map<String, Object> properties = new HashMap<String, Object>();//创建映射,用于设置Marshaller属性  
        properties.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);//放置xml自动缩进属性  
        properties.put(Marshaller.JAXB_ENCODING, "utf-8");
        jaxb2Marshaller.setClassesToBeBound(User.class);//映射的xml类放入JAXB环境中 
        jaxb2Marshaller.setMarshallerProperties(properties);//设置Marshaller属性
        return new OxmSerializer(jaxb2Marshaller, jaxb2Marshaller);
    }

    //下面是简单类型的序列化类
    public static enum StringSerializer implements RedisSerializer<String> {
        INSTANCE;

        @Override
        public byte[] serialize(String t) throws SerializationException {
            return (null != t ? t.getBytes() : new byte[0]);
        }

        @Override
        public String deserialize(byte[] bytes) throws SerializationException {
            if(bytes.length > 0){
                return new String(bytes);
            } else {
                return null;
            }
        }
    }

    public static enum LongSerializer implements RedisSerializer<Long> {
        INSTANCE;

        @Override
        public byte[] serialize(Long t) throws SerializationException {
            if(null != t){
                return t.toString().getBytes();
            }else {
                return new byte[0];
            }
        }

        @Override
        public Long deserialize(byte[] bytes) throws SerializationException {
            if(bytes.length > 0){
                return Long.parseLong(new String(bytes));
            }else {
                return null;
            }
        }
    }

    public static enum IntSerializer implements RedisSerializer<Integer> {
        INSTANCE;

        @Override
        public byte[] serialize(Integer t) throws SerializationException {
            if(null != t){
                return t.toString().getBytes();
            }else {
                return new byte[0];
            }
        }

        @Override
        public Integer deserialize(byte[] bytes) throws SerializationException {
            if(bytes.length > 0){
                return Integer.parseInt(new String(bytes));
            }else {
                return null;
            }
        }
    }
}

 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

测试用例:


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={RootConfig.class,WebConfig.class})
@WebAppConfiguration
public class KeyValueSerializersTest {
    @Autowired
    private RedisConnectionFactory connectionFactory;
    @Autowired
    private OxmSerializer oxmSerializer;

    @Test
    public void testJdkSerializer(){
        RedisTemplate<String, Serializable> redis = new RedisTemplate<String, Serializable>();

        redis.setConnectionFactory(connectionFactory);
        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
        redis.setValueSerializer(new JdkSerializationRedisSerializer());
        redis.afterPropertiesSet();

        ValueOperations<String, Serializable> ops = redis.opsForValue();

        User user1 = new User();
        user1.setUserName("xuexiaoqiang");
        user1.setAge(25);

        String key1 = "jdk/user1";
        User user11 = null;

        long begin = System.currentTimeMillis();

        for(int i = 0; i < 100; i++){
            ops.set(key1, user1);
            user11 = (User) ops.get(key1);
        }

        long time = System.currentTimeMillis() - begin;
        System.out.println("jdk time: "+time);
        System.out.println(user11.getUserName());
    }

    @Test
    public void testOxmSerializer() {
        RedisTemplate<String, Object> redis = new RedisTemplate<String, Object>();
        redis.setConnectionFactory(connectionFactory);
        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
        redis.setValueSerializer(oxmSerializer);
        redis.afterPropertiesSet();

        ValueOperations<String, Object> ops = redis.opsForValue();

        User user1 = new User();
        user1.setUserName("xuexiaoqiang");
        user1.setAge(25);

        String key1 = "oxm/user1";
        User user11 = null;

        long begin = System.currentTimeMillis();

        for(int i = 0; i < 100; i++){
            ops.set(key1, user1);
            user11 = (User) ops.get(key1);
        }

        long time = System.currentTimeMillis() - begin;
        System.out.println("oxm time: "+time);
        System.out.println(user11.getUserName());
    }

    @Test
    public void testJacksonSerialiable() {
        RedisTemplate<String, Object> redis = new RedisTemplate<String, Object>();
        redis.setConnectionFactory(connectionFactory);
        redis.setKeySerializer(RootConfig.StringSerializer.INSTANCE);
        redis.setValueSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
        redis.afterPropertiesSet();

        ValueOperations<String, Object> ops = redis.opsForValue();

        User user1 = new User();
        user1.setUserName("xuexiaoqiang");
        user1.setAge(25);

        String key1 = "json/user1";
        User user11 = null;

        long begin = System.currentTimeMillis();

        for(int i = 0; i < 100; i++){
            ops.set(key1, user1);
            user11 = (User) ops.get(key1);
        }

        long time = System.currentTimeMillis() - begin;
        System.out.println("json time: "+time);
        System.out.println(user11.getUserName());
    }

}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99

结果: 
testJdkSerializer()方法: 
控制台打印:

jdk time: 68
xuexiaoqiang
 
  • 1
  • 2

redis中:

127.0.0.1:6379> get jdk/user1
"\xac\xed\x00\x05sr\x00\x15com.redis.entity.UserJ\xfc\xa8\xf5\x86\r\xc1\x9e\x02\x00\x02I\x00\x03ageL\x00\buserNamet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x19t\x00\x0cxuexiaoqiang"
 
  • 1
  • 2

testOxmSerializer()方法: 
控制台输出:

oxm time: 471
xuexiaoqiang
 
  • 1
  • 2

redis:

127.0.0.1:6379> get oxm/user1
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<user userName=\"xuexiaoqiang\" age=\"25\"/>\n"
 
  • 1
  • 2

testJacksonSerialiable()方法: 
控制台输出:

json time: 97
xuexiaoqiang

 
  • 1
  • 2
  • 3

redis:

127.0.0.1:6379> get json/user1
"{\"userName\":\"xuexiaoqiang\",\"age\":25}"
 
  • 1
  • 2

从时间上来看,JdkSerializationRedisSerializer是最高效的,但是从序列化的结果来看,json占用的内存最小。所以个人认为最优方案是使用JSON序列化。

demo:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值