⚠️ 此页面为自动翻译,翻译可能不完美。
blog-post

systemd 下的 Manticore Search:超越 fork、PID 文件和猜测

如果你在 Linux 上运行 Manticore Search,systemd 应该是管理它的默认方式。

这句话现在听起来显而易见,但很长一段时间里只算部分正确。Manticore 确实可以在 systemd 下运行,只是两者的配合一直有点别扭。这个守护进程模型来自更早的 Unix 世界;systemd 出现得更晚,并且对服务有不同的要求。所以这套配置能用,但从来谈不上多让人满意。

变化其实很简单:Manticore 现在支持原生的 systemd 通知。

为什么要在意?因为几个小烦人的运维问题会一下子改善:

  • systemctl status 会讲出更真实的情况
  • 启动和重载更容易追踪
  • 日志能自然地进入 journalctl
  • 当实时表正在刷盘时,关闭会更安全
  • PID 文件不再承担那么多重任

最后这一点比很多人想的影响更小,直到它真正变得很重要的那天。

先从关闭说起,因为事情通常就是在这里开始变得认真

这次变化最好的部分,并不是最显眼的部分,而是关闭行为。

如果 Manticore 正在把数据从实时表刷到磁盘,关闭可能会花一段时间。旧方案通常会退回到 searchd --stopwait,再加上一点运气。有时候这就够了。有时候真的不够。

失败模式既平淡又糟糕:systemd 认为服务卡住了,等待足够长时间后发送 SIGKILL。如果 Manticore 正在刷盘中,这大概是强行杀掉进程的最糟时机。

新行为则是协作式的。只要 Manticore 还在刷盘,它就会告诉 systemd 进度仍在继续,而且还需要更多时间。具体来说,它会每 15 秒发送一次超时延长通知,每次再申请 30 秒。

如果要给文中几乎所有收益排个优先级,我会把这个放在最前面。更好的状态输出当然不错。更干净的重载也不错。但在 RT 刷盘过程中把关闭路径搞坏,要糟得多。

现在,慢停止不再天然可疑了。有时候它只是说明服务器正在完成真正重要的那部分工作。

先看看旧方案长什么样

从历史上看,Manticore 使用的是标准的 Unix 守护进程模式:从终端分离,双重 fork 到后台,写入 PID 文件,然后继续运行。这并不是什么奇怪的设计选择。只要你在乎可移植性,很快就会走到这一步。

摩擦来自把这个模型和 systemd 混在一起。

虽然支持存在,但很有限。unit 必须相信这个守护进程 fork 得正确,而且 PID 文件确实存在并且还指向正确的进程。当一切都正常时,没问题。只要稍微偏一点,监督就会变得模糊。

典型的薄弱点很容易预测:

  • 进程跟踪依赖外部文件
  • 状态报告是间接的
  • 启动进度对 systemd 来说大多不可见
  • 重载和关闭更难被干净地监控

把这些冷静写出来并不显得多戏剧化。但在实际操作中,它会带来运维人员最讨厌的那类问题:这个服务到底是真的健康,还是只是当前还活着。

有一个具体例子值得记住。如果 Manticore 的内部 watchdog 在崩溃后重启了 searchd,systemd 可能仍然会继续监督原始进程关系,而不是新复活的守护进程。像 Supervising process ... which is not our child 这样的警告就是这么来的。

另一个更小但很常见的失败模式是配置漂移:在 Manticore 里改了 pid_file 路径,却忘了同步更新 unit,结果 systemd 追踪到了错误的位置。守护进程可能已经起来了,但 systemctl status 却讲着一个没那么有帮助的故事。

systemd_searchd_pid

这张截图很好地说明了旧方案。systemd 能看到进程树,但不一定能准确看到你真正关心的服务生命周期。

基于 notify 的 unit

新方案使用 Type=notify,这样 Manticore 就能直接报告自己的状态,而不是强迫 systemd 只靠 PID 文件和猜测来推断太多东西。

现在的 systemd unit 大致如下:

[Unit]
Description=Manticore Search Engine
...

[Service]
Type=notify
...

ExecStart=/usr/bin/searchd --config /etc/manticoresearch/manticore.conf --nodetach $_ADDITIONAL_SEARCHD_PARAMS
...

Restart=on-failure
...

这里有几个细节很重要。

