Redis 信号处理
Redis 如何处理常见的 Unix 信号
Redis 堆栈 | Redis 社区版 |
---|
本文档提供有关 Redis 如何对不同 POSIX 信号做出反应的信息,例如SIGTERM
和SIGSEGV
.
本文档中的信息仅适用于 Redis 版本 2.6 或更高版本。
SIGTERM 和 SIGINT
这SIGTERM
和SIGINT
信号告诉 Redis 正常关闭。当服务器收到这个信号时,
它不会立即退出。相反,它会安排
类似于SHUTDOWN
命令。计划的关闭会尽快开始,特别是只要
当前命令终止(如果有),并可能附加
延迟 0.1 秒或更短。
如果服务器被长时间运行的 Lua 脚本阻止,则
杀死脚本SCRIPT KILL
如果可能的话。计划关闭将
在脚本被终止或自发终止后立即运行。
此关闭过程包括以下作:
- 如果复制中存在滞后的副本:
- 暂停尝试写入的客户端
CLIENT PAUSE
和WRITE
选择。 - 等待配置的
shutdown-timeout
(默认 10 秒),以便副本赶上主服务器的复制偏移量。
- 暂停尝试写入的客户端
- 如果后台子进程正在保存 RDB 文件或执行 AOF 重写,则子进程将被终止。
- 如果 AOF 处于活动状态,Redis 会调用
fsync
system 调用 AOF 文件描述符以刷新磁盘上的缓冲区。 - 如果 Redis 配置为使用 RDB 文件保留在磁盘上,则会执行同步(阻塞)保存。由于保存是同步的,因此它不会使用任何额外的内存。
- 如果服务器已守护,则 PID 文件将被删除。
- 如果启用了 Unix 域套接字,则会将其删除。
- 服务器退出时,退出代码为零。
如果无法保存 RDB 文件,则关闭将失败,服务器将继续运行以确保不会丢失数据。
同样,如果用户刚刚开启了 AOF,并且服务器触发了第一次 AOF 重写以创建初始 AOF 文件,但无法保存此文件,则关闭将失败,服务器将继续运行。
从 Redis 2.6.11 开始,除非在编辑器中使用新的SIGTERM
收到 或SHUTDOWN
命令。
从 Redis 7.0 开始,服务器会等待滞后副本,直到shutdown-timeout
,默认情况下为 10 秒,然后关闭。
这提供了最大努力,以便在未配置保存点且 AOF 已停用的情况下最大限度地降低数据丢失的风险。
在版本 7.0 之前,在无盘设置中关闭负载较重的主节点更可能导致数据丢失。
为了最大限度地降低此类设置中数据丢失的风险,请触发手动FAILOVER
(或CLUSTER FAILOVER
) 将主节点降级为副本,并在关闭主节点之前将其中一个副本提升为新的主节点。
SIGSEGV、SIGBUS、SIGFPE 和 SIGILL
以下信号作为 Redis 崩溃处理:
- SIGSEGV 公司
- SIGBUS 公司
- SIGFPE
- 西吉尔
一旦捕获这些信号之一,Redis 就会停止任何当前作并执行以下作:
- 将 bug 报告添加到日志文件中。这包括堆栈跟踪、寄存器转储以及有关客户端状态的信息。
- 从 Redis 2.8 开始,执行快速内存测试作为对崩溃系统可靠性的首次检查。
- 如果服务器已守护 (daemonized),则会删除 PID 文件。
- 最后,服务器为收到的信号取消注册自己的 signal 处理程序,并将相同的 signal 重新发送到自身,以确保执行默认作,例如将核心转储到文件系统上。
当子进程被终止时会发生什么情况
当执行 Append Only File 重写的子进程被信号杀死时, Redis 将此作为错误处理,并丢弃(可能是部分或损坏的) AOF 文件。稍后将再次尝试重写。
当执行 RDB 保存的子项被终止时,Redis 会处理 条件设置为更严重的错误。虽然 AOF 文件重写会导致 AOF 文件放大、RDB 文件失败 创造会降低耐久度。
由于生成 RDB 文件的子项被信号终止, 或者当子项退出并显示错误(非零退出代码)时,Redis 进入 一种特殊的错误情况,即不接受进一步的写入命令。
- Redis 将继续回复读取命令。
- Redis 将使用
MISCONFIG
错误。
此错误情况将一直存在,直到可以成功创建 RDB 文件。
杀死 RDB 文件而不出错
有时,用户可能希望终止保存 RDB 的子进程,而无需
生成错误。从 Redis 版本 2.6.10 开始,这可以使用 signal 来完成SIGUSR1
.此信号以特殊方式处理:
它会像任何其他信号一样杀死子进程,但父进程会
不会将此检测为严重错误,并将继续提供写入服务
请求。