redis使用list发生事故

某应用接入Redis作为主服务器,使用List存储数据,导致流量异常增长。问题在于当新的数据写入List时,会重置所有数据的过期时间,造成数据生命周期延长。为解决此问题,改写了token的存储方式,确保新数据不会影响其他数据的时间周期。

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

应用有两台服务器,在其中一台服务器上面安装了redis,作为主服务器,项目接入了移动端,一周后,运维那边突然报告说两台服务器的流量一天比一天多,真的时成等差数列增加,奇怪的是两台服务器的流量出入是互补的。 


(由于某些原因,无法截图到原始图片)

红色表示Outgoing,绿色表示Incoming,两台服务器的流量进出大致呈现上面的图,其中下面的图是有redis的服务器,上面的图对应的服务器没有redis

这个问题出现是某个接口变得非常卡,通过设置时间查看具体的执行时间,发现在取redis的时候花费了大概1秒,查看redis内存和关键字对应的数据的时候,我们找到了问题。

之前这个接口使用list存储数据的,因为这个接口只是用来验证,生成token存入redis,之后很快就会取用这个token,如果考虑每次请求时间差不多,那么这个过程基本时先进先出,用list处理确实时不错的选择。

redisClient.rpush(key,JSON.Stringify(param),3*60);
往一个key里面存token,并且设置时间周期为3分钟,当取用token的时候:

redisClient.llen(key,function(err,len){
	redisClient.lrang(key,0,len,function(err,list){
		callback(err,list);
	})
})
redisClient.lrem('param',1,value);
会把这个key对应的list都取出来,然后循环找到对应token,并删除(上面代码只有redis的操作)。整个来说都是没有什么问题的,服务端请求时生成token,给客户端使用,用掉之后就会清除,这个接近FIFO的操作用list可以提高查询效率。只是,现在接入了移动端,移动端有一个特点,就是经常断线重连,服务端请求token,给客户端使用,为了安全这个过程一般来说都是连续的,但是移动端的接入,有很大的情况就是服务端生成了token,然后就断线了客户端(移动端)没有取拿这个生成的token,导致token会滞留并累计在redis,导致list会非常的长,每次读取的时候也会非常的慢,同时在读取redis数据到缓存处理的时候,使得两台服务器的流量出入呈现互补。

有人应该会问:不是设置了3分钟的时间周期吗?

是的,设置了时间周期,但是问题就在于这是单个list,如果有新的数据写入那么就会重新设置3分钟的时间周期,移动端访问的频率较高,所以如果有些数据时间周期快到了,这时新存入了一个数据,又给它续了一波命微笑。后来我们改写了token的存储方式,还是设置了3分钟的时间周期,这次新数据存入时就不会影响其他数据的时间周期。


结论:

如果是多个数据都有设置时间周期,那么这些数据不应该存放到list里面,时间周期是对key来说的,单一的list在多个数据设置时间周期时会重置掉




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值