欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

redis数据问题小计 博客分类: redis redis 串库 备份 nosql 

程序员文章站 2024-03-01 22:52:46
...

将最近遇到的redis问题总结一下:

1.问题描述

   程序从redis里面获取数据,时有时无,概率一半一半

 

2.问题分析

   最近开发遇到了从redis里获取数据时有时无的现象,开始以为是redis出了问题,由于赶上运维重新搭建测试环境,同时又是在测试环境中遇到的,就没太在意,想着用新环境就好了,过来几天将代码移植到新的测试环境中,发现现象依然存在,就和运维描述了一下问题(当时还是以为是redis系统方面出了问题),后来将代码部署到线上测试环境,发现问题依然存在,这个时候我就警觉起来了,开始怀疑是程序方面出了问题,然后开始了代码排查,开始由于固定思维模式,并未发现什么问题,获取数据这块的代码也并未改动过。十分的不解,然后开始仔细回忆bug最开始出现的时间以及在什么模式下会出现,最好锁定是新增的一块功能后,这个bug就出现了(和这块没什么关系),不甘心,继续调试,发现出现问题的时候,从redis榜单中并未获取到数据(正常的是获取到数据的),因为从配置上看是从同一个redis源拿的数据。继续往深了调试,发现取数据之前要验证一下redis key的type  出问题的时候type为none(没有这个redis key),找到问题了松了一口气,然后怀疑是redis 没判断出来,以为是redis的bug(怎么也没想到是redis 串库了)。后来查资料,网上并未找到这个redis bug的相关文章,这就令我百思不得其解了。

后来为了验证是这个版本的代码有问题,就从线上拷贝了一份代码放到线上测试环境,一看并未出现问题。

 

代码问题,代码问题,代码问题,重要的事情说三遍。

 

慢慢排查代码之路开始了,灵光一现,在获取redis对象的时侯查验一下对象的ip和端口,不就能确定是不是同一个源了吗,说干就干,经过调试还真发现不是同一个源,redis 串库了。

又开始回想,这个版本增加了什么,代码一行一行的排查,发现是一个方法里面获取某个redis 对象用完后

returnResource 的时return 错了,获取了两个redis Resource ,用完后returnResource return错了。

(大家都知道jedis用完要释放,不然链接用完了就出问题了)

看下面事例代码:

 

Jedis Jedis1 = jedisPool1.getResource();

Jedis Jedis2 = jedisPool2.getResource();

try {

      xxxxx

}catch(Exception e){

}finally{

      jedisPool1.returnResource(jedis2); //正确的是return jedis1的 结果写成了jedis2

}

 

3.解决问题

正确的pool 对应正确的jedis

 

总结:这个问题本来就不是问题,但由于粗心大意(粘贴复制)写错了东西,导致了这么严重的问题,因为之前也没遇到过串库的问题,所以一开始根本就没网那方面想,不过庆幸的是通过一番努力找到了问题的根本原因,也算积累了经验。

 

最后再次强调一现,redis数据文件一定要记得备份,备份,备份并定期检查数据备份是否正确。

因为最近亲身经历一次线上redis数据丢失的情况,情况是这样的当运维调整网络后,把redis机器

重启了一下(当然是在晚上11点后了),起来之后发现数据丢了(文件被重新写入了),然后立马去从机拷贝数据,结果从机上根本没有数据,顿时傻了,原来运维在配置主从的时候配置错了,导致从机并没有备份数据并且主redis上数据持久化配置的也有问题,导致重启机器后数据被冲了,无奈没办法,连夜赶到公司从数据库里恢复数据到redis,幸好这个redis刚上线没多久,数据量也不大(几百兆),比较容易恢复。

 

教训:

操作nosql数据库一定要小心再小心,备份再备份。