本文档提供了关于 Valkey 如何响应各种 POSIX 信号(如 SIGTERM
和 SIGSEGV
)的信息。
SIGTERM 和 SIGINT
SIGTERM
和 SIGINT
信号指示 Valkey 优雅地关闭。当服务器收到这些信号时,它不会立即退出。相反,它会安排一次与 SHUTDOWN
命令执行的关闭类似的关闭。计划的关闭会尽快开始,具体来说,只要当前正在执行的命令终止(如果有),就会开始,并可能额外延迟 0.1 秒或更少。
如果服务器被长时间运行的 Lua 脚本阻塞,请尽可能使用 SCRIPT KILL
终止该脚本。计划的关闭将在脚本被终止或自动终止后立即运行。
此关闭过程包括以下操作
- 如果有任何副本在复制方面落后
- 使用
CLIENT PAUSE
和WRITE
选项暂停尝试写入的客户端。 - 等待最多配置的
shutdown-timeout
(默认 10 秒),以便副本赶上主节点的复制偏移量。
- 使用
- 如果后台子进程正在保存 RDB 文件或执行 AOF 重写,则终止该子进程。
- 如果 AOF 处于活动状态,Valkey 会对 AOF 文件描述符调用
fsync
系统调用,以将缓冲区刷新到磁盘。 - 如果 Valkey 配置为使用 RDB 文件持久化到磁盘,则会执行同步(阻塞)保存。由于保存是同步的,因此不会使用任何额外的内存。
- 如果服务器已守护进程化,则移除 PID 文件。
- 如果 Unix 域套接字已启用,则将其移除。
- 服务器以零退出代码退出。
如果 RDB 文件无法保存,关闭将失败,服务器将继续运行以确保数据不丢失。同样,如果用户刚刚开启 AOF,并且服务器触发了第一次 AOF 重写以创建初始 AOF 文件,但该文件无法保存,则关闭将失败,服务器将继续运行。除非收到新的 SIGTERM
信号或发出 SHUTDOWN
命令,否则不会再尝试关闭。
自 Redis OSS 7.0 起,服务器在关闭前会等待滞后的副本,最长可达可配置的 shutdown-timeout
(默认为 10 秒)。这提供了最大努力来最小化在没有配置保存点且 AOF 未激活的情况下数据丢失的风险。在 7.0 版本之前,在无盘设置中关闭一个负载沉重的主节点更容易导致数据丢失。为了最小化此类设置中的数据丢失风险,请在关闭主节点之前,触发手动 FAILOVER
(或 CLUSTER FAILOVER
)将主节点降级为副本,并将其中一个副本提升为新的主节点。
SIGSEGV, SIGBUS, SIGFPE 和 SIGILL
以下信号被视为 Valkey 崩溃处理
- SIGSEGV
- SIGBUS
- SIGFPE
- SIGILL
一旦捕获到这些信号之一,Valkey 会停止任何当前操作并执行以下动作
- 将错误报告添加到日志文件。这包括堆栈跟踪、寄存器转储以及客户端状态信息。
- 执行快速内存测试,作为对崩溃系统可靠性的初步检查。
- 如果服务器已守护进程化,则移除 PID 文件。
- 最后,服务器会注销其自身针对收到的信号的信号处理器,并重新向自身发送相同的信号,以确保执行默认操作,例如在文件系统上转储核心文件。
当子进程被终止时会发生什么
当执行仅追加文件重写的子进程被信号终止时,Valkey 会将其视为错误并丢弃(可能是部分或损坏的)AOF 文件。它将在稍后再次尝试重写。
当执行 RDB 保存的子进程被终止时,Valkey 会将此情况视为更严重的错误。虽然 AOF 文件重写失败可能导致 AOF 文件增大,但 RDB 文件创建失败会降低持久性。
由于生成 RDB 文件的子进程被信号终止,或者子进程以错误(非零退出代码)退出,Valkey 会进入一种特殊错误状态,在此状态下不再接受任何写入命令。
- Valkey 将继续响应读取命令。
- Valkey 将以
MISCONFIG
错误响应所有写入命令。
此错误状态将持续存在,直到可以成功创建 RDB 文件。
无错误地终止 RDB 文件保存进程
有时用户可能希望在不生成错误的情况下终止 RDB 保存子进程。这可以通过使用 SIGUSR1
信号来完成。该信号以特殊方式处理:它像其他任何信号一样终止子进程,但父进程不会将其检测为严重错误,并将继续服务写入请求。