redis 命令输入分号引发的惨案

都说习惯养成自然,这句话一点没错。

对于程序员原来说,一行代码写完后,随手敲一个分号作为分隔符,这是刻在骨子里面的事情。

写 SQL 语句,一行语句写完敲一个分号,这也是再正常不过的事情了。

然而,今天下午遇到一件奇葩事,因为一个分号的错误引入,导致酿成大错,不到一个小时的时间竟带来损失上千元。

小小分号竟然有如此威力?且听我细细道来。

图片

01

下午午睡刚起来,同事跟我说线上有个问题,有个企业员工创建一直不成功,时不时会重试一把,一直重试一直不成功。

创建员工会有一个uid 纬度的分布式锁用来防止并发,看日志是这个锁获取一直失败。

系统用的是 redis分布式锁,正常会有过期时间,重试的话总会有获取锁成功的时候。一直获取不到锁,只能说明这个 key 没有设置过期时间。

上 dms 控制台查询这个 key的情况。

一查,发现没有redis 库权限。权限分为查询、变更,第一次申请本着最小权限原则,只申请了查询权限。

权限申请好以后,在 dms 输入 

get  CREATE_USER_LOCK_KEY_XXX

返回 1;

输入

ttl CREATE_USER_LOCK_KEY_XXX

返回 -1;

好家伙,这不就是 key没有过期吗?怪不得一直获取不到锁。

确定是 key 没有设置过期时间,那要想让用户创建成功,只能将这个key请除掉。

再把 redis 库的变更权限申请下来。

有了库的变更权限,可以发起数据变更申请了。提交一个工单,申请数据变更,命令如下:

del CREATE_USER_LOCK_KEY_XXX;

老大审批通过,执行,执行成功!

OK,齐活了,跟企业反馈,重新同步下。

重试一次,同步不成功。

重试第二次,同步不成功。

WTF!

图片

02

问题出在了哪里?

莫非是提交的变更脚本不正确,再三检查,确认没有问题;

难道是dms 变更有缓存,两次重试间隔了5分钟,缓存不可能有这么长时间吧?

一定是 dms 数据变更存在 bug!对,就是他。提 dms 答疑工单,同步联系DBA。

虽然在这个过程中脑海中有飘过一个念头“出现奇奇怪怪的case ,一般都是自己的问题,很少有是中间件的问题”,但是很快一扫而过。

DBA 在了解完情况后,登录到redis 库,查询对应的key,发现 key值 还存在。

WTF!

图片

再次证明了我的推断,dms 数据变更存在 bug!

通过 dms 变更删除不了,线上问题又比较紧急,跟 DBA 沟通直接由他来执行命令删除。

DBA 删除后,反馈企业重试。OK,一把重试成功!

dms 数据变更真的存在bug吗?

带着这个问题,我们找到了 dms 的开发同学。

在经过短暂的排查后,一个噩耗传来:

图片

WTF!

图片

原来加了分号,redis 认为是另外一个key了。

那为什么一开始查询能查到呢?

回去翻阅查阅历史,发现第一次查的时候没有加分号!

整个排查过程,从始至终,耗时大约1个小时。前后有4位同学参与进来,按照每个同学平均月薪1.6w算,每天是800元,1小时就是100元,4个人共计 400元。

事实上,这个金额绝对是少算了,一小时总计上千应该不是问题。

一个小小的分号,耽误了大家一个小时,对公司来说相当于损失了近千元,说起来真是让人汗颜。

后来,同事跟我说,真是懊恼啊,浪费了半天时间。我跟他说,这个案例多么有价值,至少有两个点你估计会永远铭记于心:

1. redis 分布式加锁使用非原子操作真的会出现过期时间设置不上的问题

2. redis 命令加分号认为是一个新的 key

同事深以为然,在地铁上想来有趣,随手写了这边文章。

不知道读者看到这里是什么感想,习惯的力量真是可怕,容易固化人的思维,让一些简单的事情变得复杂。生活中,我们要尽量克服这种思维,有时候跳出原有的思路,换多个纬度想想,就会有不错的收获。

  • 27
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值