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 文件。
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
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
小智 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)
参考:
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)
| 归档时间: |
|
| 查看次数: |
20246 次 |
| 最近记录: |