Type=notify 表示 systemd 期望直接收到 Manticore 发来的状态更新。

--nodetachsearchd 保持在前台。在 systemd 下,这才是正确的默认方式。其他做法都属于额外的仪式感。这个标志本身并不新;变化在于,它现在已经成为打包好的 systemd 配置的一部分,而不只是用于调试的选项。

PIDFile 不再是主要的监督机制,但如果你还有依赖它的旧工具,它依然可能有用,也仍然可以手动添加。

有了这套配置,Manticore 可以报告如下状态:

  • 启动中
  • 正在加载表
  • 正在重载
  • 就绪

这听起来并不华丽。不过,和旧的“有个进程,大概没问题”模型相比,这已经是实质性的改进了。

我喜欢的一个小变化:重载不再那么别扭

重载 Manticore 传统上意味着向 searchd 发送 SIGHUP。在 systemd 下也还是这样。打包后的 unit 使用:

ExecReload=/bin/kill -HUP $MAINPID

因此 systemctl reload manticore 并不会重启守护进程。它会向正在运行的 searchd 发送 SIGHUP,从而启动表轮换:Manticore 会重新打开 普通表 ,并切换到新构建的表文件,而不是完整重启守护进程。

这个区别很重要。reload 是在不先停服务的前提下触发表轮换的低风险方式。根据 seamless_rotate 设置,在轮换窗口期间,新查询可能会短暂停顿,客户端也可能看到临时错误。restart 则完全是另一回事:它会先停止服务,然后重新启动。

现在好的地方在于可见性更强了。当轮换开始时,Manticore 会向 systemd 报告 RELOADING=1;当轮换完成时,再次报告 READY=1。因此 systemctl status manticore 可以显示守护进程正在主动轮换,而不是只停留在一个笼统的运行状态。

--nodetach 也修正了日志故事

这个选项并不新。变化的是它所处的环境。

当 Manticore 不是钻到后台里消失,而是保持与 systemd 连接时,日志就会进入 journal,而且主进程也是 systemd 真正认识的那个进程。中间层更少了。这个好处通常是在之后才显现,而不是立刻见效。以前在 --nodetach 之前,启动信息可能会先出现在 journalctl,然后在 detach 之后,后续内容又转到 Manticore 自己的日志文件里。

所以对很多部署来说,常用工具就已经够了:

journalctl -u manticore
journalctl -u manticore -f
journalctl -u manticore --since "1 hour ago"

我喜欢平淡无奇的日志方案。只看一个最先要找的地方,这件事其实很值。

如果你乐意把 systemd journal 当作主日志目标,那么你可能不再需要 manticore.conf 里那套旧日志配置。通常这意味着少操心一件事。

关于内部 watchdog

如果 Manticore 运行在 systemd 下,我会推荐最简单的方案:让 systemd 监督这个服务,除非你确实需要,否则不要启用 Manticore 的内部 watchdog。

能同时开两者吗?可以。
正常部署里我会选这个吗?不会。

如果你明确启用了内部 watchdog,监督模型就会变得不那么直接,而且你可能会看到这样的警告:

Supervising process ... which is not our child

这个配置是受支持的。但对大多数人来说,它只是多了些移动部件。

几条补充说明

在基于通知的监督下,PID 文件对 systemd 自身的重要性会小得多。你也许可以从配置中移除 pid_file,但前提是你环境里没有别的东西还依赖它。旧脚本往往比任何人预期的都活得更久。

如果你使用可执行配置文件,包括像 #!/usr/bin/env python 这样的基于 shebang 的配置,这套方案通常会比一些旧的服务管理方式更自然。

你真正会用到的命令

sudo systemctl start manticore
sudo systemctl stop manticore
sudo systemctl restart manticore
sudo systemctl reload manticore
sudo systemctl status manticore
sudo systemctl enable manticore

再看日志:

sudo journalctl -u manticore
sudo journalctl -u manticore -f
sudo journalctl -u manticore --since "1 hour ago"

基本就是这样。

实际结果并不炫目:Manticore 更像一个现代 Linux 服务,而不再像一个来自更早年代、大家都学着绕着走的守护进程。但这类基础设施改动往往最有价值。它们消除了那些你几乎已经不再注意到的摩擦。

安装Manticore Search

安装Manticore Search