XX公司生产事故-高并发下访问redis一个key

故障分析:
在分布式服务部署环境,高并发访问时,一个seq生成到临界点了,单秒订单记录重复,然后引发了一系列的问题

问题代码:

1
2
3
4
5
6
7
8
9
public string getSeq(){
long seq=redisClient.incr(SN_REDIS_KEY);
if(seq>999999){
seq=1;
redisClient.del(SN_REDIS_KEY);
seq=redisClient.incr(SN_REDIS_KEY);
}
return string.format("%06d",seq);
}

原因:
这段代码是redis客户端执行del操作,下一步是incr操作,如果是在高并发场景下,没有加锁控制,会导致服务副本不安全执行上面的代码导致redis客户端返回的数据是脏数据,从而程序的执行逻辑出现异常.

解决:
这段代码如果是单体服务,要做进程内的加锁操作,可以使用sync(低效率简单),也可以使用可重入锁.
如果是在分布式多副本环境下,要做分布式锁操作,方案有三个:
使用zk实现分布式锁,在锁环境下操作上述代码.
使用redis实现全局原子性操作,redis可以分发分布式锁,redis可以执行lua脚本,保障全局下,这段代码操作的原子性.

秦老师的解决方案:
ringbuffer,imax方案,单机tps达到600万.