Redis 提供了多种工具,旨在提高和维护高效的内存数据库使用。虽然其独特的数据类型和命令可以微调数据库以在应用程序级别无需任何额外的处理来满足应用程序请求,但错误配置,或者更确切地说,使用开箱即用的配置,会导致操作挑战和性能问题。尽管这些挫折导致了许多头疼的问题,但解决方案确实存在,而且可能比预期更简单。本系列文章将重点介绍使用 Redis 时出现的一些最令人恼火的问题,以及解决这些问题的技巧。它们基于我们运行数千个 Redis 数据库实例的真实经验。
继我们之前在该系列文章中发布的关于 复制缓冲区的文章之后,我们列表中的下一个难题将继续讨论主从复制主题。特别是,我们将更深入地了解完成该过程所需的时间长度以及可能导致重大不便的一些配置问题。
正如我们在之前的 无限复制循环帖子中讨论的那样,Redis 的复制过程由两个同步阶段组成:初始阶段和持续阶段。虽然持续阶段相当稳定(只要主服务器和从服务器之间的连接保持不变),但初始阶段完成起来有些棘手。初始同步的成功完成不仅取决于为复制缓冲区分配的内存量(请参见 之前的难题),还取决于此步骤所需的时间量。
您可能还记得,初始同步步骤包括后台保存并将整个数据库从主服务器传输到从服务器。根据数据集的大小和网络连接的质量,这可能是一个漫长的过程。如果该阶段花费的时间太长,Redis 的复制超时设置可能会达到,从而导致初始阶段反复重复,令人厌烦。在这种情况下,您会发现从服务器的 Redis 日志中充满了类似于以下内容的消息
[28618] 21 Jul 00:33:36.031 * Connecting to MASTER 10.60.228.106:25994
[28618] 21 Jul 00:33:36.032 * MASTER <-> SLAVE sync started
[28618] 21 Jul 00:33:36.032 * Non blocking connect for SYNC fired the event.
[28618] 21 Jul 00:33:36.032 * Master replied to PING, replication can continue...
[28618] 21 Jul 00:33:36.032 * Partial resynchronization not possible (no cached master)
[28618] 21 Jul 00:33:36.032 * Full resync from master: 549907b03661629665eb90846ea921f23de6c961:2537453
Redis 的复制超时默认设置为 60 秒(请参见 redis.conf 文件 中的 repl-timeout 指令,或者使用 redis-cli 执行 config get repl-timeout )。这段时间可能太短,尤其是在以下情况下
存储缓慢:如果主服务器和/或从服务器连接到性能较低的存储设备,这会导致主服务器的后台保存过程花费大量时间。在从服务器的情况下,从磁盘写入和加载数据可能会延长。
大型数据集:数据集越大,保存和传输所需的时间就越长。
网络性能:当主服务器和从服务器之间的网络连接带宽有限和/或延迟较高时,会直接影响数据传输速率。
您可以通过将复制超时设置为更合适的值来解决此问题。首先,估算一下复制数据库所需的时间。首先,检查 Redis 执行后台保存需要多长时间,方法是执行 BGSAVE 命令并检查日志文件以查找相关行(即 * Background saving started by pid nnn * 表示该进程已启动,而 * Background saving terminated with success * 表示该进程已终止)。接下来,计时将生成的 RDB 文件从主服务器复制到从服务器磁盘需要多长时间。最后,您需要计时实际从磁盘加载数据需要多长时间(例如,通过重新启动 Redis 并查找日志文件中的 * DB loaded from disk 行)。这些测量的总和可以作为您所需复制超时值的粗略估计,但您可能需要为安全起见再增加 10-20%。
根据估计值设置好超时时间后,您可以通过让从服务器执行几次完全同步并检查日志文件来测试复制实际需要多长时间。如果可能,请尝试在一天中的不同时间重复此练习,以便更好地了解系统在不同负载下的行为。最后,请记住,应该根据数据库的增长定期查看超时设置的值。
这结束了我们对 Redis 复制难题的回顾。复制是保持数据库可用和扩展其读取吞吐量的强大工具,但请注意默认设置,并确保已根据您的用例配置数据库。
如果您已阅读完本文,并想深入了解 DevOps 头疼的下一个常见原因,请继续阅读有关 客户端缓冲区的信息。