我不喜欢最常见的备份策略——每天仅备份一次。这似乎意味着,一旦遭遇灾难,可能会丢失许多人精心撰写的内容。然而,我并不想搭建一个高可用(HA)集群;这对我的使用场景来说资源开销太大。我只希望拥有高度的信心,能够恢复在 Discourse 上撰写的几乎所有内容,即使恢复过程需要一些时间。这个 Discourse 是为一个非付费社区提供的免费资源,因此我既重视社区对其投入的价值,也对额外成本保持敏感。停机时间比数据丢失更容易被接受。
在我协助管理的一个 Discourse 实例中,我设置了本地托管的图片(将图片迁移到 S3 是不可逆的,这是我踩过坑后学到的教训),并利用 minio-client 的 --watch 功能,将上传近乎实时地流式传输到 S3。这是在宿主机上完成的。(不过,这在 Digital Ocean Spaces 上无法工作;我同样踩过坑,发现 Ceph 的限制会导致此操作失败。)这使得恢复变得非常简单:只需使用 minio-client 复制所有文件回来。一条命令即可恢复所有数据,甚至能恢复到最近的那一刻,尽管数据库备份可能已经接近一天前……我真的很喜欢这种范式。
在我看来,对于 WAL 流式归档,也可以实现类似的效果,而无需使用 --watch,而是通过 archive_command 在每次 WAL 文件完成时调用 minio-client 仅处理该文件。不过,在这种情况下,minio 必须与 PostgreSQL 一起运行在容器内,而不是在宿主机上。
这引发了我的思考……
虽然我可以利用容器 YAML 文件中的 exec: 指令自行添加 minio-client 并完成这一切,但大家觉得如果 discourse/discourse_docker 仓库提供一个 image/base/install-minio-client 以及一个标准模板,用于放置 .mc/config.json、添加 runit 配置文件,并基于容器配置实现相对便捷的流式备份与恢复,大家会怎么看?这显然是一种高级配置,文档中会带有
警告,且默认不会启用。但既然我迟早可能会做这项工作,如果能在 discourse/discourse_docker 中实现,会比仅仅修改我自己的 data.yml 文件更具可访问性。其代价是在基础镜像中引入 minio-client,大小约为 21MB,大约是 redis-server 二进制文件的两倍。
我并非承诺一定会做,只是好奇如果我真的完成了这项工作,这样的提议是否会被接受。![]()
编辑:另一种方案是设置一个单独的目录来存放文件,然后在容器外部使用 minio-client 等工具将数据流式传输到远程位置,或者在该目录上挂载远程文件系统(如 s3fs)。这可能是一种更简单、更灵活的配置方式,能达到同样的效果,同时无需在每个 Discourse 镜像中都携带 minio-client 的额外负担。