redis返回的结果是null_记一次线上Redis故障恢复和分析(二)

本文详述了一次线上Redis故障的恢复和分析过程,问题表现为incrBy命令返回异常,导致业务流程中断。经过测试和日志分析,发现原因是Jedis超时时间设置过短,触发TCP重传,造成Redis执行多次命令。解决方案是延长Jedis的超时时间,并对Redis集群进行优化,以避免key分布不均导致的超时问题。
摘要由CSDN通过智能技术生成

异常场景

最近一段时间时不时就有开发人员向我反应:redis的key有点问题,帮我删个key值、怎么key没有过期,我明明设了过期时间的。一开始没有放心上,以为只是程序逻辑处理不当或者redis偶尔抽风,不用在意。可是渐渐反应的人多了,觉得可能不是这么简单了,于是就和相关的开发人员讨论了下,发现会出现异常的基本是以下两种场景:

  • 使用redis 的 incrBy 命令来防止重复提交,大致的redis交互如下:
 incrBy key 1 # 返回 1 表示正常 返回 > 1  表示重复提交 直接 return expire key 5 # 5秒后过期 del key # 正常业务逻辑走完后 显示删除key
  • 使用 redis (set setnx setex ) + expire 组合命令:
 set |setnx | setex key expire key seconds # 设置失败

由于系统中大量使用了第一种方式来防止重复提交,所以这个问题对业务影响还是很大的,redis具体现象为:

  • 设置incrby 第一次应该返回 1
  • 实际上却返回了 2 ,导致业务流程无法走完,并且key没有删除也没有设置过期时间

查找问题

编写测试程序

为了排查问题写了一个简单的小程序:

@Testpublic void test() throws InterruptedException {    final List list = Lists.newArrayListWithCapacity(5000000);    Long first_id = 500000000000000001L;    for (int i = 0; i < 5000000; i++) {        list.add(first_id++);    }    final CountDownLatch allDone = new CountDownLatch(2);    // incrby    new Thread(        new Runnable() {                        public void run() {                try {                    testIncrby(list);                } catch (InterruptedException e) {                }                allDone.countDown();            }        }    ).start();    new Thread(        new Runnable() {                        public void run() {                try {                    testIncrByAndDel(list);                } catch (InterruptedException e) {                }                allDone.countDown();            }        }    ).start();    allDone.await();    log.info("finish method test");}public void testDelAndTTL() throws InterruptedException {    final List list = Lists.newArrayListWithCapacity(5000000);    Long first_id = 500000000000000001L;    for (int i = 0; i < 5000000; i++) {        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值