【问题标题】:Redis Daemon not creating a PID fileRedis 守护进程未创建 PID 文件
【发布时间】:2014-10-20 07:55:54
【问题描述】:

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)

【问题讨论】:

  • redis启动是否正确?哪个用户用来启动redis?它是否有足够的权限来写入 PID 文件?你在redis日志中有什么吗?您正在使用 rhel 提供的 shell 脚本。您是否尝试在没有此脚本的情况下启动 redis 以查看它是否可以在没有脚本的情况下工作?
  • @zenbeni,是的,Redis 启动并正常运行,并且在 UID:redis 下运行。不过,似乎没有在那里创建文件的权限。我会尝试设置它

标签: redis rhel6


【解决方案1】:

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

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

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

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

bind 127.0.0.1 ::1

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

bind 127.0.0.1

编辑:正如 cmets 中所指出的(感谢 @nicholas-vasilaki 和 @tommyalvarez),默认情况下,redis 只允许来自 localhost 的连接。注释所有行,使用:

# bind 127.0.0.1 ::1

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

更多详情请见redis configuration file

【讨论】:

  • 这一定与我的问题无关,因为该步骤对我没有帮助。 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 绑定没有帮助。
  • 我也遇到过这个问题。 redis 日志中的错误是Creating Server TCP Listening socket ::1:6379: unable to bind socket, errno 97
  • @jgrocha # bind 127.0.0.1 ::1 向所有“Hello world”打开redis服务器,不是吗?
  • @NicholasVasilaki # bind 127.0.0.1 ::1 禁用监听端口 ::1。它关闭了对 IPv6 客户端的 redis。
  • @jgrocha 如果只删除 ::1 - 是的。但是如果像示例中那样评论整行,那么我们将有下一个:monosnap.com/file/kzDbSaZDAyO4YcegsQR6sEhObBv6BD
【解决方案2】:

对于那些体验过 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 文件。

【讨论】:

  • 非常感谢,这也解决了 Ubuntu 18.04 的问题
  • Ubuntu 20.04.2 的正确修复
  • 这肯定是合法的
  • 对于那些使用 Debian 和 Ubuntu 的人来说,如果您通过 systemd 管理 redis,正确的做法是忽略警告。 redis 在作为守护进程启动时尝试创建一个 PID 文件,配置为 /var/run/redis/redis.pid ,并且不能配置为不创建一个。但是如上所示,systemd 已经使用 PIDFile=/run/redis/redis-server.pid 为您管理了一个 PID 文件。这种方式比创建临时 PID 文件要好。
  • 谢谢,这也适用于 ubuntu 20.04 版本。
【解决方案3】:

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

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

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

【讨论】:

  • 我的 pidfile 路径设置为 pidfile="/var/run/redis.pid",所以由于 /var/run/ 的权限,redis 无法创建文件,这个解决方案帮助我弄清楚了我的情况,谢谢
  • 这在 Ubuntu 18.04 上是不够的。权限很好。有时 PID 文件存在,有时不存在。没有逻辑。这使得 Redis 很难监控。
【解决方案4】:

在 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 File

【讨论】:

  • 这正是我们所需要的!
  • 曾在 Fedora 上工作。谢谢!
  • 这适用于 Ubuntu 18.04,但文件 redis.service 位于路径 /etc/systemd/system/
  • @JoshuaFlood /etc/systemd/system/redis.service 这是一个符号链接。在 Ubuntu 18.04 中位于路径:/lib/systemd/system/redis-server.service
【解决方案5】:

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

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

discussion on systemd-devel@lists.freedesktop.org 有人写道:

... systemd 将随时添加 MAINPID 环境变量 知道主PID是什么。它通过读取 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 

【讨论】:

  • 谢谢; systemd 服务文件中的 Type=notify 位在 Debian 10 (buster) 上对我有用
【解决方案6】:

从 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)

【讨论】:

    【解决方案7】:
    sudo nano /etc/redis/redis.conf
    

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

    【讨论】:

      【解决方案8】:

      对于 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
      

      【讨论】:

        【解决方案9】:

        对于难以让它在 Ubuntu 18.04 上运行的人,您需要编辑 /etc/redis/redis.conf 并将 pidfile 声明更新为以下内容:

        pidfile "/var/run/redis/redis-server.pid"
        

        【讨论】:

          【解决方案10】:

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

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

          【讨论】:

          • 这个更改(至少单独)并没有解决我在 Ubuntu 18.04 上的问题(另外,755 != drwxrwxr-x = 775)
          猜你喜欢
          • 2013-06-17
          • 2016-10-01
          • 2022-09-27
          • 2014-08-30
          • 2018-07-27
          • 2016-05-08
          • 2018-03-10
          • 2014-10-10
          • 1970-01-01
          相关资源
          最近更新 更多