redisson用阿里云集群版redis的问题_redission 序列化问题追踪
背景
项目原本是用jedis连接redis,但考虑到需要用redis锁,因此替换为方便快捷的redisson,但是使用redisson之后会报decode error,具体信息如下:
2019-05-15 13:39:59.973 [redisson-netty-2-3] ERROR o.r.c.h.CommandDecoder [decodeCommand:203] - Unable to decode data. channel: [id: 0x477c5ced, L:/192.168.4.94:57423 - R:10.10.10.43/10.10.10.43:6379], reply: ReplayingDecoderByteBuf(ridx=102, widx=102), command: (GET), params: [Geek:xxxxx:xxxx]
java.io.IOException: java.lang.NullPointerExceptionat org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:247)at org.redisson.codec.FstCodec$1.decode(FstCodec.java:228)at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:368)at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:200)at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:140)at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:115)at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:502)at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366)at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:278)
测试代码
RBucket ste = redissonClient.getBucket("Geek:add:ddd");
Object re = ste.get();
考虑可能是由于序列化产生的问题,查到NullPointer 3.10.6,设置codec为StringCodec
,即
redissonClient.getConfig().setCodec(new StringCodec());
但是并未解决问题,redisson仍然使用默认的FstCodec
,通过idea强大的提示功能可以看到 getBucket接受一个codec参数
修改代码为
RBucket ste = redissonClient.getBucket("Geek:add:ddd", new StringCodec());
String re = ste.get();
完美解决
问题
为什么直接设置redisson config 不生效呢,一步步查源码 RedissonObject#RedissonObject
public RedissonObject(CommandAsyncExecutor commandExecutor, String name) {this(commandExecutor.getConnectionManager().getCodec(), commandExecutor, name);
}
可以看出redisson 默认从ConnectionManager
里获取codec
方式,继续看,以 SingleConnectionManager
为例,SingleConnectionManager
是MasterSlaveConnectionManager
的子类,具体的类图关系
config.java
public Config(Config oldConf) {setExecutor(oldConf.getExecutor());if (oldConf.getCodec() == null) {// use it by defaultoldConf.setCodec(new FstCodec());}
......}
即检测到原有codec为空时,则设置为FstCodec
看一下 Redisson.java 配置关键部分代码
protected Redisson(Config config) {this.config = config;Config configCopy = new Config(config);connectionManager = ConfigSupport.createConnectionManager(configCopy);evictionScheduler = new EvictionScheduler(connectionManager.getCommandExecutor());writeBehindService = new WriteBehindService(connectionManager.getCommandExecutor());
}public static RedissonClient create(Config config) {Redisson redisson = new Redisson(config);if (config.isReferenceEnabled()) {redisson.enableRedissonReferenceSupport();}return redisson;
}
可以看出, config是在redisson初始化的时候传入的
因为我用的是redisson-spring-boot-starter
,看一下这个starter里面,是如何初始化的,redisson starter 默认使用 spring-data-redis 配置。
@Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean(RedissonClient.class)public RedissonClient redisson() throws IOException {Config config = null;....if (redissonProperties.getConfig() != null) {....} else {config = new Config();String prefix = "redis://";Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, redisProperties)) {prefix = "rediss://";}config.useSingleServer().setAddress(prefix + redisProperties.getHost() + ":" + redisProperties.getPort()).setConnectTimeout(timeout).setDatabase(redisProperties.getDatabase()).setPassword(redisProperties.getPassword());}return Redisson.create(config);
回到一开始的问题,直接设置redisson codec为什么不生效?仔细以上分析可以知道,redisson统一设置codec主要是通过初始化的时候传入ConnectionManager使 codec生效,而通过 redissonClient.getConfig().setCodec(...)
的方式并不能改变ConnectionManager中的编码方式。
结论:
- 如果想自定义codec,需要自己初始化redissonClient[调用Redisson.create(config)], 或者重写redisson-starter
- 在定制化程度不高时,可直接使用默认codec,或者把特定的codec传入方法体内
Reference
本文由 歧途老农 创作,采用 CC BY 4.0 CN 协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。
redisson用阿里云集群版redis的问题_redission 序列化问题追踪相关推荐
- 阿里云集群服务器的正确搭建
前面搞了个教程教大家<如何处理网站高并发流量问题?> 里面有提到需要搭建集群服务器,今天就给大家介绍一下阿里云搭建集群服务器的方法. 准备工作: 1.需要有2台以上的阿里云服务器:http ...
- 淘淘商城第39讲——使用Spring来管理单机版Redis与集群版Redis
我们知道Jedis在处理Redis的单机版和集群版时是完全不同的,有可能在开发的时候使用的是单机版,但是当项目上线后使用的则是集群版,这就需要能够方便的在单机版和集群版之间进行切换了.我们的做法便是定 ...
- Linux上安装集群版Redis
[前言] 之前自己在Windows中玩过一段时间Redis(感兴趣的朋友可以看下-Redis系列博客),这次在项目中也有幸能负责起Redis,也由于前两天服务器硬盘损坏导致开发的Redis服务器重新装 ...
- FastDFS V6.06 阿里云集群安装配置双IP(踩坑)
安装之前 如果您看到了本教程请务必先阅读安装之前,看看是否是您期望的效果.可以利用FastDFS实现一个简单的对象存储功能. 实现效果 1.利用阿里云和腾讯云的3台学生主机 ECS 搭建一个分布式集群 ...
- Docker系列之搭建集群版Redis
1. 海量数据需要缓存时,如何设计存储方案? 1.1. 哈希取余分区 假设有N台机器构成一个集群,用户每次读写操作都是根据公式:hash(key)%N个机器台数,计算出哈希值,用来决定数据映射到哪一个 ...
- (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
http://blog.csdn.net/yerenyuan_pku/article/details/72863323 我们知道Jedis在处理Redis的单机版和集群版时是完全不同的,有可能在开发的 ...
- 阿里云Redis集群版简要介绍
阿里云云数据库Redis集群版火热抢购,详情参见>> 产品简介 云数据库 Redis 提供集群版实例,轻松突破 Redis 自身单线程瓶颈,可极大满足对于 Redis 大容量或高性能的业务 ...
- 阿里云短信验证解决方案(java版)(redis存储)
阿里云短信验证解决方案(java版)(redis存储) 参考文章: (1)阿里云短信验证解决方案(java版)(redis存储) (2)https://www.cnblogs.com/Amos-Tur ...
- 使用Spring Data Redis操作Redis(集群版)
说明:请注意Spring Data Redis的版本以及Spring的版本!最新版本的Spring Data Redis已经去除Jedis的依赖包,需要自行引入,这个是个坑点.并且会与一些低版本的Sp ...
最新文章
- 计算机虚拟建造创新实践英语,《信息技术促进初中英语学科教学的实践研究》结题报告...
- vue2中的keep-alive使用总结及注意事项
- 怎样在电脑上上传图片_电脑上回收站怎样恢复
- 清空VS2003/VS2005最近打开解决方案记录
- 两种设置安卓背景图片的方法
- java5 ReadWriteLock用法--读写锁实现
- 数据格式与数据类型(Content-Type)
- java将图书信息写入原有文件里_Java保存图书信息
- 千呼万唤的线粒体基因组完成图
- FPGA是什么呢,通透讲解单片机和FPGA的区别
- 继杭州购房宝典后,Github上的这个程序员买房实用指南火了!
- clickhouse 新增列_# 记录一次clickhouse表新增字段遇到的问题
- Virtual-Taobao: Virtualizing Real-World Online Retail Environment for Reinforcement Learning
- Crossplane - 比 Terraform 更先进的云基础架构管理平台?
- win10在哪找计算机配置,电脑教程:windows10的设置在哪
- 怎么样用计算机计算上浮的价格,原价上上涨百分比怎么算
- 2018年11月总结,12月计划
- 【算法•日更•第十二期】信息奥赛一本通1585:【例 1】Amount of Degrees题解
- 叮咚买菜nodejs自动下单脚本,支持邮件强通知和定时任务,支持捡漏和高峰模式
- Unity学习-skybox天空盒纹理
热门文章
- w7 全网架构-rsync-备份
- S1.2 Python开发规范指南
- pythonfor输入多个数字_我一天学会了python最基础的编程
- 与数学实验第二版艾冬梅_吉林省实验繁荣新初一师资大起底,快来看看娃的老师长啥样?...
- 回帖赢好礼,让AI回应你的要求
- 云效DevOps实践-代码评审
- Serverless在编程教育中的实践
- 架构设计 | 基于消息中间件,图解柔性事务一致性
- 送外卖也要“黑科技”?阿里移动感知技术应用揭秘
- 【趣话编程】一个Java对象的回忆录:垃圾回收