数据中台建设方案:冷热数据分层与归档落地实践

发布时间:2026/9/17 20:36:51
数据中台建设方案:冷热数据分层与归档落地实践 简介这份《数据中台建设方案》文档面向智慧城市、政务与行业大数据项目的架构师、数据平台开发及技术方案编制人员用于解决数据中台从零规划时缺乏完整架构参考与落地路径的问题也可作为企业级大数据平台选型、投标方案撰写的参考底稿。压缩包内共1个docx文件大小约20.78MB以图文并茂的方案文档形式呈现便于直接阅读、摘取章节或二次编辑成汇报材料。方案内容围绕星环科技Transwarp Data HubTDH与云操作系统TOS展开覆盖总体建设方案、大数据平台产品优势与性能优化、数据采集/存储/交换/管理/资源管理五层集成平台建设以及大数据计算平台、开发平台可视化工具与集成能力并延伸至大数据运维、安全、高可用、开放性与兼容性等章节目录层级清晰、模块划分完整。目前已有230人学习下载适合作为数据中台顶层设计与落地实施的系统化参考资料。1. 一份数据中台建设方案.docx 交出去之前先确认冷热数据这条线落没落地写过数据中台建设方案的人大概都经历过这个场面架构图六层画得齐齐整整主题域、指标口径、资产目录、质量规则一样不缺评审会上所有人都点头。半年后账单出来对象存储和 HDFS 用量涨了三倍实际被查询的表不到总量的四成剩下六成是三年没人动过的明细分区。问题不在架构在方案里少了一句话——冷热数据怎么分、归档表什么时候建、归档之后下游任务怎么接。这三件事写在文档里是一行字落到工程上是几百 TB 的差额也是数据中台从「建起来」到「养得住」的分水岭。下面按落地顺序把它拆开分层职责怎么划、冷热边界用什么口径、归档表用什么引擎建、迁移和校验的 SQL 怎么写、调度与元数据怎么配套最后给一组能拿去验收的指标。2. 数据中台建设方案的分层设计从贴源层到归档层的职责划分分层这件事在方案文档里通常只有一张图但真正决定成本的是每一层的保留策略和存储引擎。图谁都会画策略写不写得出数字才是方案能不能落地的差别。2.1 数据中台的六层职责与选型理由常见做法是把中台划成六层前四层是加工链路后两层是成本治理和合规兜底。方案里如果只写前四层后面一定会补一份「存储优化专项」不如一次写全。层职责存储引擎常见选择保留策略参考ODS 贴源层原样落地业务库增量/全量保留原始语义Hive / 对象存储 / Hudi热存 3090 天DWD 明细层清洗、去重、脱敏、统一编码Hive / Iceberg12 年DWS 汇总层按主题域轻度聚合指标口径收敛点Hive / ClickHouse23 年ADS 应用层面向报表与接口的宽表ClickHouse / Doris / MySQL随业务生命周期归档层低频访问明细列存压缩可查但慢Hive ORC/Parquet 冷存储310 年备份层合规留存几乎不参与查询对象存储归档型按合规要求有两点选型理由值得在方案里写清楚。一是 ODS 不要直接下沉到冷存储回溯重跑、对账、链路重放都会读它冷存储的取回延迟会把补数窗口直接顶爆。二是归档层要独立建表而不是在 DWD 里靠分区过滤「假装归档」——同一张表分区跨到三年分区元数据膨胀、小文件堆积、NameNode 压力全都跟着来查询规划阶段就会变慢。2.2 冷热数据的分界按访问频次、时间还是成本三种判定口径各有取舍。时间法最省事按业务日期一刀切缺点是会误伤那些虽然老但仍在被频繁引用的分区。访问频次法最准但要先有查询审计日志很多团队是在中台建完一年后才补上。成本法最贴近财务算的是单位 GB 查询成本与单位 GB 存储成本的交叉点。实际落地一般用组合口径判定维度数据来源阈值示例适用场景分区年龄分区元数据超过 180 天日增量大、访问随时间衰减明显的事实表近 N 天查询次数查询审计日志90 天内被查少于 3 次已有审计日志、查询集中的团队下游血缘数量血缘图谱无下游且无 BI 引用僵尸表、僵尸分区治理合规分级数据分级标签强制留存年限只能归档不能删除的数据一个反直觉的点访问频次低不等于可以归档还要看恢复代价。如果一次回溯要等六小时业务方会用脚投票直接在 DWD 上再拉一份宽表中台白建。所以方案里除了写阈值还要写「归档后单分区恢复时间目标」常见做法是不超过 30 分钟超过就说明归档粒度太粗了应该按分区而不是整表迁移。2.3 用 SQL 把冷热标记写进明细表与其每天现算不如把分层结果物化成一个字段下游和治理任务都读它。-- 在 DWD 明细表上增加分层标记字段元数据操作不重写历史数据 ALTER TABLE dwd_order_detail ADD COLUMNS ( storage_tier STRING COMMENT hot/warm/archive由治理任务每日刷新 ); -- 按分区年龄打标阈值必须与 2.2 的口径表对齐 INSERT OVERWRITE TABLE dwd_order_detail PARTITION (dt) SELECT order_id, user_id, pay_amount, dt, CASE WHEN dt date_sub(current_date(), 30) THEN hot -- 30 天内留在原表 WHEN dt date_sub(current_date(), 180) THEN warm -- 30~180 天观察 ELSE archive -- 超过 180 天进入归档候选 END AS storage_tier FROM dwd_order_detail_stage WHERE dt ${bizdate};这段逻辑的关键在两点。ALTER TABLE ... ADD COLUMNS只动 metastore不触发数据重写加的列在旧分区里读出来是 NULL需要治理任务逐分区回填。CASE里的 30 和 180 不是拍脑袋的数字要跟 2.2 表格里的阈值一致改阈值时两边一起改否则会出现「标记为 hot 但早已被归档」的状态错位。实际生产中我一般还会加一个辅助字段last_query_time由审计日志回写让「年龄 查询」两个口径能交叉验证。提示打标任务本身要幂等用INSERT OVERWRITE分区而不是INSERT INTO否则重跑一次就多一批重复行。3. 数据中台建设方案里的归档表落地建表、迁移、校验的三段式命令分层标记只是判定真正省下成本的动作是把数据从热存搬到冷存并且保持可查。这一段是整个数据中台建设方案里最容易写虚、也最容易在半年后返工的部分。3.1 归档表的三种形态与选型归档不等于把数据删掉也不等于原样复制一份。常见三种形态成本和可查性差别很大。形态做法压缩比参考可查性适用同构归档表schema 一致换存储介质和压缩算法24 倍直接查语义不变仍需按明细回溯的数据裁剪归档表只留分析必需列去掉大文本、JSON 明细510 倍部分字段不可查日志类、埋点类宽表快照归档按年/月导出 Parquet 文件挂外表取决于压缩需按路径查合规留存、几乎不查选型的判断标准是「归档后还有没有人按主键查单条」。有就老老实实做同构归档表没有裁剪归档的收益最大。日志埋点类数据是裁剪归档的典型对象因为 80% 的存储被少数几个大字段占着而这些字段在分析里很少被 select。3.2 Hive 归档表的建表与分区迁移建表时把压缩和文件块参数一次配好后面就不用反复重建。CREATE TABLE IF NOT EXISTS dwd_order_detail_archive ( order_id BIGINT COMMENT 订单ID, user_id BIGINT COMMENT 用户ID, pay_amount DECIMAL(18,2), channel_code STRING, storage_tier STRING ) COMMENT 订单明细归档表180 天以上分区 PARTITIONED BY (dt STRING) STORED AS ORC TBLPROPERTIES ( orc.compress ZLIB, -- 归档场景优先压缩比ZSTD 读写更快但压缩略低 orc.bloom.filter.columns order_id, -- 单条回溯全靠它 orc.row.index.stride 10000, hive.exec.dynamic.partition.mode nonstrict );迁移不建议一条INSERT跑到底按分区逐月搬迁更稳失败可以断点续跑。# migrate_archive.py # 逐月搬迁 dwd_order_detail 中 storage_tierarchive 的分区 from pyspark.sql import SparkSession spark (SparkSession.builder .appName(dwd_order_detail_archive_migrate) .config(spark.sql.shuffle.partitions, 400) # 单月数据量按 400 分区摊 .config(spark.sql.adaptive.enabled, true) # 自适应合并小文件 .config(spark.sql.adaptive.advisoryPartitionSizeInBytes, 268435456) # 单分区目标 256MB .enableHiveSupport() .getOrCreate()) months [2023-01, 2023-02, 2023-03] # 由调度传参不用手写 for m in months: spark.sql(f INSERT OVERWRITE TABLE dwd_order_detail_archive PARTITION (dt) SELECT order_id, user_id, pay_amount, channel_code, storage_tier, dt FROM dwd_order_detail WHERE dt LIKE {m}% AND storage_tier archive )三个参数值得解释。spark.sql.shuffle.partitions默认 200对月级明细偏小容易在单分区里堆出超大文件调到 400800 更合适。advisoryPartitionSizeInBytes设成 256MB 是让 AQE 把小于这个值的分区合并直接解决归档表最常见的小文件问题。INSERT OVERWRITE ... PARTITION (dt)用动态分区写入重跑同一月份不会产生重复文件。注意迁移前先把目标表的生命周期TTL和冷存储策略绑定不然数据搬过去了存储介质还是热存钱一分没省。3.3 归档前后的一致性校验搬完必须校验三种粒度一起看缺一种都可能漏。-- 粒度一行数对齐 SELECT src AS t, COUNT(*) AS cnt FROM dwd_order_detail WHERE dt LIKE 2023-01% AND storage_tierarchive UNION ALL SELECT dst, COUNT(*) FROM dwd_order_detail_archive WHERE dt LIKE 2023-01%; -- 粒度二主键去重计数防止迁移过程中因重分区引入重复 SELECT src, COUNT(DISTINCT order_id) FROM dwd_order_detail WHERE dt LIKE 2023-01% AND storage_tierarchive UNION ALL SELECT dst, COUNT(DISTINCT order_id) FROM dwd_order_detail_archive WHERE dt LIKE 2023-01%; -- 粒度三金额汇总用于发现字段截断或精度丢失 SELECT src, SUM(pay_amount) FROM dwd_order_detail WHERE dt LIKE 2023-01% AND storage_tierarchive UNION ALL SELECT dst, SUM(pay_amount) FROM dwd_order_detail_archive WHERE dt LIKE 2023-01%;行数对不上多半是WHERE条件里storage_tier的边界写错比如源表用而目标表用LIKE。去重计数对不上一般是迁移里混进了重复分区。金额汇总对不上优先查DECIMAL精度声明归档表建表时写成DECIMAL(10,2)就会静默截断。三步都过了再删源分区删除动作也要按分区来不要DROP TABLE。4. 数据中台建设方案的调度与元数据配套冷热链路不能只做一半归档表建好只是开始如果调度、元数据、权限三块没跟上下游会在两周内把归档表重新读成热表或者干脆绕过中台自己拉数据。4.1 调度依赖归档任务与下游任务错峰归档任务会占用大量 IO 和 shuffle 资源跟出报表的任务挤在同一个时间窗两边都会超时。常见做法是把归档调度放在业务低峰并且和下游任务建立明确依赖。任务建议时间窗依赖关系超时阈值日常 ETL01:0005:00上游为 ODS 同步60 分钟归档迁移05:3008:00依赖当日 ETL 完成、标记任务完成120 分钟一致性校验归档后 30 分钟强依赖归档迁移成功30 分钟源分区清理校验通过后强依赖校验任务成功15 分钟依赖链的写法是「归档任务依赖打标任务清理任务依赖校验任务」中间任何一环失败就中断不要用「忽略失败继续跑」否则会出现「校验没过但源分区已被删」这种不可逆的问题。4.2 元数据与血缘让归档表可被搜到归档表最容易变成「数据沼泽」的原因是它没进资产目录没人知道它存在于是下游重新从 ODS 拉一遍。迁移任务里应该同步写元数据。-- 把归档表注册进元数据表标注源表、归档时间、粒度 INSERT INTO meta_table_registry (table_name, source_table, layer, partition_grain, archive_start, owner, ttl_days) VALUES (dwd_order_detail_archive, dwd_order_detail, archive, day, 2023-01-01, data-platform, 3650);partition_grain标清是日分区还是月分区下游查的时候才不会按天扫全表。archive_start标明最早分区配合血缘图谱BI 工具在解析 SQL 时就能提示「该表为归档表查询延迟较高」把预期先降下来。4.3 权限与冷查询成本控制归档表如果对所有分析师开放成本会以一种很隐蔽的方式反弹单次查询慢、扫描量大但每个人都觉得自己只查了一次。常见做法是给归档表单独设一个只读角色并强制查询带上分区条件。-- 归档层专用角色只读 CREATE ROLE archive_reader; GRANT SELECT ON TABLE dwd_order_detail_archive TO ROLE archive_reader; -- 通过视图收口强制分区过滤禁止全表扫描 CREATE VIEW v_dwd_order_detail_archive AS SELECT order_id, user_id, pay_amount, channel_code, dt FROM dwd_order_detail_archive WHERE dt date_sub(current_date(), 1095); -- 只暴露近三年用视图收口的好处是策略写在一处改阈值不用逐个通知用户。代价是视图会隐藏部分分区需要历史全量的场景要走单独申请流程。这一步在数据中台建设方案里常常被忽略但它决定了归档之后成本曲线是往下走还是回来。5. 数据中台建设方案的验收三类指标验证冷热分层有没有真省钱方案写完、任务跑完怎么证明这一套起了作用不要只看存储总量那个数字受业务增长影响太大。看三类比值更准。第一类存储结构指标。归档层容量占全量比例、热存容量同比增速、单表平均压缩比。正常的组合是归档层占比稳步上升热存增速明显低于业务数据量增速压缩比落在 25 倍区间。如果归档层占比上去了但总账单没降先查归档表用的存储介质是不是还在热存桶里。第二类访问结构指标。归档层查询占比、单次归档查询平均扫描分区数、P95 恢复时间。归档层查询占比长期低于 5% 说明分层合理如果单次查询平均扫描分区数在涨说明视图收口没生效有人在绕过视图直接查表。第三类一致性指标。校验任务通过率、源分区清理滞后天数、血缘覆盖率。清理滞后天数是个容易被忽视的指标它反映「数据搬了但没删」等于双份存储很多团队成本降不下来就卡在这一步。-- 每日采一次落到治理看板 SELECT current_date() AS stat_date, SUM(CASE WHEN layerarchive THEN size_gb ELSE 0 END) / SUM(size_gb) AS archive_ratio, SUM(CASE WHEN layer IN (ods,dwd,dws) THEN size_gb ELSE 0 END) AS hot_size_gb, COUNT(DISTINCT table_name) AS table_cnt, AVG(compression_ratio) AS avg_compress FROM meta_table_registry WHERE stat_date current_date();一个具体技巧阈值别一次调到位。先把归档线从 365 天挪到 180 天跑两周看恢复请求量再决定要不要继续降到 120 天。降得太快业务方的回溯需求会集中爆发恢复任务排队反而把归档链路压垮。把这条阈值当成一个需要持续微调的参数而不是方案文档里写死的一个数冷热分层的收益才会随业务一起滚起来。本文还有配套的精品资源点击获取