41

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

我通过以下方式安装了redis:

$ yum install redis
$ chkconfig redis on
$ service redis start

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

daemonize yes
pidfile /var/run/redis/redis.pid

在启动脚本(/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
}

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

4

11 回答 11

44

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

redis(on )报告的错误/var/log/redis/redis-server.log

 # Creating Server TCP listening socket ::1:6379: bind: Cannot assign requested address

这是因为我在此主机上禁用了 IPv6,并且redis-serverUbuntu 的软件包(版本 5:4.0.9-1)附带:

bind 127.0.0.1 ::1

编辑/etc/redis/redis.conf和删除::1地址可以解决问题。例子:

bind 127.0.0.1

编辑:正如评论中指出的(感谢@nicholas-vasilaki 和@tommyalvarez),默认情况下redis 只允许来自本地主机的连接。评论所有行,使用:

# bind 127.0.0.1 ::1

有效,但让 redis 从网络(不仅从本地主机)监听。

更多细节可以在redis 配置文件中找到。

于 2018-11-05T19:34:35.503 回答
40

对于那些体验 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

然后:

sudo systemctl daemon-reload

sudo systemctl restart redis.service

检查 redis.service 状态:

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

于 2020-03-27T12:17:34.670 回答
26

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

sudo mkdir /var/run/redis
sudo chown redis /var/run/redis

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

于 2014-08-27T14:10:25.800 回答
16

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

$ vi /usr/lib/systemd/system/redis.service

下一行:

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

然后重启服务:

$ sudo systemctl daemon-reload
$ sudo systemctl restart redis.service

参考:

CentOs 7:Systemd 和 PID 文件

于 2017-01-03T22:41:12.980 回答
13

我在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,它都会增加足够的延迟以使错误消失。

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

ExecStartPost=/bin/sleep 1

/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
...

另一种解决方案是使用“监督 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

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

systemctl edit redis-server.service

并输入以下内容:

[Service]
Type=notify

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

sudo systemctl restart redis.service
sudo systemctl status redis.service 
于 2020-07-07T00:42:08.893 回答
2

从 2018 年开始

在开始之前,我在 Ubuntu 18.04 上。如果有人通过搜索相同的错误来到这里,我会写这个。

在我的情况下,错误是相同的,但问题是如此不同。此处提出的解决方案均无效。

所以我检查了日志是否存在并寻找有什么有用的。发现它们;

cat /var/log/redis/redis-server.log

搜索日志,发现问题是另一个服务正在侦听同一个端口

2963:C 21 Sep 11:07:33.007 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2963:C 21 Sep 11:07:33.008 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=2963, just started
2963:C 21 Sep 11:07:33.008 # Configuration loaded
2974:M 21 Sep 11:07:33.009 # Creating Server TCP listening socket 127.0.0.1:6379: bind: Address already in use 

我检查了谁在听。

netstat anp | grep 6379

找到了。

tcp6       0      0 :::6379                 :::*                    LISTEN      3036/docker-proxy   

是另一个工具安装的redis的docker镜像

root@yavuz:~# docker ps
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS                   PORTS                    NAMES
a6a94d401700        redis:3.2                   "docker-entrypoint.s…"   20 hours ago        Up 3 hours               0.0.0.0:6379->6379/tcp   incubatorsuperset_redis_1

所以我停止了 docker image

root@yavuz:~# docker stop incubatorsuperset_redis_1

并且 redis-server 启动没有问题。

root@yavuz:~# systemctl start redis-server
root@yavuz:~# systemctl status redis-server
● redis-server.service - Advanced key-value store
   Active: active (running) since Fri 2018-09-21 11:10:34 +03; 1min 49s ago
  Process: 3671 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
于 2018-09-21T08:35:01.170 回答
0
sudo nano /etc/redis/redis.conf

在文件中,找到受监督的指令。该指令允许您声明一个初始化系统来将 Redis 管理为服务,从而为您提供对其操作的更多控制。监督指令默认设置为 no。由于您正在运行使用 systemd init 系统的 Ubuntu,请将其更改为 systemd。

于 2020-05-23T14:47:32.860 回答
0

对于 CentOS:

在我的情况下,Redis 服务器的名称是redis.service,启动它编辑

systemctl edit redis.service

添加这个:

[Service]

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

我的情况是它创建文件:/etc/systemd/system/redis.service.d/override.conf

重启服务后:

systemctl daemon-reload
systemctl restart redis

pid文件是:

cat /var/run/redis/redis.pid 
=> 19755
于 2021-08-02T14:39:09.773 回答
0

我的默认设置是,Redis 不作为守护进程运行,这就是它不创建 pid 文件的原因。如果您查看/etc/redis/redis.conf,它会在 General 下明确表示。

#By default Redis does not run as a daemon.  Use 'yes' if you need it...
daemonize no

所以你需要做的就是把它改成daemonize yes

于 2022-02-08T17:04:27.207 回答
-1

对于那些难以让它在 Ubuntu 18.04 上工作的人,您需要编辑/etc/redis/redis.conf和更新 pidfile 声明,如下所示:

pidfile "/var/run/redis/redis-server.pid"
于 2019-11-11T12:00:14.273 回答
-1

Ubuntu 18./var/run/redis 权限错误:drwxr-sr-x 2 redis redis 60 Apr 27 12:22 redis

更改为 755 (drwxrwxr-x) 并出现 pid 文件。

于 2020-04-27T04:28:15.783 回答