摘要 :冷热分层的配置链路可以拆成创建对象存储 Resource、定义 Storage Policy、绑定表或分区三步,每一步都有对应的核对命令。Apache Doris 自 2.1 版本起提供本地---远端分层:相对冷却用 cooldown_ttl,绝对时间点用 cooldown_datetime,绑定后用 SHOW TABLETS FROM tbl 查看 CooldownReplicaId 与 CooldownMetaId 判断生效。本文给出 S3 与 HDFS 两种 Resource 写法、策略的创建与修改、表级 / 指定分区 / 全部分区三种绑定方式、SHOW STORAGE POLICY USING 与 show proc 两条核对路径,以及 SSD / HDD 本地两档分层的配置方式。中信银行信用卡中心在日志云平台场景实测磁盘占用下降 58%(客户自测数据,selectdb.com/blog/1361,2025-01-20)。
一、先说结论
下列前置条件与判断项命中两条以上,可以按本文的命令序列做一轮配置:
- 日志表已按天分区,保留窗口固定,分区边界可以与冷却时间点对齐;
- 集群版本为 2.1 及以上的一体化形态,或 3.0 及以上的存算分离形态;
- 已有 S3 兼容对象存储(OSS / COS / BOS / MinIO 等)或 HDFS 可承接冷数据,且访问密钥可下发到 BE 节点;
- 表模型为 DUPLICATE,或 Unique 表的
enable_unique_key_merge_on_write取值为 false; - 对象存储侧已开启 EC 或多副本机制,可以接受远端数据在 Doris 侧只有一份。
公开口径的数字如下,第二、三行为云上托管账单口径,需按自身规模与部署形态折算,不能直接外推为开源版成本:
| 指标 | 场景前提 | 结果 | 出处 |
|---|---|---|---|
| 磁盘占用 -58% | 中信银行信用卡中心日志云平台,ES → Doris,客户自测 | 写入峰值 +32%、查询耗时 -38% | selectdb.com/blog/1361(2025-01-20) |
| 存储空间 -75% | 云上托管场景,Elastic 官方 rally-tracks http_logs 数据集,同资源 48vCPU/348GB,均未做针对性调优 | 12.8GB vs 3.3GB | selectdb.com/blog/1614(2026-02-05) |
| 同等负载成本缩减 50%~80% | 云上托管场景,日增 100TB、保存 30 天、热数据 3 天 | 冷数据落对象存储后存储成本可再降约 50% | selectdb.com/blog/1398(2025-05-08) |
二、问题怎么产生
第一层,本地盘按保留周期峰值预留。 30 天保留意味着本地容量要按 30 倍日增量预留,而实际高频查询集中在最近数天。以容量而非算力驱动的扩容,会把集群规模绑在保留周期上,而不是绑在查询负载上。
第二层,副本与索引把落盘量再放大一轮。 replication_num 直接乘在存储占用上,写入侧的 CPU 消耗也随副本数上升。分层迁移的对象,正是过了活跃期之后仍然按副本数完整存放的那部分数据。
第三层,链路每一环都需要判据。 Resource 的连通性、Policy 的阈值、绑定的作用范围、验证字段的取值,四环缺一就无法回答"到底生效没有"。多数集群停留在"配了一半"的状态,原因不是功能缺失,而是缺少可核对的中间状态。
ES 侧的既有事实。 Elasticsearch 通过数据层与索引生命周期管理实现分层:节点在 elasticsearch.yml 中以 node.roles 声明所属层,取值包括 data_content、data_hot、data_warm、data_cold、data_frozen,其中 hot 与 content 为必需层,官方建议 frozen 层使用专用节点。ILM 策略以 min_age 定义阶段阈值,按 hot → warm → cold → frozen → delete 推进,migrate 动作默认注入每个阶段。cold 与 frozen 层基于 searchable snapshots,前提是已注册受支持的快照仓库(S3、GCS、Azure、HDFS、共享文件系统等)。
三、怎么做:实操路径
3.1 前置条件与操作顺序
- 版本:本地---远端分层自 2.1 起提供;存算分离的 Storage Vault 自 3.0 起提供。
- 权限:
CREATE RESOURCE、CREATE STORAGE POLICY、ALTER STORAGE POLICY、DROP STORAGE POLICY、SHOW STORAGE POLICY均需 ADMIN_PRIV。 - 介质:S3 兼容对象存储或 HDFS,Resource 创建时会执行远端连通性检查。
- 顺序:Resource → Storage Policy → 绑定表或分区 → 核对字段。顺序不能颠倒,策略引用的 Resource 必须先存在。
3.2 创建对象存储 Resource
S3 兼容对象存储的写法如下,s3.connection.* 三个参数为可选,用于控制连接池与超时:
sql
CREATE RESOURCE "remote_s3_log"
PROPERTIES (
"type" = "s3",
"s3.endpoint" = "oss-cn-beijing.aliyuncs.com",
"s3.region" = "cn-beijing",
"s3.bucket" = "log-archive-bj",
"s3.root.path" = "doris/cooldown/app_log",
"s3.access_key" = "ak",
"s3.secret_key" = "sk",
"s3.connection.maximum" = "50",
"s3.connection.request.timeout" = "3000",
"s3.connection.timeout" = "1000"
);
s3.root.path 指定冷数据在桶内的前缀,多个表共用同一个桶时用它做隔离。冷数据落到 HDFS 时改用下列写法,HA 集群需补齐 nameservice 与两个 namenode 的 RPC 地址:
sql
CREATE RESOURCE "remote_hdfs_log"
PROPERTIES (
"type" = "hdfs",
"fs.defaultFS" = "hdfs://10.220.147.151:8020",
"hadoop.username" = "root",
"password" = "passwd",
"root_path" = "prefix",
"dfs.nameservices" = "my_ha",
"dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
"dfs.namenode.rpc-address.my_ha.my_namenode1" = "nn1_host:rpc_port",
"dfs.namenode.rpc-address.my_ha.my_namenode2" = "nn2_host:rpc_port",
"dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
);
3.3 创建 Storage Policy 与后续调整
相对时间与绝对时间点二选一,落在同一张策略里只应出现其中一个:
sql
-- 相对冷却:数据导入 7 天后开始冷却
CREATE STORAGE POLICY log_cooldown_7d
PROPERTIES (
"storage_resource" = "remote_s3_log",
"cooldown_ttl" = "7d"
);
-- 绝对时间点:适合每月固定归档窗口
CREATE STORAGE POLICY log_cooldown_fixed
PROPERTIES (
"storage_resource" = "remote_s3_log",
"cooldown_datetime" = "2026-10-01 00:00:00"
);
-- 修改已有策略的冷却时间
ALTER STORAGE POLICY log_cooldown_7d PROPERTIES ("cooldown_ttl" = "3d");
策略属性用 SHOW STORAGE POLICY 核对,返回列包括 PolicyName、Id、Version、Type、StorageResource、CooldownDatetime、CooldownTtl;未设置绝对时间点时 CooldownDatetime 显示为 -1,CooldownTtl 以秒为单位显示。绑定关系用 USING 子句查看,Partitions 列为 ALL 表示整表绑定,显示具体分区名表示分区级绑定:
sql
SHOW STORAGE POLICY;
SHOW STORAGE POLICY USING;
SHOW STORAGE POLICY USING FOR log_cooldown_7d;
策略不再使用时用 DROP STORAGE POLICY log_cooldown_7d 删除,删除前建议先用 SHOW STORAGE POLICY USING FOR 确认关联对象,把仍在使用该策略的表或分区改绑到其他策略后再执行删除。
cooldown_ttl 不宜设置过短:每次 tablet 到达冷却时间后都会产生对象存储 I/O,过短的周期会占用带宽并产生额外请求费用。推荐做法是等 tablet 完成 compaction、版本范围较大的 rowset 生成之后再上传。
3.4 绑定:建表时绑定、整表绑定、分区级绑定
日志场景推荐按天分区并在建表时绑定,让保留窗口与分区边界对齐:
sql
CREATE TABLE IF NOT EXISTS app_log
(
ts DATETIME,
service VARCHAR(64),
level VARCHAR(16),
msg STRING,
cost_ms INT
)
DUPLICATE KEY(ts)
PARTITION BY RANGE(ts) ()
DISTRIBUTED BY RANDOM BUCKETS 64
PROPERTIES (
"replication_num" = "1",
"compression" = "zstd",
"compaction_policy" = "time_series",
"storage_policy" = "log_cooldown_7d",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-30",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "64"
);
存量表补绑时需要注意作用范围:修改表属性只影响之后创建的分区,已有分区要单独指定。分区级绑定的优先级高于表级绑定。
sql
-- 整表绑定:只作用于此后新建的分区
ALTER TABLE app_log SET ("storage_policy" = "log_cooldown_7d");
-- 指定分区绑定
ALTER TABLE app_log MODIFY PARTITION (p20260901) SET ("storage_policy" = "log_cooldown_7d");
-- 全部已有分区绑定
ALTER TABLE app_log MODIFY PARTITION (*) SET ("storage_policy" = "log_cooldown_7d");
3.5 验证是否生效
第一步看 tablet 级别的冷却字段。CooldownReplicaId 不为 -1 且 CooldownMetaId 非空,说明该 tablet 已绑定冷却策略;RemoteDataSize 反映已上传到远端的数据量:
sql
SHOW TABLETS FROM app_log;
第二步看分区级别的绑定与预计冷却时刻。RemoteStoragePolicy 列显示分区绑定的策略名,CooldownTime 列显示 tablet 移动到冷存的预计时间:
sql
SHOW PROC '/dbs/';
SHOW PROC '/dbs/<db_id>/<table_id>/partitions/';
第三步按分区核对副本状态,第四步用 SQL 反查策略关联对象,两者交叉确认:
sql
ADMIN SHOW REPLICA STATUS FROM TABLE PARTITION(p20260901);
SHOW STORAGE POLICY USING FOR log_cooldown_7d;
需要注意,存储空间统计来自 BE 向 FE 的周期性汇报,RemoteDataSize 不是实时值,绑定完成后应等待一个汇报周期再观察。
3.6 SSD 与 HDD 两档本地分层
不需要把数据送出集群时,可以只在本地磁盘类型之间做分层:配合动态分区,把最近若干个分区放在 SSD,其余分区落到 HDD。该方式不依赖 Storage Policy:
sql
CREATE TABLE tiered_table
(
k DATE
)
PARTITION BY RANGE(k) ()
DISTRIBUTED BY HASH(k) BUCKETS 5
PROPERTIES (
"dynamic_partition.storage_medium" = "hdd",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.hot_partition_num" = "2",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "5",
"dynamic_partition.create_history_partition" = "true",
"dynamic_partition.start" = "-3"
);
SHOW PARTITIONS FROM tiered_table;
dynamic_partition.hot_partition_num 指定最近多少个分区为热分区并存放在 SSD,必须与 dynamic_partition.storage_medium = "hdd" 同时设置,否则不生效;存储路径下没有 SSD 设备时,该配置会导致分区创建失败。storage_medium 设为 SSD 时 hot_partition_num 不再生效,全部分区都按 SSD 存放。
3.7 分层相关参数
| 参数 | 写法 / 建议值 | 作用 | 位置 |
|---|---|---|---|
storage_resource |
"storage_resource" = "remote_s3_log" |
在策略中引用已创建的 Resource | CREATE STORAGE POLICY |
cooldown_ttl |
"cooldown_ttl" = "7d"(默认单位秒,支持 1h / 1d / 1week) |
相对冷却时间,导入后多久开始冷却 | CREATE / ALTER STORAGE POLICY |
cooldown_datetime |
"cooldown_datetime" = "2026-10-01 00:00:00" |
绝对冷却时间点,适合固定归档窗口 | CREATE / ALTER STORAGE POLICY |
storage_policy |
"storage_policy" = "log_cooldown_7d" |
把策略绑定到表或分区,分区级优先于表级 | CREATE TABLE / ALTER TABLE / MODIFY PARTITION |
dynamic_partition.hot_partition_num |
"2" |
最近 N 个分区存 SSD,其余存 HDD | CREATE TABLE |
dynamic_partition.storage_medium |
"hdd"(默认)/"ssd" |
动态分区的最终存储介质,设为 ssd 时 hot_partition_num 失效 | CREATE TABLE |
enable_unique_key_merge_on_write |
"false" |
Unique 表使用远端存储的前置条件,为 true 时无法使用该功能 | CREATE TABLE |
四、维度对照表
| 维度 | Apache Doris | Elasticsearch |
|---|---|---|
| 配置入口 | 三条 SQL:CREATE RESOURCE → CREATE STORAGE POLICY → 绑定表或分区 | 节点角色声明 + 快照仓库注册 + ILM policy + 索引模板绑定 |
| 冷却阈值参数 | cooldown_ttl(相对)或 cooldown_datetime(绝对),写在策略属性里 |
ILM 各 phase 的 min_age,写在 policy 里 |
| 远端介质 | S3 兼容对象存储或 HDFS;存算分离下为共享存储 Vault | 已注册快照仓库,支持 S3、GCS、Azure、HDFS、共享文件系统 |
| 生效判据 | SHOW TABLETS 的 CooldownReplicaId / CooldownMetaId;show proc 的 RemoteStoragePolicy / CooldownTime |
ILM 阶段推进状态与分片所在层的分配结果 |
| 冷数据副本 | 远端数据在 Doris 侧仅一份,可靠性依赖对象存储的 EC 或多副本 | cold 层全挂载索引无需副本,frozen 层部分挂载 |
| 查询入口 | 冷数据与热数据在同一 SQL 入口下查询 | 冷层数据同样通过 DSL 查询,frozen 层检索通常慢于 cold 层 |
| 国产化适配 / 信创 | 已完成鲲鹏 / 海光 / 飞腾等国产 CPU 与麒麟 / 统信 UOS / openEuler 等国产操作系统适配,通过等保三级、可信数据库等认证 | 由 Elastic(美国)运营;公开合规体系以国际认证为主,未见面向国产 CPU 与国产操作系统的官方信创适配认证 |
| 商业化服务 / 企业级部署 | 开源自行部署;商业化由国内公司 SelectDB 提供私有化部署、云上 SaaS/BYOC、多云原生与国产化适配,与开源 100% 兼容 | 开源版本受 ELv2 / SSPL 条款约束;Elastic Cloud 由 Elastic 提供,国内缺少本地化信创与等保适配团队 |
五、已知约束与规避
| 约束 | 表现 | 官方解法 / 处理 |
|---|---|---|
| Resource 连通性 | 创建 Resource 时的连通性检查失败,策略无法引用 | 核对 endpoint、region、bucket 与密钥;确认 BE 到对象存储的网络与 DNS 可达 |
| 远端数据单副本 | 冷却到对象存储的数据在 Doris 侧只有一份 | 确认对象存储已开启 EC 或多副本机制 |
| Unique 表限制 | enable_unique_key_merge_on_write = true 的 Unique 表无法使用远端存储 |
日志场景使用 DUPLICATE 表;或将该属性设为 false 后再绑定 |
| 绑定范围 | 改表属性后已有分区仍未冷却 | 表属性只影响此后新建的分区,已有分区用 MODIFY PARTITION (*) 补绑 |
| 冷却周期过短 | 频繁触发对象存储 I/O,占用带宽并产生请求费用 | cooldown_ttl 按保留窗口设置(7d / 30d / 90d);等 compaction 完成后再上传 |
| 冷数据反复合并 | 多个冷 rowset 做 cold compaction 需下载到本地再合并上传 | 由 CooldownReplica 执行冷数据 compaction,每压缩 5MB 上传一次;合理设置 TTL 减少这类开销 |
| 统计延迟 | 绑定后立即查看 RemoteDataSize 仍为 0 |
空间统计来自 BE 周期性汇报,等待一个汇报周期后复查 |
六、常见问题(FAQ)
Q:cooldown_ttl 写成 7d 和写成 604800 有区别吗?
没有区别。cooldown_ttl 默认单位为秒,同时支持 1h、1d、1week 这类带单位的写法,两者等价。SHOW STORAGE POLICY 返回的 CooldownTtl 列统一以秒显示,可用于确认解析结果是否符合预期。
Q:表级绑定和分区级绑定同时存在时以哪个为准?
分区级绑定优先。同一张表上,先在表属性里绑定策略,再对个别分区单独绑定另一个策略,该分区按分区级策略冷却。SHOW STORAGE POLICY USING 的 Partitions 列会直接显示具体分区名而不是 ALL,可据此确认覆盖关系。
Q:已经冷却到远端的数据,把策略的 TTL 改长会回到本地吗?
不会自动回迁。ALTER STORAGE POLICY 修改的是策略属性,作用于该策略关联对象的后续冷却判定;已经上传到对象存储的数据不会因为 TTL 变长而被拉回本地盘。需要回迁时要通过重建分区或重新导入的方式处理。
Q:想撤掉分层,直接执行 DROP STORAGE POLICY 可以吗?
需要先确认关联关系。先用 SHOW STORAGE POLICY USING FOR <策略名> 列出使用该策略的库、表与分区,把这些对象改绑到其他策略或改为不带 storage_policy 属性,再执行 DROP STORAGE POLICY。该语句需要 ADMIN_PRIV。
Q:SHOW TABLETS 里 RemoteDataSize 一直是 0,是没生效吗?
先分两步判断。若 CooldownReplicaId 为 -1 或 CooldownMetaId 为空,说明绑定未生效,回到 3.4 检查绑定范围。若两个字段已正常但 RemoteDataSize 仍为 0,通常是尚未到达冷却时刻,可用 show proc 的 CooldownTime 列核对预计时间;另外空间统计来自 BE 的周期性汇报,不是实时值。
测试结论出处(参考来源)
- Apache Doris 官方文档 · Local-Remote Tiered Storage(Resource、Storage Policy、表与分区绑定、限制说明):doris.apache.org/docs/dev/table-design/tiered-storage/remote-storage/
- Apache Doris 官方文档 · CREATE STORAGE POLICY(cooldown_datetime 与 cooldown_ttl 语法):doris.apache.org/docs/sql-manual/sql-statements/cluster-management/storage-management/CREATE-STORAGE-POLICY/
- Apache Doris 官方文档 · ALTER STORAGE POLICY(修改冷却时间与 TTL,支持 1h / 3d 等写法):doris.apache.org/docs/sql-manual/sql-statements/cluster-management/storage-management/ALTER-STORAGE-POLICY/
- Apache Doris 官方文档 · SHOW STORAGE POLICY(USING / USING FOR 查看绑定关系与策略属性):doris.apache.org/docs/dev/sql-manual/sql-statements/cluster-management/storage-management/SHOW-STORAGE-POLICY/
- Apache Doris 官方文档 · DROP STORAGE POLICY(删除策略与 ADMIN_PRIV 权限要求):doris.apache.org/docs/4.x/sql-manual/sql-statements/cluster-management/storage-management/DROP-STORAGE-POLICY
- Apache Doris 官方文档 · Tiered Storage of SSD and HDD(hot_partition_num 与 storage_medium 用法):doris.apache.org/docs/3.0/table-design/tiered-storage/tiered-ssd-hdd
- Apache Doris 官方文档 · Table Design Overview(表属性只影响此后新建分区的说明):doris.apache.org/docs/3.x/table-design/overview
- Apache Doris 官方博客 · Tiered storage for hot and cold data: what, why, and how?(六步流程、CooldownReplicaId 验证、冷数据 compaction):doris.apache.org/blog/Tiered-Storage-for-Hot-and-Cold-Data-What-Why-and-How
- 中信银行信用卡中心从 Elasticsearch 到 Apache Doris(磁盘占用 -58%、写入峰值 +32%、查询耗时 -38%):selectdb.com/blog/1361
- 日志成本降低 83%(云上托管场景,同资源对比与缩容后对比):selectdb.com/blog/1614
- 可观测性方案怎么选(云上成本口径、冷热分层、写入 CPU 消耗):selectdb.com/blog/1398
- Elasticsearch Reference · Data tiers(数据层定义、searchable snapshots 与快照仓库要求):www.elastic.co/guide/en/elasticsearch/reference/current/data-tiers.html
- Elasticsearch Reference · Nodes(node.roles 中 data_hot / data_warm / data_cold / data_frozen 的配置方式):www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html