Redis守护进程没有创建PID文件

jsm*_*rtt 16 redis rhel6

Redis启动脚本应该在启动时创建一个pid文件,但我已经确认了我能找到的所有设置,并且没有创建任何pid文件.

我安装了redis:

$ yum install redis
$ chkconfig redis on
$ service redis start
Run Code Online (Sandbox Code Playgroud)

在我的配置文件(/etc/redis.conf)中,我检查了以确保这些已启用:

daemonize yes
pidfile /var/run/redis/redis.pid
Run Code Online (Sandbox Code Playgroud)

在启动脚本(/etc/init.d/redis)中有:

exec="/usr/sbin/$name"
pidfile="/var/run/redis/redis.pid"
REDIS_CONFIG="/etc/redis.conf"

[ -e /etc/sysconfig/redis ] && . /etc/sysconfig/redis

lockfile=/var/lock/subsys/redis

start() {
    [ -f $REDIS_CONFIG ] || exit 6
    [ -x $exec ] || exit 5
    echo -n $"Starting $name: "
    daemon --user ${REDIS_USER-redis} "$exec $REDIS_CONFIG"
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $name: "
    killproc -p $pidfile $name
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}
Run Code Online (Sandbox Code Playgroud)

这些是安装时默认提供的设置.知道为什么没有创建pid文件?我需要将它用于Monit.(系统是RHEL 6.4 btw)

Sab*_*rov 32

对于那些在 Debian buster 上体验的人:

编辑 nano /etc/systemd/system/redis.service

并在redis下面添加这一行 [Service]

ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis/redis.pid"

它看起来像这样:

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
ExecStop=/bin/kill -s TERM $MAINPID
ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis/redis.pid"
PIDFile=/run/redis/redis-server.pid
Run Code Online (Sandbox Code Playgroud)

然后:

sudo systemctl daemon-reload

sudo systemctl restart redis.service

检查 redis.service 状态:

sudo systemctl status redis.service 现在应该会出现 pid 文件。

  • 非常感谢,这也解决了 Ubuntu 18.04 的问题 (3认同)
  • Ubuntu 20.04.2 的正确修复 (3认同)

jgr*_*cha 21

在我的Ubuntu 18.04上,我遇到了同样的错误。

redis(在/var/log/redis/redis-server.log)报告的错误: # Creating Server TCP listening socket ::1:6379: bind: Cannot assign requested address

这是因为我已在此主机上禁用了IPv6,redis-server而Ubuntu的软件包(版本5:4.0.9-1)具有以下功能: bind 127.0.0.1 ::1

编辑/etc/redis/redis.conf和注释行,或删除::1地址都可以解决此问题。例: # bind 127.0.0.1 ::1

  • 这一定与我的问题无关,因为该步骤对我没有帮助。`sudo systemctl status redis` 导致 `redis-server.service: Can't open PID file /var/run/redis/redis-server.pid (yet?) after start: No such file or directory`,但是该文件确实存在并且由“redis”拥有。删除 IPv6 绑定没有帮助。 (4认同)

jsm*_*rtt 12

问题是用户redis没有权限创建pid文件(或它所在的目录).固定:

sudo mkdir /var/run/redis
sudo chown redis /var/run/redis
Run Code Online (Sandbox Code Playgroud)

然后我杀了并重新启动了redis,果然,还有redis.pid

  • 这在 Ubuntu 18.04 上还不够。权限没问题。有时 PID 文件存在,有时不存在。没有逻辑。这使得Redis难以监控。 (3认同)

小智 10

在CentOs 7中我需要添加到文件中:

$ vi /usr/lib/systemd/system/redis.service
Run Code Online (Sandbox Code Playgroud)

下一行:

ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis/redis.pid"
Run Code Online (Sandbox Code Playgroud)

然后重启服务:

$ sudo systemctl daemon-reload
$ sudo systemctl restart redis.service
Run Code Online (Sandbox Code Playgroud)

参考:

CentOs 7:系统和PID文件

  • 这可以使用Ubuntu 18.04,但文件`redis.service`位于路径`/ etc/systemd/system /`. (2认同)

brt*_*brt 10

我在Debian Buster上遇到了类似的问题,systemd 抱怨缺少 PID 文件,即使该文件存在并且 redis 正在运行。

在我的系统上,使用的解决方案"echo $MAINPID > /run/redis/redis.pid" 偶然工作,虽然/因为真实的 PID 文件被设置为/run/redis/redis-server.pid (发现不同的文件名!)并且在我的系统上 /run/redis/redis.pid 的内容(回声之一)是空的。

关于 systemd-devel@lists.freedesktop.org讨论中,有人写道:

... systemd 将在知道主 PID 是什么时添加 MAINPID 环境变量。它通过读取 PID 文件来了解这一点……因此到 ExecStartPost 运行时,主 PID 可能已知也可能未知

拥有一个空的 MAINPID 环境变量甚至可能是有害的:如果您注意到建议解决方案中的不同 PID 文件名,并对其进行更正,您可能最终会遇到由 redis 写入的 PID 文件被空文件覆盖的情况。这发生在我身上,结果systemctl start redis.service永远没有完成。

我还注意到另一台具有 100% 相同操作系统和配置的服务器,但不同的硬件没有这个问题。

我的结论是它只是遇到了某种竞争条件,systemd 似乎过早地寻找 PID 文件。在我的系统上,无论我使用什么命令作为 ExecStartPost,它都会增加足够的延迟以使错误消失。

因此,解决方案是使用“睡眠 1”(睡眠 0.1 也可以,但 1 秒可能是安全的):

ExecStartPost=/bin/sleep 1
Run Code Online (Sandbox Code Playgroud)

/etc/systemd/system/redis.service 现在看起来像:

[Service]
Type=forking
ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
ExecStartPost=/bin/sleep 1
ExecStop=/bin/kill -s TERM $MAINPID
PIDFile=/run/redis/redis-server.pid
...
Run Code Online (Sandbox Code Playgroud)

一个替代的解决方案是使用“有监督systemd”:

/etc/redis/redis.conf:

# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
#   supervised no      - no supervision interaction
#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
#   supervised auto    - detect upstart or systemd method based on
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
#       They do not enable continuous liveness pings back to your supervisor.
supervised systemd
Run Code Online (Sandbox Code Playgroud)

使用以下命令覆盖 redis-server.service 文件:

systemctl edit redis-server.service
Run Code Online (Sandbox Code Playgroud)

并输入以下内容:

[Service]
Type=notify
Run Code Online (Sandbox Code Playgroud)

重新加载服务,错误应该消失了:

sudo systemctl restart redis.service
sudo systemctl status redis.service 
Run Code Online (Sandbox Code Playgroud)