Prometheus 有几种配置文件,每种可能有多个具体的文件。
这些配置文件可能包括:
- 配置文件如 prometheus.yml
- 告警规则文件如 rule.yml
- 服务发现用的监控目标文件如 targets.json
- node-exporter 的 textfile
这些文件有些可能会手工修改,然后手工触发 reload,有些可能会由 sidecar 程序监控变更并reload,如 thanos-sidecar,有些可能由自定义的程序进行修改如自己写的 go 程序定期更新目标文件。
以监控目标文件为例,Prometheus 会有三种场景读取这个文件:
- 首次启动加载
- 监视到文件变更时触发加载
- 定期加载
前两种场景问题不大,第三种情况有可能出现问题。Prometheus 有可能在你更新文件的过程中读取该文件,这可能造成读到空文件、读到部分文件或者发生读取错误。比如我的 targets.json 文件 7M+,写入的时间要若干毫秒。
我想过加锁写,但这可能会引发不必要的麻烦,比如读阻塞,官方给出的正确更新姿势是先写一个临时文件,然后更名这个文件为要修改的文件。注意要在同一个文件系统上,最好是同一个目录下,否则可能就不是原子的更名操作了。同时要注意只有符合标准 POSIX 规范的文件系统可以保证这个操作是原子的,这也是 NFS 不被 Prometheus 官方支持的主要原因之一。