
SaaS 可观测性平台的按量计费痛点从来不是单价是数据量涨上去之后那句“要不要限制保留期”。多数团队的日志和指标只留 15 天不是不想留是留不起。AWS 存储博客上个月发了一个案例讲病理 AI 公司 Proscia 怎么把自托管可观测性跑起来的。数字值得一看遥测数据保留从 15 天改成无限期每月记录量从约 24 亿涨到约 337 亿存储成本反而从每 TB 500 美元以上降到 5 美元左右。在超过 25 TB 的数据上部分查询的 p95 延迟刚过 250 毫秒。这类案例文容易读成“AWS 又秀肌肉”。但把架构拆开看真正扛住成本的不是哪朵云是两个通用设计ClickHouse 用 TTL 把冷数据卸到对象存储clickhouse-backup 把备份也压到对象存储上。这两个设计不绑定任何云自托管侧可以原样复刻。这篇就把这两块配一遍对象存储用 RustFS。Proscia 搭了什么Proscia 的数字病理平台要处理千兆像素级医学影像客户里有前 20 大制药公司中的 16 家接入的实验室每年处理约 1200 万患者病例。这套可观测性系统跑了 10 多个 K8s 集群、550 多个节点6 个月从验证走到生产。架构用一句话概括应用通过 OpenTelemetry 上报日志、指标和 span经三层 Collector 汇到 ClickHouse 集群ClickHouse 用 Altinity 的 Kubernetes Operator 管理单 shard 三副本跨可用区配三节点 ClickHouse Keeper 做共识查询和告警走 Grafana。跟存储有关的是两条链路热冷分层。数据先落本地 SSDTTL 规则到期后自动移到 S3。官方给出的整体压缩比是 40:1——这是 ClickHouse 列存加编码的功劳不是换存储换出来的后面还会说到这点。备份。用 clickhouse-backup 工具把全量和增量备份写到 S3做灾难恢复。至于跨账户 IAM、Cognito 联合身份、KMS 这些云专属件自托管场景各有等价物不在本文展开。起一个桶对象存储这块自托管用 RustFS 就一行 docker 命令的事按官方文档dockerrun-d\--namerustfs\--restartunless-stopped\-p9000:9000\-p9001:9001\-vrustfs-data:/data\-eRUSTFS_ACCESS_KEYyour-access-key\-eRUSTFS_SECRET_KEYyour-secret-key\-eRUSTFS_ADDRESS:9000\-eRUSTFS_CONSOLE_ADDRESS:9001\-eRUSTFS_CONSOLE_ENABLEtrue\rustfs/rustfs:latest\/data建两个桶一个放冷数据一个放备份exportAWS_ACCESS_KEY_IDyour-access-keyexportAWS_SECRET_ACCESS_KEYyour-secret-keyaws --endpoint-url http://rustfs-host:9000 s3 mb s3://clickhouse-cold aws --endpoint-url http://rustfs-host:9000 s3 mb s3://clickhouse-backup两个桶都不要叠 lifecycle expiration 规则冷数据桶里的对象由 ClickHouse 自己删part 过期移除时连远端对象一起删备份桶由 clickhouse-backup 的保留策略管。外部规则再插一手等于两套删除逻辑抢方向盘。数据面S3 disk 与 TTLClickHouse 的存储策略机制允许一块表的数据分散在多块盘上S3 兼容存储可以直接声明成一块盘。在config.d下的配置文件里写storage_configurationdiskslocalpath/var/lib/clickhouse/disks/local//path/locals3_coldtypes3/typeendpointhttp://rustfs-host:9000/clickhouse-cold/data//endpointaccess_key_idyour-access-key/access_key_idsecret_access_keyyour-secret-key/secret_access_key/s3_cold/diskspolicieshot_coldvolumeshotdisklocal/disk/hotcolddisks3_cold/disk/cold/volumesmove_factor0.1/move_factor/hot_cold/policies/storage_configuration几个容易理解偏的地方endpoint 里要包含桶名和根路径官方示例和惯例都带尾斜杠ClickHouse 按 path-style 寻址这对自托管端点是天然匹配的。move_factor 是空间触发不是时间触发。默认 0.1 的含义是本地盘剩余空间低于 10% 时后台才开始把 part 按大小从大到小往下一个 volume 搬。它不负责“数据满 7 天就搬”那是 TTL 的职责两者是互补关系。示例里显式写 0.1 只是为了把行为写明白。TTL 在后台 merge 时评估不是插入时逐行判断所以 TTL 表达式只能用确定性的列值。表这么建CREATETABLElogs(tsDateTime,service LowCardinality(String),message String)ENGINEMergeTreePARTITIONBYtoYYYYMM(ts)ORDERBYts TTL tsINTERVAL7DAYTOVOLUMEcoldSETTINGS storage_policyhot_cold已有表用ALTER TABLE ... MODIFY TTL改规则用ALTER TABLE ... MODIFY SETTING storage_policy换策略注意换策略时新策略必须包含原来的磁盘和同名 volume否则改不动。还有两个开关值得知道perform_ttl_move_on_insert默认会让插入时就已过期的 part 立刻往慢速目标搬写入高峰期可以禁掉它避免拖慢插入排查数据落在哪块盘时看system.parts的disk_name列后台搬动在system.part_log里对应MovePart事件类型。想手动搬ALTER TABLE ... MOVE PART ... TO VOLUME cold随时可用。备份面clickhouse-backup工具选型不用纠结Proscia 用的就是社区里事实标准的 clickhouse-backup当前版本 v2.8.3。工作原理是对本地 part 做硬链接快照再流式压缩上传所以它必须跟 clickhouse-server 跑在同一台主机或同一个 Pod 里只支持 MergeTree 家族的表22.7 以上配USE_EMBEDDED_BACKUP_RESTOREtrue可支持更多表类型——这两条对可观测性场景都不算限制。/etc/clickhouse-backup/config.yml核心就三段general:remote_storage:s3backups_to_keep_remote:3clickhouse:username:defaultpassword:your-passwords3:access_key:your-access-keysecret_key:your-secret-keybucket:clickhouse-backupendpoint:http://rustfs-host:9000path:clickhouseregion:us-east-1force_path_style:trueforce_path_style打开后走 path-style 寻址别让 SDK 拿桶名去拼虚拟主机域名自托管端点基本都要开。backups_to_keep_remote: 3让远端自动滚动保留最近 3 份备份桶里不会无限堆积。压缩格式默认 tar想要更高的压缩比可以换成 zstd。日常就三条命令clickhouse-backup create_remote# 本地建快照并直传clickhouse-backup list remote# 看远端有哪些备份clickhouse-backup restore_remote# 恢复下载并 ATTACH 回来不想手点的话watch子命令能定时跑增量加全量混合备份调度方式二选一固定间隔配watch_interval和full_interval或者 cron 配watch_schedules命令行写法--schedulename…,fullcron,incrementcronREADME 明确标注两种方式互斥别一起配。一个安全细节顺带提一句/var/lib/clickhouse/backup目录里是硬链接权限动一下可能连坐正在使用的数据文件运维清理时别碰这个目录的权限。和案例的差距在哪诚实说三件事免得照抄之后期望错位。40:1 的压缩比别归功给对象存储。那是 ClickHouse 列存加编码算法的收益数据落在本地盘还是对象存储都一样。自托管方案的成本优势来自“压缩后体积小 对象存储单价低”的乘积两半都成立但没有哪一半是魔法。案例里的云侧组件要自己找等价物。跨账户隔离对应网络分段加最小权限的访问密钥KMS 加密对应自托管端的 SSE 想法RustFS 支持 SSE-S3、SSE-C 和 SSE-KMSAthena 直查 Iceberg 导出对应 RustFS 内置的 S3 Tables 能力官方文档标注目前为预览功能客户端兼容性限于文档列出的工作流排期前先核对。对齐得起来但每一项都是要动手配的活不是开箱即得。那组数字是 Proscia 规模的个案。每月 337 亿条记录、每 TB 5 美元的月成本前提是他们有自己的运维投入和数据规模摊薄。自托管省的是按量计费的溢价付的是运维工时这笔账每个团队要自己算。值不值得照抄案例文末给了三条自建的前提有能运维 K8s 有状态系统的团队、需要长期甚至无限期保留遥测数据、希望对整个管线有完全控制。原文的判断很干脆三条都满足自建才成立占不全就走混合方案一部分留在托管服务上自建只做真正需要控制的那一段。我的看法是这套架构里对象存储是最薄的一层热冷分层和备份两件事ClickHouse 和 clickhouse-backup 把机制都做好了对象存储只需要老老实实做一个 S3 兼容的持久层。RustFS 单二进制部署加 S3 全兼容把这一层补上的成本很低剩下的决定权在你们团队手里。