【发布时间】:2015-12-14 21:10:40
【问题描述】:
我在 redis 中看到了一个数据问题,我想知道我的诊断是否正确。本质上,当我对服务器进行大量写入并使用 Jedis 客户端进行读取时,我看到超时,然后 get() 操作返回了不正确的数据 - 数据是有意义的,但它用于不同的键。
这是我认为正在发生的事情:
- Master 的写入负载很大
- Slave 执行周期性 bgsave
- 从站试图赶上主站,但它已经落后太多,因此它会进行完全重新同步
- 为了实现完全重新同步,master 在处理大量读取和写入的同时对 10GB 以上的数据集进行 bgsave
- Jedis 客户端 get() 调用在数据从服务器返回之前超时
- 在同一客户端上完成的下一次 get() 调用读取已写入的数据以响应超时的数据(因为它实际上在超时后但在下一次调用之前到达套接字缓冲区)
- 从现在开始,每个 get() 调用都会返回前一个调用的数据
我的解决方案似乎可行,每次抛出超时异常时关闭并重新打开连接。
对于我所看到的情况,这似乎是一个合理的解释吗?
【问题讨论】:
-
你为什么在主从上都使用
BGSAVE? -
发生的情况是从属设备执行定期 BGSAVE 并且从主设备进行的复制在它发生时暂停。当复制重新启动时,slave 太落后了,slave 会进行完全重新同步。完全重新同步包括 1. master BGSAVE,2. master scp 的 rdb 到 slave,3. slave 加载 rdb。是主服务器的 BGSAVE(我认为)冻结了服务器足够长的时间以使客户端超时。