当前位置:网站首页>Redis zadd导致的一次线上问题排查和处理
Redis zadd导致的一次线上问题排查和处理
2022-07-02 06:33:00 【程序员柒柒】
背景
最近有用户反馈,主播收了1881数值礼物,头像下数字显示881, 正常来说,应该显示1881的数值。
经过排查,是因为redis zadd在并发情况下导致数据不一致的问题。
问题排查
经过对送礼日志的排查,发现mongodb数据更新正常,但是redis数据异常,查看业务代码后发现了问题。
业务代码如下:
这里的逻辑是先更新 mongodb, 然后对redis数值进行zadd覆盖. 一般情况下没啥问题, 但如果稍微遇到高并发:
- A线程跟B线程同时对mongo进行修改操作, 在数据库层面, B的修改后于A的修改.
- 但在进程中, 线程B先于线程A调用redis修改, 线程A对redis的修改覆盖了B的数值.
- 导致redis中数据维护错误.
问题修复
使用Lua脚本修改redis值,并发情况下不处理覆盖逻辑, 避免旧值覆盖新值,利用mongodb自增保证原子性。 代码如下:
Lua脚本如下:
SAFE_ZADD_SCRIPT = """
local key = KEYS[1]
local field = ARGV[1]
local new_value = tonumber(ARGV[2])
local old_value = redis.call("zscore", key, field)
local res = nil
if (not old_value) or (tonumber(old_value) < new_value)
then
res = redis.call('zadd', key, new_value, field)
end
return res
"""
复制代码
为啥不使用zincrby?
zincrby虽然保证不会有并发问题,但是如果key失效或者被清理,会导致排行榜从0开始计数,导致数据错误。
边栏推荐
猜你喜欢
随机推荐
C language - Blue Bridge Cup - 7 segment code
Analysis and solution of a classical Joseph problem
C# 高德地图 根据经纬度获取地址
查看was发布的应用程序的端口
PCL calculates the intersection of three mutually nonparallel planes
Sqli labs level 12
Npoi export word font size correspondence
Openshift build image
C#钉钉开发:取得所有员工通讯录和发送工作通知
Qt的connect函数和disconnect函数
2022/2/14 summary
Sentinel 简单使用
Shengshihaotong and Guoao (Shenzhen) new energy Co., Ltd. build the charging pile industry chain
Googlenet network explanation and model building
Connect function and disconnect function of QT
ORA-12514问题解决方法
kubernetes部署loki日志系统
OpenFeign 简单使用
gocv opencv exit status 3221225785
OpenShift 容器平台社区版 OKD 4.10.0部署