pidfile 与 PIDFile 路径不一致时,引起的 redis 无法通过 systemd 启动

问题现象

  • 现象1:使用 systemctl 不能正常启动 redis 服务,状态显示为 activating,无法正常进入 active(running) 状态。

  • 现象2:手动执行 redis 进程启动命令:redis-server /etc/redis/redis.conf 能正常启动和提供服务。


排查结果

redis 配置文件中使用 pidfile 指定的文件路径 和 systemd service 配置文件中 PIDFile 指定的路径不一致导致的。

因为 redis 配置文件中指定 redis 采用守护进程模式运行(daemonize yes),systemd 中 service 要托管守护进程时,需要使用 forking 这种启动模式,并且还要配置 PIDFile 来指定,需要托管哪个进程。

如果这个PIDFile 指定路径下的文件不存在,systemd 就不知道要托管哪个进程,也就导致了无法正常启动。

注意:PIDfile 指令指定一个文件时,只会去这个文件中读取进程的PID,不会去创建,创建是 进程自己干的事。


知识补充

linux 中的三种进程类型

  • 前台进程:在当前终端直接运行命令启动的进程,会独占当前终端,在进程生命周期结束前,没法使用这个终端做其他操作;终端关闭,该进程也就跟着结束了,因为它是做为当前终端子进程的形式运行的,父进程结束后,会给子进程发送 HUB 信号,收到后也就结束了。

  • 后台进程:就是将前台进程放在后台执行,从而释放当前终端,可以用这个终端执行其他任务;但是终端关闭,这个后台进程还是会结束,因为它还是终端的子进程,终端结束发的HUB信号,它还是能收到和处理。

  • 守护进程:一种特殊的后台进程,它脱离了终端的控制,不再是终端的子进程,收不到终端信号,所以能独立长期运行。

守护进程的创建流程:

  • 简单理解就是先使用指令创建 进程A,进程A 会fork(复制)一个子进程B,然后进程A退出,由进程B来提供服务。

service 的三种启动类型

systemd 是现代 linux 操作系统启动的第一个用户进程,也就是PID=1的进程,systemd 通过 资源管理单元(unit)来对系统资源进行管理。

service 这种 unit 是用来运行、管理守护进程的,也就是某个进程要长期提供服务,可以通过 service 来进行托管。

systemd 的 service 通过编写配置文件来托管进程服务,配置文件采用 Section(节)来进行组织。

[Service] 这个 Section 中,通过 ExecStart 来指定通过哪个指令来启动需要托管的进程,通过 Type 来指定采用何种方式启动这个进程。


simple 类型:

  • 默认的启动方式,前台进程、后台进程采用这种启动方式
  • 这种启动方式就是如果通过 ExecStart 指定的指令成功执行了,就认为启动成功了,状态显示为:active(running)

notify 类型:

  • 和 simple 一样,只不过 通过 ExecStart 指定的指令成功执行了后,这个进程会主动给 systemd 发送一个信号,说自己已经准备好了,此时才会显示启动成功。
  • 如果某个进程不会给 systemd 发信号,用这个启动方式会出现一直卡在 activating 状态。

forking 类型:

  • 这种方式是用来托管守护进程的,如果某个进程采用守护进程的方式运行,就需要使用这种启动方式。
  • 通过 ExecStart 指定的指令启动的进程是进程A,然后进程A 在 fork 子进程(进程B)退出的时候,会将进程B的PID写入一个文件,具体在哪里,一般是由配置文件指定的路径。
  • 然后 systemd 还需要使用 PIDFile 指令去指定从哪里找这个进程的PID,从而确定要托管的进程。如果找不到就会一直卡在activating 状态。

posted on 2025-11-19 18:47  一直小爪子  阅读(17)  评论(0)    收藏  举报