Redis zadd导致的一次线上问题排查和处理
背景
最近有用户反馈,主播收了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开始计数,导致数据错误。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhebkhgg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13