FG
🗄️ Databases

高负载的时候会出现数据错误!!

Freshover 10 years ago
Mar 14, 20260 views
Confidence Score84%
84%

Problem

开始是 ioredis + redis,因为准备加更多的缓存,所以换成了 codis。开始是正常的,直到某次代码更新,增加了大量的缓存数据。然后一直都会出现奇怪的错误,比如 get 一个数字,却返回了一串字符,总之返回的不是想要取的数据。在最简单的 redis.get("key") 代码里也会出现…… 同时伴随着 node 内存使用会增加很多(大部分会这样),我们以为是 codis 的问题,于是又把 codis 换回到原生的 redis 了。 这时候已经正常了(或者还有低概率发生这种情况但是没有发现,因为从 redis 取一段数据存到另一个地方可能并不会报错,类型被自动转换了之类的)。 直到昨天服务上整体的访问量翻了 N 倍,突然又爆发出来这个问题。我们用的 sentry,会一直出现各种奇怪的 cast 错误……比如把一串 json string cast 到 _id ,总之是和上面一样的问题。而且会集中爆发在一个或几个特定的 node 实例上,重启即可正常。 现在只能怀疑 ioredis 的 异步处理方式是不是在高负载下并不能保证正确的工作?因为 redis 协议的实现方式正确性基本依赖于一一对应的命令和应答,然而在 ioredis 里接收到应答是放到一个队列里(并没有仔细看源码,但好像大体是这么写的),然后通过 command send 的队列回调取去对应的数据,所以如果中间丢失了一段的话,那么这个 connection 之后的所有数据都会串掉…… 这个问题非常可怕。。。。

Unverified for your environment

Select your OS to check compatibility.

1 Fix

Canonical Fix
Moderate Confidence Fix
84% confidence100% success rate1 verificationLast verified Mar 14, 2026

Solution: 高负载的时候会出现数据错误!!

Low Risk

出现这种问题时客户端到 Redis 之间没有设置其他代理了吗?Redis 协议必须依赖于服务器能够严格按照请求顺序依次返回处理结果,否则就会出现你说的问题。 就像你说的,ioredis 会把发出的命令存储在队列中,每当收到新回复时就会弹出命令进行处理。这个队列本身是可靠的,不会“中间丢失了一段”。目前 ioredis 还没有收到过直连 Redis 出现类似问题的反馈,你们的 qps 大概是多少呢?换成 hiredis 解析模块(`npm install hiredis` 后,ioredis 会自动使用 hiredis)会有类似的问题吗?

84

Trust Score

1 verification

100% success
  1. 1

    出现这种问题时客户端到 Redis 之间没有设置其他代理了吗?Redis 协议必须依赖于服务器能够严格按照请求顺序依次返回处理结果,否则就会出现你说的问题。

    出现这种问题时客户端到 Redis 之间没有设置其他代理了吗?Redis 协议必须依赖于服务器能够严格按照请求顺序依次返回处理结果,否则就会出现你说的问题。

  2. 2

    就像你说的,ioredis 会把发出的命令存储在队列中,每当收到新回复时就会弹出命令进行处理。这个队列本身是可靠的,不会“中间丢失了一段”。目前 ioredis

    就像你说的,ioredis 会把发出的命令存储在队列中,每当收到新回复时就会弹出命令进行处理。这个队列本身是可靠的,不会“中间丢失了一段”。目前 ioredis 还没有收到过直连 Redis 出现类似问题的反馈,你们的 qps 大概是多少呢?换成 hiredis 解析模块(`npm install hiredis` 后,ioredis 会自动使用 hiredis)会有类似的问题吗?

Validation

Resolved in redis/ioredis GitHub issue #189. Community reactions: 0 upvotes.

Verification Summary

Worked: 1
Last verified Mar 14, 2026

Sign in to verify this fix

Environment

Submitted by

AC

Alex Chen

2450 rep

Tags

redisiorediscache