耗时三天整理:一份可以直接拿来使用的《电商数据仓库开发规范》
本文提供了一份可直接参考的中型电商数据仓库开发规范,涵盖设计、开发、运维全流程。核心包括:分层(ODS/DWD/DWS/ADS)命名与设计规范;SQL、Python代码及DataWorks任务开发标准;任务调度与依赖配置;强调数据质量,内嵌检查与独立稽核结合;并规定了文档、监控及成本控制要求。该规范旨在建立标准化、可维护、高效且成本可控的数仓体系,团队可根据自身建设阶段选择性遵循与完善。
前言:以下这份电商数据仓库开发规范以笔者10年数仓开发经验来看,对大部分电商数仓,可以直接拿来使用,只需根据自己公司的实际情况微调即可;实际执行过程中,可根据公司实际数仓建设阶段,选择型的遵循和完善。
《中型电商数据仓库开发规范》
版本号:V2.0
生效日期:2025年6月1日
适用范围:数据仓库开发团队及相关协作方
第一章:总则
1.1 规范目的
为保障数据仓库建设的规范性、可维护性和高效性,统一数据开发标准,降低维护成本,特制定本规范。
1.2 适用范围
-
数据仓库所有层次的表(ODS/DWD/DWS/ADS)
-
所有ETL/ELT数据处理任务
-
所有数据开发人员及协作方
-
MaxCompute+DataWorks平台所有数据开发活动
1.3 核心原则
1. 简单优于复杂:在满足需求的前提下,选择最简单的实现 2. 稳定压倒一切:确保数据产出的稳定性和准确性 3. 可维护优先:代码和设计要易于理解和修改 4. 成本可控:关注计算和存储成本,避免浪费 5. 持续改进:规范需要定期评审和优化
1.4 违反规范的后果
-
轻微违规:代码Review不通过,需重新修改
-
一般违规:影响项目进度,记入个人绩效考核
-
严重违规:导致数据事故,按公司规定处理
第二章:命名规范
2.1 分层命名约定
ods_ 原始数据层:贴源数据,保持原样 dwd_ 明细数据层:清洗、整合、维度退化 dws_ 汇总数据层:轻度汇总,面向主题 ads_ 应用数据层:高度汇总,面向应用 dim_ 维度表层:缓慢变化维度 tmp_ 临时表层:中间计算临时表
2.2 表命名规范
格式:{层次}_{业务主题}_{表名描述}_{更新频率}
示例:
ods_order_mysql_di # 订单MySQL日增量
dwd_order_fact_di # 订单事实日增量表
dws_user_order_di # 用户订单日增量汇总
ads_sales_daily_df # 销售日全量表
dim_product_df # 商品维度全量表
tmp_order_calculate_daily # 订单计算临时表
注意:
1. 业务主题:order(订单)、user(用户)、product(商品)、trade(交易)等
2. 表名描述:简短准确,不超过3个单词
3. 更新频率:di(日增量)、df(日全量)、wi(周增量)、mi(月增量)
2.3 字段命名规范
-- 通用字段命名
CREATE TABLE example (
id BIGINT COMMENT 'ID', -- 主键用id
order_id STRING COMMENT '订单ID', -- 业务主键用{业务}_id
user_id STRING COMMENT '用户ID',
product_id STRING COMMENT '商品ID',
order_amount DECIMAL(18,2) COMMENT '订单金额', -- 金额字段用amount
order_status INT COMMENT '订单状态',
is_deleted TINYINT COMMENT '是否删除', -- 是否标志用is_开头
create_time TIMESTAMP COMMENT '创建时间', -- 时间字段用_time结尾
update_time TIMESTAMP COMMENT '更新时间',
dt STRING COMMENT '分区日期' -- 分区字段统一用dt
);
-- 命名规则:
1. 全部小写,使用下划线分隔
2. 避免使用保留关键字
3. 相同含义的字段在不同表中保持一致
4. 布尔类型字段以is_、has_、can_开头
2.4 任务命名规范
DataWorks节点命名:
{业务}_{分层}_{表名}_{操作}_{频率}
示例:
order_ods_order_mysql_di_sync_daily # 订单ODS层MySQL同步日任务
trade_dwd_order_fact_di_process_daily # 交易DWD层订单事实处理日任务
user_dws_user_order_di_agg_daily # 用户DWS层订单聚合日任务
调度依赖命名:
{上游任务名} → {下游任务名}
示例:order_ods_order_mysql_di_sync_daily → trade_dwd_order_fact_di_process_daily
2.5 变量命名规范
sql
-- SQL变量命名
SET bizdate = '${yyyy-mm-dd-1}'; -- 业务日期
SET hour = '${hh}'; -- 小时
SET week = '${yyyy-ww}'; -- 周
-- Python变量命名
user_count = 1000 # 小写+下划线
max_retry_times = 3 # 常量用大写
TASK_TIMEOUT = 3600 # 配置常量全大写
第三章:表设计规范
3.1 分层设计标准
3.1.1 ODS层设计规范
sql
-- 1. 保持源数据结构,不做业务逻辑处理
CREATE TABLE ods_order_mysql_di (
-- 源表所有字段原样保留
order_id STRING COMMENT '订单ID',
user_id STRING COMMENT '用户ID',
order_amount DECIMAL(10,2) COMMENT '订单金额',
-- 添加技术字段
source_db STRING COMMENT '源数据库',
source_table STRING COMMENT '源表名',
etl_time TIMESTAMP COMMENT 'ETL时间',
dt STRING COMMENT '分区日期'
)
PARTITIONED BY (dt STRING) -- 必须按天分区
COMMENT '订单原始数据表'
LIFECYCLE 90; -- 生命周期90天
-- 注释: 如果是基于hive数仓,数据生命周期管理替代方案
-- 在运维脚本或调度任务中定期执行,例如删除90天前的分区
ALTER TABLE ods_order_mysql_di DROP IF EXISTS PARTITION (dt < '${90天前日期}');
-- 或使用动态参数
ALTER TABLE ods_order_mysql_di DROP IF EXISTS PARTITION (dt < date_sub(current_date, 90));
-- 2. 同步方式选择
-- 增量表:表名以_di结尾,每天增量同步
-- 全量表:表名以_df结尾,每天全量同步
3.1.2 DWD层设计规范
sql
-- 1. 事实表设计
CREATE TABLE dwd_order_fact_di (
order_id STRING COMMENT '订单ID',
user_id STRING COMMENT '用户ID',
product_id STRING COMMENT '商品ID',
-- 事实度量
order_amount DECIMAL(18,2) COMMENT '订单金额',
product_count INT COMMENT '商品数量',
-- 维度退化(减少关联)
user_name STRING COMMENT '用户名',
product_name STRING COMMENT '商品名',
product_category STRING COMMENT '商品类目',
-- 时间维度
order_date STRING COMMENT '订单日期',
order_hour STRING COMMENT '订单小时',
-- 状态标志
is_paid TINYINT COMMENT '是否支付',
is_refund TINYINT COMMENT '是否退款',
dt STRING COMMENT '分区日期'
)
PARTITIONED BY (dt STRING)
COMMENT '订单事实表'
LIFECYCLE 365;
-- 2. 设计原则
-- 一张事实表对应一个业务过程
-- 适当维度退化,提高查询性能
-- 保留历史变化,便于追溯
3.1.3 DWS层设计规范
sql
-- 1. 汇总表设计
CREATE TABLE dws_user_order_di (
dt STRING COMMENT '统计日期',
user_id STRING COMMENT '用户ID',
-- 订单汇总
order_count BIGINT COMMENT '订单数',
order_amount DECIMAL(18,2) COMMENT '订单金额',
paid_order_count BIGINT COMMENT '支付订单数',
paid_amount DECIMAL(18,2) COMMENT '支付金额',
-- 商品汇总
product_count BIGINT COMMENT '商品数',
distinct_product_count BIGINT COMMENT '去重商品数',
-- 时间相关
first_order_date STRING COMMENT '首单日期',
last_order_date STRING COMMENT '末单日期',
avg_order_interval_days DECIMAL(5,1) COMMENT '平均下单间隔天数',
PRIMARY KEY (dt, user_id)
)
PARTITIONED BY (dt STRING)
COMMENT '用户订单汇总表'
LIFECYCLE 365;
-- 2. 设计原则
-- 按主题域汇总,避免跨主题
-- 保留明细关联能力,可下钻分析
-- 汇总粒度要明确,避免歧义
3.1.4 ADS层设计规范
sql
-- 1. 应用表设计
CREATE TABLE ads_sales_daily_df (
dt STRING COMMENT '统计日期',
channel STRING COMMENT '渠道',
product_category STRING COMMENT '商品类目',
-- 核心指标
gmv DECIMAL(18,2) COMMENT 'GMV',
order_count BIGINT COMMENT '订单数',
uv BIGINT COMMENT '访客数',
paid_user_count BIGINT COMMENT '支付用户数',
-- 衍生指标
conversion_rate DECIMAL(5,4) COMMENT '转化率',
avg_order_value DECIMAL(10,2) COMMENT '客单价',
-- 方便查询的字段
week_of_year INT COMMENT '周数',
is_weekend TINYINT COMMENT '是否周末',
is_holiday TINYINT COMMENT '是否节假日',
PRIMARY KEY (dt, channel, product_category)
)
PARTITIONED BY (dt STRING)
COMMENT '销售日报表'
LIFECYCLE 90; -- ADS层生命周期较短
-- 2. 设计原则
-- 面向应用,无需复杂计算
-- 宽表设计,减少关联
-- 数据要稳定,避免频繁变更
3.1.5 维度表设计规范
sql
-- 1. 缓慢变化维处理(Type 2)
CREATE TABLE dim_product_scd (
product_id STRING COMMENT '商品ID',
product_name STRING COMMENT '商品名称',
product_price DECIMAL(10,2) COMMENT '商品价格',
product_category STRING COMMENT '商品类目',
-- SCD2技术字段
start_date STRING COMMENT '生效日期',
end_date STRING COMMENT '失效日期',
is_current TINYINT COMMENT '是否当前版本',
version INT COMMENT '版本号',
dt STRING COMMENT '分区日期',
PRIMARY KEY (product_id, start_date)
)
COMMENT '商品维度表(缓慢变化维)'
LIFECYCLE 365;
-- 2. 查询当前有效版本
SELECT * FROM dim_product_scd
WHERE is_current = 1
AND dt = '${bizdate}';
3.2 分区设计规范
sql
-- 1. 分区策略选择 -- 按天分区:绝大多数表使用 -- 按月分区:历史归档表使用 -- 按小时分区:实时数据表使用 -- 2. 分区键统一使用dt(STRING类型) PARTITIONED BY (dt STRING) -- 3. 分区命名规范 -- 按天:dt='2024-01-01' -- 按月:dt='2024-01' -- 按小时:dt='2024-01-01-08' -- 4. 分区维护 -- 自动创建:通过调度参数自动创建新分区 -- 自动清理:设置LIFECYCLE自动清理过期分区 -- 禁止手动删除分区,必须通过流程申请
3.3 存储格式规范
1. 文本表:仅用于临时数据交换 2. 内部表:所有正式表使用内部表 3. 存储优化: - 设置合适的存储格式(ORC/Parquet):事实表、汇总表等查询频繁的表使用 ORC,因其在Hive生态中 支持更佳(特别是ACID);与Spark生态交互频繁或需要更好Schema演进支持的可用 Parquet。 - 合并小文件:每天执行一次(ALTER TABLE dwd_order_fact_orc PARTITION (dt='2024-01-01') CONCATENATE; -- 合并小文件) - 设置生命周期:根据数据重要性设置 4. 压缩设置: - 高压缩比:历史数据使用ZSTD - 平衡性能:热数据使用SNAPPY
3.4 索引设计规范
sql
-- 1. 主键设置(Hologres/ADB等)
CREATE TABLE ads_sales_daily_df (
dt STRING,
channel STRING,
product_category STRING,
gmv DECIMAL(18,2),
PRIMARY KEY (dt, channel, product_category) -- 查询频次高的组合
);
-- 2. 聚簇索引(MaxCompute)
CLUSTERED BY (user_id) SORTED BY (create_time DESC) INTO 128 BUCKETS
-- 3. 索引使用原则
-- 主键:查询条件中的等值过滤字段
-- 聚簇键:经常分组聚合的字段
-- 排序键:经常排序或范围查询的字段
-- 4. 说明
如果是在hive数仓中,一般不设置索引;
第四章:代码开发规范
4.1 SQL开发规范
4.1.1 基本规范
sql
-- 1. 关键字大写,表名、字段名小写
SELECT
user_id,
COUNT(DISTINCT order_id) as order_count,
SUM(order_amount) as total_amount
FROM dwd_order_fact_di
WHERE dt = '${bizdate}'
AND order_status = 2
GROUP BY user_id
HAVING order_count >= 1
ORDER BY total_amount DESC
LIMIT 100;
-- 2. 缩进:4个空格,不要用Tab
-- 3. 每行不超过100个字符
-- 4. 复杂SQL要分段,加空行
4.1.2 查询优化规范
sql
-- ❌ 错误示例:SELECT * 全表扫描
SELECT * FROM dwd_order_fact_di WHERE dt = '${bizdate}';
-- ✅ 正确示例:只查询需要的字段
SELECT
order_id,
user_id,
order_amount
FROM dwd_order_fact_di
WHERE dt = '${bizdate}';
-- ❌ 错误示例:在WHERE条件中使用函数
SELECT * FROM dwd_order_fact_di WHERE DATE_FORMAT(create_time, '%Y-%m-%d') = '${bizdate}';
-- 说明:避免在WHERE条件中对字段进行函数转换,这会导致无法使用分区裁剪或索引(如果存在)。
-- ✅ 正确示例:使用分区过滤
SELECT * FROM dwd_order_fact_di WHERE dt = '${bizdate}';
-- ❌ 错误示例:多表关联没有分区过滤
SELECT a.*, b.*
FROM table_a a
JOIN table_b b ON a.id = b.id;
-- ✅ 正确示例:关联时添加分区过滤
SELECT a.*, b.*
FROM table_a a
JOIN table_b b ON a.id = b.id
WHERE a.dt = '${bizdate}'
AND b.dt = '${bizdate}';
4.1.3 数据类型规范
sql
-- 1. 金额类型:DECIMAL(18,2)
-- 2. 数量类型:BIGINT
-- 3. 状态类型:INT或TINYINT
-- 4. 时间类型:TIMESTAMP(存储),STRING(分区)
-- 5. 文本类型:STRING,避免过长的VARCHAR
-- 示例:
CREATE TABLE example (
id BIGINT COMMENT 'ID',
amount DECIMAL(18,2) COMMENT '金额',
count BIGINT COMMENT '数量',
status TINYINT COMMENT '状态',
create_time TIMESTAMP COMMENT '创建时间',
content STRING COMMENT '内容'
);
4.1.4 注释规范
sql
-- 1. 表注释(必须)
CREATE TABLE dwd_order_fact_di (
...
) COMMENT '订单事实表,包含所有订单的明细数据,每天增量更新';
-- 2. 字段注释(必须)
CREATE TABLE dwd_order_fact_di (
order_id STRING COMMENT '订单ID,唯一标识一个订单',
user_id STRING COMMENT '用户ID,关联用户维度表',
order_status INT COMMENT '订单状态:1-待支付,2-已支付,3-已发货,4-已完成,5-已取消',
...
);
-- 3. 复杂SQL注释(必须)
WITH daily_order AS (
-- 步骤1:获取每日订单基础数据
SELECT
dt,
user_id,
COUNT(DISTINCT order_id) as order_cnt,
SUM(order_amount) as order_amount
FROM dwd_order_fact_di
WHERE dt >= DATE_SUB('${bizdate}', 30) -- 最近30天数据
AND order_status = 2 -- 已支付订单
GROUP BY dt, user_id
),
user_stats AS (
-- 步骤2:计算用户统计指标
SELECT
user_id,
AVG(order_cnt) as avg_daily_order,
SUM(order_amount) as total_amount
FROM daily_order
GROUP BY user_id
)
-- 步骤3:最终筛选和排序
SELECT
user_id,
avg_daily_order,
total_amount,
CASE
WHEN total_amount >= 10000 THEN '高价值'
WHEN total_amount >= 5000 THEN '中价值'
ELSE '低价值'
END as user_level
FROM user_stats
WHERE avg_daily_order >= 1
ORDER BY total_amount DESC;
4.2 DataWorks节点开发规范
4.2.1 节点配置规范
python
# DataWorks PyODPS节点模板
# -*- coding: utf-8 -*-
# @Name: dwd_order_fact_di加工
# @Author: 张三
# @Project: ${project}
# @Desc: 从ODS层加工订单事实表,包含订单明细和维度退化
# @Schedule: 每天02:00运行,依赖ODS层任务
# @Timeout: 2小时
# @Alert: 失败时电话告警
from odps import ODPS
import datetime
def main():
"""
主函数:订单事实表加工
输入:ods_order_mysql_di
输出:dwd_order_fact_di
逻辑:
1. 数据清洗:过滤无效数据
2. 维度退化:关联用户和商品维度
3. 状态标记:标记支付、退款等状态
4. 数据输出:写入DWD层分区
"""
# 获取业务日期(从调度参数)
biz_date = '${bizdate}'
print(f"开始处理订单事实表,日期:{biz_date}")
# 数据加工SQL
sql = f"""
INSERT OVERWRITE TABLE dwd_order_fact_di PARTITION (dt='{biz_date}')
SELECT
-- 订单基础信息
o.order_id,
o.user_id,
o.product_id,
-- 订单金额信息
o.order_amount,
o.payment_amount,
o.refund_amount,
-- 维度退化(减少后续关联)
COALESCE(u.user_name, '未知') as user_name,
COALESCE(p.product_name, '未知') as product_name,
COALESCE(p.category_name, '其他') as product_category,
-- 时间信息
o.create_time,
DATE(o.create_time) as order_date,
HOUR(o.create_time) as order_hour,
-- 状态标志
CASE WHEN o.order_status = 2 THEN 1 ELSE 0 END as is_paid,
CASE WHEN o.refund_amount > 0 THEN 1 ELSE 0 END as is_refund,
-- 技术字段
'{biz_date}' as dt
FROM ods_order_mysql_di o
LEFT JOIN dim_user_df u ON o.user_id = u.user_id AND u.dt = '{biz_date}'
LEFT JOIN dim_product_df p ON o.product_id = p.product_id AND p.dt = '{biz_date}'
WHERE o.dt = '{biz_date}'
AND o.order_id IS NOT NULL -- 过滤空订单号
AND o.user_id IS NOT NULL -- 过滤空用户
AND o.order_amount >= 0 -- 金额不能为负
"""
# 执行SQL
odps.execute_sql(sql)
print(f"订单事实表加工完成,日期:{biz_date}")
if __name__ == '__main__':
main()
4.2.2 参数使用规范
python
# 调度参数使用规范
# ✅ 正确:使用系统预置参数
bizdate = '${bizdate}' # 业务日期:T-1
yyyymmdd = '${yyyymmdd}' # 日期格式:20240101
hour = '${hour}' # 小时:00-23
# ✅ 正确:自定义参数(需在调度配置中定义)
start_date = '${start_date}' # 开始日期
end_date = '${end_date}' # 结束日期
user_type = '${user_type}' # 用户类型
# ❌ 错误:硬编码日期
bizdate = '2024-01-01' # 错误!不能硬编码
# ✅ 正确:日期计算
yesterday = '${yyyymmdd-1}' # 昨天
last_week = '${yyyymmdd-7}' # 一周前
first_day_of_month = '${yyyy-mm-01}' # 当月第一天
4.2.3 错误处理规范
python
# 错误处理模板
import traceback
from odps import ODPS
from odps.errors import ODPSError
def safe_execute_sql(odps, sql, max_retry=3):
"""安全执行SQL,包含重试机制"""
retry_count = 0
while retry_count < max_retry:
try:
print(f"执行SQL,尝试次数:{retry_count + 1}")
result = odps.execute_sql(sql)
print("SQL执行成功")
return result
except ODPSError as e:
retry_count += 1
print(f"SQL执行失败,错误:{str(e)}")
if retry_count >= max_retry:
raise e
# 等待后重试
import time
time.sleep(60 * retry_count) # 等待时间递增
def main():
try:
# 业务逻辑
odps = ODPS(...)
# 执行多个SQL,每个独立捕获异常
try:
sql1 = "INSERT OVERWRITE TABLE tmp_step1 ..."
safe_execute_sql(odps, sql1)
except Exception as e:
print(f"步骤1失败:{str(e)}")
# 发送告警但不退出,继续尝试后续步骤
send_alert("步骤1失败", str(e), level="warning")
try:
sql2 = "INSERT OVERWRITE TABLE tmp_step2 ..."
safe_execute_sql(odps, sql2)
except Exception as e:
print(f"步骤2失败:{str(e)}")
# 关键步骤失败,整个任务失败
send_alert("关键步骤2失败", str(e), level="error")
raise e
except Exception as e:
# 全局异常处理
error_msg = f"任务执行失败:{str(e)}\n{traceback.format_exc()}"
print(error_msg)
send_alert("任务执行失败", error_msg, level="critical")
raise e
4.3 Python开发规范
4.3.1 代码结构规范
python
# 标准PyODPS任务结构
"""
模块名称:order_etl.py
功能描述:订单ETL处理任务
作者:张三
创建时间:2024-01-01
"""
# 1. 导入标准库
import datetime
import json
import logging
# 2. 导入第三方库
from odps import ODPS
from odps.models import Table
# 3. 导入自定义模块
from utils.logger import setup_logger
from utils.config import get_config
# 4. 常量定义
MAX_RETRY_TIMES = 3
TIMEOUT_SECONDS = 3600
DEFAULT_PARTITION = 'dt'
# 5. 日志配置
logger = setup_logger(__name__)
# 6. 类定义
class OrderETL:
"""订单ETL处理器"""
def __init__(self, odps_client):
self.odps = odps_client
self.bizdate = None
def process(self, bizdate):
"""主处理流程"""
self.bizdate = bizdate
logger.info(f"开始处理订单ETL,日期:{bizdate}")
# 步骤1:数据提取
self.extract_data()
# 步骤2:数据转换
self.transform_data()
# 步骤3:数据加载
self.load_data()
logger.info(f"订单ETL处理完成,日期:{bizdate}")
def extract_data(self):
"""数据提取"""
logger.info("开始数据提取")
# 实现逻辑...
def transform_data(self):
"""数据转换"""
logger.info("开始数据转换")
# 实现逻辑...
def load_data(self):
"""数据加载"""
logger.info("开始数据加载")
# 实现逻辑...
# 7. 主函数
def main():
"""主函数"""
# 初始化配置
config = get_config()
# 初始化ODPS客户端
odps = ODPS(
access_id=config['access_id'],
secret_access_key=config['secret_access_key'],
project=config['project'],
endpoint=config['endpoint']
)
# 创建ETL实例并执行
etl = OrderETL(odps)
# 从调度参数获取业务日期
bizdate = '${bizdate}'
try:
etl.process(bizdate)
except Exception as e:
logger.error(f"ETL处理失败:{str(e)}", exc_info=True)
raise
if __name__ == '__main__':
main()
4.3.2 性能优化规范
python
# 性能优化示例
class OptimizedProcessor:
def process_large_data(self):
"""处理大数据量的优化方案"""
# ❌ 错误:一次性读取所有数据
# records = table.read() # 可能内存溢出
# ✅ 正确:分批读取
batch_size = 10000
for batch in table.read(batch_size=batch_size):
self.process_batch(batch)
# ✅ 正确:使用SQL优先
# 能在MaxCompute中完成的,不要在Python中处理
# ✅ 正确:使用向量化操作
import pandas as pd
df = pd.DataFrame(data)
# 使用向量化操作而不是循环
df['new_column'] = df['amount'] * df['quantity'] # 向量化
# ❌ 错误:逐行处理
# for index, row in df.iterrows():
# df.loc[index, 'new_column'] = row['amount'] * row['quantity']
第五章:任务调度规范
5.1 调度依赖规范
5.1.1 依赖配置标准
任务依赖关系:
1. 同层依赖:上游任务 → 下游任务
2. 跨层依赖:ODS → DWD → DWS → ADS
3. 跨主题依赖:订单 → 用户 → 商品
示例依赖链:
order_ods_mysql_sync_daily(02:00)
↓
order_dwd_fact_process_daily(03:00)
↓
user_dws_order_agg_daily(04:00) ← user_ods_mysql_sync_daily(02:30)
↓
ads_sales_daily_calculate(05:00)
5.1.2 依赖配置方式
python
# DataWorks依赖配置示例
# 方式1:节点输出作为下游输入
{
"nodes": [
{
"id": "node_1",
"outputs": ["table_1"] # 输出表
},
{
"id": "node_2",
"inputs": ["table_1"] # 输入表,依赖node_1
}
]
}
# 方式2:跨周期依赖
# 使用:${yyyymmdd-1} 依赖昨天的数据
# 使用:${yyyy-mm-01} 依赖月初的数据
5.2 调度时间规范
5.2.1 时间窗口设计
数据处理时间窗口: 00:00-00:30:源系统数据准备期(禁止同步) 00:30-06:00:数据同步和加工期(核心任务) 06:00-09:00:数据汇总和应用期(报表任务) 09:00-18:00:业务查询期(禁止重型任务) 18:00-24:00:优化和备份期(非关键任务) 任务执行时间安排:(基于实际调整,因为是基于事件依赖) 00:30:ODS层同步开始 02:00:DWD层加工开始 04:00:DWS层汇总开始 05:00:ADS层计算开始 06:00:数据质量检查 07:00:核心报表就绪 08:00:所有数据就绪
5.2.2 超时时间设置
python
# 超时时间配置标准
timeout_config = {
"同步任务": {
"ods_mysql_sync": 3600, # 1小时
"ods_api_sync": 1800, # 30分钟
},
"加工任务": {
"dwd_fact_process": 5400, # 1.5小时
"dws_agg_calculate": 7200, # 2小时
},
"应用任务": {
"ads_calculate": 3600, # 1小时
"report_generate": 1800, # 30分钟
}
}
# 在DataWorks节点中配置
# @Timeout: 7200 # 单位:秒
5.3 重试机制规范
5.3.1 重试策略
重试策略: 第一级:任务级别重试(DataWorks配置) 重试次数:3次 重试间隔:5分钟 第二级:代码级别重试(Python实现) 重试次数:2次 重试间隔:递增(1分钟、5分钟、15分钟) 第三级:人工干预(告警通知) 失败后通知值班人员 人工判断是否继续重试
5.3.2 幂等性设计
sql
-- 所有任务必须支持幂等性
-- 使用INSERT OVERWRITE而不是INSERT INTO
INSERT OVERWRITE TABLE dwd_order_fact_di PARTITION (dt='${bizdate}')
SELECT ... FROM ...
-- 使用TRUNCATE + INSERT(如果需要)
TRUNCATE TABLE tmp_calculate;
INSERT INTO TABLE tmp_calculate SELECT ...;
说明:幂等性设计指的是:同一个操作(如一个任务、一段脚本),无论被重复执行一次还是多次,最终对系统状态(数据结果)造成的影响是完全一致的。
在数据开发的语境下,可以通俗地理解为:你的ETL任务可以放心地重跑,而不会产生重复、错误或混乱的数据。
第六章:数据质量规范
数据质量检查分级:并非所有检查失败都应触发紧急告警。
可以将其分为 P0(关键)、P1(重要)、P2(警告) 等级别,对应不同的告警方式(如电话、钉钉、邮件)。
6.1 质量规则嵌入规范
6.1.1 开发阶段质量检查(行级和字段级的详细检查)
以下这段SQL被设计为主ETL任务的一部分,在生产数据的同时,进行实时过滤、标记和记录问题。
sql
-- 在ETL任务中嵌入数据质量检查
INSERT OVERWRITE TABLE dwd_order_fact_di PARTITION (dt='${bizdate}')
WITH source_data AS (
SELECT * FROM ods_order_mysql_di WHERE dt = '${bizdate}'
),
## quality_check 这是一个诊断步骤,它计算问题数据的数量(如空ID、负金额),但不实际过滤数据。## 结果可用于监控报表,了解每日数据健康状况。主流程并不依赖其结果,因此不会因质量检查失败而阻塞## 任务。
quality_check AS (
-- 数据质量检查(仅计数,不阻塞)
SELECT
COUNT(*) as total_count,
COUNT(CASE WHEN order_id IS NULL THEN 1 END) as null_order_id,
COUNT(CASE WHEN order_amount < 0 THEN 1 END) as negative_amount
FROM source_data
),
filtered_data AS (
-- 过滤不合格数据(记录到日志)
SELECT
*,
CASE
WHEN order_id IS NULL THEN 'order_id_is_null'
WHEN order_amount < 0 THEN 'amount_negative'
ELSE 'valid'
END as data_quality_flag -- 关键:为每一行打上质量标签
FROM source_data
WHERE order_id IS NOT NULL
AND order_amount >= 0
)
-- 主查询
SELECT
order_id,
user_id,
order_amount,
'${bizdate}' as dt
FROM filtered_data
WHERE data_quality_flag = 'valid';
-- 记录质量问题
INSERT INTO log_data_quality_issue
SELECT
'${bizdate}' as dt,
'dwd_order_fact_di' as table_name,
data_quality_flag as issue_type,
COUNT(*) as issue_count
FROM filtered_data
WHERE data_quality_flag != 'valid'
GROUP BY data_quality_flag;
-- 含义:这是质量可追溯性的关键。将问题数据的统计结果(问题类型、数量)写入一张单独的日志表。运维人员可以监控此表,当issue_count突然飙升时触发告警。
详细说明:SQL嵌入式检查 (6.1.1):开发者的“质检门禁”
-
这是什么:这是主ETL脚本的一部分,要求开发者在编写
dwd_order_fact_di的加工逻辑时,必须同步编写质量检查逻辑。 -
何时操作:在每天的任务开发和调度执行中自动运行。
-
实际工作流:
-
开发时:你写订单DWD表脚本,需要增加
quality_check和filtered_data两个CTE。这迫使你思考:“这个表的核心质量规则是什么?”(如:订单ID非空、金额非负)。 -
运行时:任务处理今天(
${bizdate})的数据时,自动执行:-
quality_check:生成诊断快照(今天有1000条记录,其中5条ID为空)。 -
filtered_data:自动过滤掉这5条脏数据,并打上‘order_id_is_null‘标签。 -
洁净数据写入核心表;问题统计写入
log_data_quality_issue日志表。
-
-
-
核心价值:
-
强制质量意识:将质量检查变为开发固定动作,如同写
WHERE条件一样自然。 -
实时止损:脏数据在入核心层时就被拦截,不会污染下游。
-
问题可追溯:
log_data_quality_issue表成为“病历本”,可回溯每日、每表的问题趋势。
-
实际应用场景
设想场景:某日支付系统出现bug,产生了100笔金额为负的订单。
-
ETL运行时:这100笔订单会被
filtered_data步骤过滤掉,不会进入dwd_order_fact_di表,保证了核心明细数据的可靠性。 -
ETL运行后:
log_data_quality_issue表中会新增一条记录:(dt=‘2024-01-01‘, issue_type=‘amount_negative‘, issue_count=100)。数据团队会看到这条异常记录,并反馈给业务系统团队进行排查修复。
6.1.2 质量检查任务规范(表级和分区级的聚合指标检查)
python
-- DataQualityChecker 类代表一个独立于ETL任务的后置检查任务,通常在每天所有ETL完成后运行,对结果数据进行全面“体检”。
# 质量检查任务模板
class DataQualityChecker:
def check_table_quality(self, table_name, dt):
"""检查表数据质量"""
checks = [
self._check_not_empty(table_name, dt),
self._check_no_null_key(table_name, dt),
self._check_data_fluctuation(table_name, dt), # 环比/同比波动检查
self._check_business_rules(table_name, dt) # 自定义业务规则
]
"""
含义:该类采用了“检查插件化” 的设计模式。每个_check_方法代表一种质量规则,可以灵活扩展。
这里包含了四大类常见检查:
完整性:表/分区是否有数据。
一致性:关键字段是否非空。
稳定性:数据量、主要指标是否发生异常波动。
业务正确性:是否符合特定业务逻辑(如“订单完成时间必须晚于创建时间”)。
"""
# 汇总结果
all_passed = all(check['passed'] for check in checks)
if not all_passed:
# 发送告警
self._send_quality_alert(table_name, dt, checks)
# 记录质量结果
self._log_quality_result(table_name, dt, checks)
return all_passed
def _check_not_empty(self, table_name, dt):
"""检查数据非空"""
sql = f"SELECT COUNT(*) as cnt FROM {table_name} WHERE dt='{dt}'"
result = self.odps.execute_sql(sql).fetchone()
return {
'check_name': '数据非空检查',
'passed': result['cnt'] > 0, # 判断逻辑:数据量>0则通过
'actual_value': result['cnt'], # 实际值:具体的数据行数
'expected_value': '>0' # 期望值
}
"""
该方法封装了一条检查SQL,并返回一个结构化的结果字典。‘passed‘字段是布尔值,是触发告警的依据;‘actual_value‘和‘expected_value‘则用于在告警信息或报表中清晰地展示问题详情。
"""
详细说明:Python独立稽核任务 (6.1.2):运维的“晨间巡检”
-
这是什么:这是一个独立于ETL的、定时运行的巡检脚本(如每天早6点)。
-
何时操作:在所有核心ETL任务完成后,业务方查看数据前执行。
-
实际工作流:
-
配置任务:你将此
DataQualityChecker类部署为一个每天早6点的调度任务。 -
自动巡检:任务启动后,会按配置逐一检查关键表(如
dwd_order_fact_di)。它执行的不是行级检查,而是表级健康度检查:-
_check_not_empty:今天分区有数据吗?(避免空跑) -
_check_no_null_key:关键字段有大量空值吗? -
_check_data_fluctuation:今日订单量相比昨天暴跌50%吗?(配置阈值)
-
-
决策与告警:任何一项失败(
‘passed‘: False),脚本会自动汇总结果,并触发告警(如发送钉钉消息给值班员:“警报:订单事实表今日数据量异常,较昨日下降60%”)。
-
-
核心价值:
-
全局健康视图:在业务开始用数前,主动发现异常,防患于未然。
-
插件化扩展:
checks列表可随意增加新检查项(如添加_check_avg_amount_range检查客单价是否在合理区间),易于团队共建质量规则库。 -
告警标准化:结构化的返回结果(
check_name,actual_value等)让告警信息清晰明了,便于快速定位问题。
-
实际应用场景
设想场景:每日凌晨,订单DWD层任务成功运行。
-
早晨6点:
DataQualityChecker任务自动启动,对dwd_order_fact_di表当日分区进行检查。 -
发现问题:
_check_data_fluctuation方法发现当日订单总数环比下降超过50%(预设阈值),标记为‘passed‘: False。 -
触发告警:由于
all_passed为False,系统自动向数据值班人员发送钉钉告警:“数据波动异常:表dwd_order_fact_di在分区2024-01-01的订单总数环比下降60%”,并附上详细数值。 -
人工介入:值班人员收到告警后,开始排查是业务本身出现下滑,还是上游数据同步或ETL逻辑出现了问题。
6.2 数据稽核规范
6.2.1 跨层数据稽核
sql
-- DWD层与ODS层数据一致性稽核
WITH ods_stats AS (
SELECT
COUNT(DISTINCT order_id) as ods_order_cnt,
SUM(order_amount) as ods_order_amount
FROM ods_order_mysql_di
WHERE dt = '${bizdate}'
AND order_status = 2
),
dwd_stats AS (
SELECT
COUNT(DISTINCT order_id) as dwd_order_cnt,
SUM(order_amount) as dwd_order_amount
FROM dwd_order_fact_di
WHERE dt = '${bizdate}'
AND is_paid = 1
)
SELECT
'订单数一致性' as check_item,
ods_order_cnt as ods_value,
dwd_order_cnt as dwd_value,
CASE
WHEN ods_order_cnt = 0 THEN 1.0
ELSE ABS(ods_order_cnt - dwd_order_cnt) * 1.0 / ods_order_cnt
END as diff_rate,
CASE
WHEN ABS(ods_order_cnt - dwd_order_cnt) * 1.0 / ods_order_cnt < 0.01
THEN 'PASS'
ELSE 'FAIL'
END as check_result
FROM ods_stats, dwd_stats;
详细说明:跨层数据稽核 (6.2.1):数据链路的“对账工具”
-
这是什么:用于验证数据在加工过程中是否发生丢失或扭曲的稽核SQL。
-
何时操作:在核心层级加工完成后(如DWD任务跑完),或当业务对数据有质疑时手动执行。
-
实际工作流:
-
编写稽核点:数据架构师或资深开发在设计
dwd_order_fact_di时,就需定义其与上游ods_order_mysql_di的核心一致性稽核点(如:“已支付订单”的数量和金额在两层必须一致)。 -
自动化/手动执行:将此SQL配置为任务后置检查,或放入数据质量平台。它比较ODS层的“已支付订单”与DWD层标记为
is_paid=1的订单。 -
解读结果:
diff_rate(差异率)和check_result(PASS/FAIL)直观给出结果。如果FAIL(差异>1%),说明加工逻辑(如支付状态判断)可能有bug,需立即排查。
-
-
核心价值:
-
保障加工逻辑正确性:是验证ETL代码逻辑是否准确的“试金石”。
-
量化数据一致性:用明确的数字(
diff_rate)取代模糊的“感觉数据不对”。
-
6.2.2 业务指标稽核
sql
-- 同一指标不同计算方式稽核
WITH method1 AS (
-- 方法1:从订单事实表计算GMV
SELECT
dt,
SUM(order_amount) as gmv_method1
FROM dwd_order_fact_di
WHERE dt = '${bizdate}'
AND is_paid = 1
GROUP BY dt
),
method2 AS (
-- 方法2:从支付流水表计算GMV
SELECT
dt,
SUM(payment_amount) as gmv_method2
FROM dwd_payment_flow_di
WHERE dt = '${bizdate}'
AND payment_status = 1
GROUP BY dt
)
SELECT
m1.dt,
m1.gmv_method1,
m2.gmv_method2,
ABS(m1.gmv_method1 - m2.gmv_method2) as absolute_diff,
CASE
WHEN m1.gmv_method1 = 0 THEN 1.0
ELSE ABS(m1.gmv_method1 - m2.gmv_method2) / m1.gmv_method1
END as relative_diff,
CASE
WHEN ABS(m1.gmv_method1 - m2.gmv_method2) / m1.gmv_method1 < 0.05
-- 实际开发中可以根据实际业务场景分级:核心指标<1%,重要指标<3%,一般指标<5%。
THEN 'PASS'
ELSE 'FAIL'
END as check_result
FROM method1 m1
JOIN method2 m2 ON m1.dt = m2.dt;
详细说明:业务指标稽核 (6.2.2):关键指标的“交叉验证”
-
这是什么:针对同一业务指标,通过不同数据源进行交叉验证,确保核心指标绝对可靠。
-
何时操作:面向高管的关键报表(如每日GMV战报)产出前,或定期(如每周) 执行。
-
实际工作流:
-
定义核心指标:与业务方共同确认,GMV是必须万无一失的核心指标。
-
寻找独立数据源:约定从
订单事实表和支付流水表两个独立加工链路计算GMV。 -
执行交叉验证:运行此SQL,如果两个结果
relative_diff < 5%,则通过,说明数据高度可信。如果失败,则需深入分析:是订单漏支付记录?还是支付流水有重复?
-
-
核心价值:
-
建立终极信任:用“数据证明数据”,让业务方对核心报表数据充满信心。
-
发现深层问题:当两个独立源结果不一致时,往往能暴露出业务流程或数据模型中隐藏的深层缺陷。
-
第七章:文档规范
7.1 数据字典规范
7.1.1 表级文档
## 表名:dwd_order_fact_di ### 基本信息 - **中文名称**:订单事实表(日增量) - **所属层次**:DWD明细数据层 - **更新频率**:每日增量 - **负责人**:张三 - **创建时间**:2024-01-01 ### 业务描述 存储订单的明细事实数据,包括订单基本信息、金额信息、状态信息等。 用于订单明细查询、订单分析、用户行为分析等场景。 ### 数据来源 - 主表:ods_order_mysql_di(订单原始数据) - 维表:dim_user_df(用户维度)、dim_product_df(商品维度) ### 加工逻辑 1. 数据清洗:过滤无效订单(订单ID为空、金额为负等) 2. 维度退化:关联用户和商品维度,退化常用维度字段 3. 状态标记:标记支付状态、退款状态等 4. 数据输出:写入DWD层分区 ### 重要提示 1. 此表为增量表,每天只包含当天的数据 2. 历史数据不会更新,如需变更需重跑历史分区 3. 关联查询时务必带上dt分区条件
7.1.2 字段级文档
sql
-- 字段注释标准格式
CREATE TABLE dwd_order_fact_di (
-- 订单标识
order_id STRING COMMENT '订单ID,唯一标识一个订单,格式:ORD{yyyymmdd}{8位序列}',
-- 用户标识
user_id STRING COMMENT '用户ID,关联dim_user_df表,格式:USR{10位数字}',
-- 商品标识
product_id STRING COMMENT '商品ID,关联dim_product_df表,格式:PROD{8位数字}',
-- 金额信息
order_amount DECIMAL(18,2) COMMENT '订单金额,单位为元,保留2位小数',
-- 状态信息
order_status INT COMMENT '''
订单状态:
1 - 待支付
2 - 已支付
3 - 已发货
4 - 已完成
5 - 已取消
6 - 退款中
7 - 已退款
''',
-- 时间信息
create_time TIMESTAMP COMMENT '订单创建时间,UTC时间,格式:yyyy-MM-dd HH:mm:ss',
-- 技术字段
dt STRING COMMENT '分区字段,格式:yyyy-MM-dd,用于按天分区'
);
7.2 任务文档规范
7.2.1 DataWorks节点文档
python
# DataWorks节点头信息规范 # -*- coding: utf-8 -*- # @Name: dwd_order_fact_di加工任务 # @Author: 张三 # @Department: 数据平台部 # @Project: 电商数仓项目 # @CreateTime: 2024-01-01 # @UpdateTime: 2024-01-15 # @Version: 1.2 # @Desc: # 从ODS层加工订单事实表,包含以下步骤: # 1. 数据清洗:过滤无效数据 # 2. 维度退化:关联用户和商品维度 # 3. 状态转换:转换为统一状态码 # 4. 数据输出:写入DWD层分区 # @Input: # 1. ods_order_mysql_di(订单原始数据) # 2. dim_user_df(用户维度表) # 3. dim_product_df(商品维度表) # @Output: # dwd_order_fact_di(订单事实表) # @Schedule: # 每天03:00运行 # 依赖:ods_order_mysql_di同步任务 # 下游:dws_user_order_di汇总任务 # @Timeout: 7200秒(2小时) # @Alert: 失败时电话告警 # @Params: # bizdate: 业务日期,格式:yyyy-MM-dd # hour: 小时,格式:HH # @ChangeLog: # 2024-01-01 v1.0 张三 初始版本 # 2024-01-10 v1.1 李四 增加退款状态处理 # 2024-01-15 v1.2 张三 优化性能,添加索引
7.2.2 变更记录规范
## 变更记录 ### 2024年1月 #### 2024-01-15 v1.2 **变更类型**:优化 **变更人**:张三 **影响范围**:dwd_order_fact_di **变更内容**: 1. 优化SQL性能,添加分区裁剪 2. 增加商品类目维度退化 3. 修复金额计算精度问题 **验证方式**:数据一致性稽核通过 #### 2024-01-10 v1.1 **变更类型**:功能增强 **变更人**:李四 **影响范围**:dwd_order_fact_di **变更内容**: 1. 增加退款状态标记 2. 增加数据质量检查 3. 增加处理日志记录 **验证方式**:数据质量检查通过 #### 2024-01-01 v1.0 **变更类型**:新建 **变更人**:张三 **影响范围**:dwd_order_fact_di **变更内容**: 1. 创建订单事实表基础版本 2. 实现基本ETL逻辑 **验证方式**:数据验收通过
7.3 知识库维护规范
7.3.1 知识库结构
数据知识库/
├── 01_数据架构/
│ ├── 数据分层规范.md
│ ├── 数据流向图.md
│ └── 技术选型说明.md
├── 02_数据模型/
│ ├── 主题域划分.md
│ ├── 核心模型设计.md
│ └── 维度建模规范.md
├── 03_开发规范/
│ ├── SQL开发规范.md
│ ├── Python开发规范.md
│ └── 任务调度规范.md
├── 04_数据质量/
│ ├── 质量监控规则.md
│ ├── 问题处理流程.md
│ └── 应急处理预案.md
├── 05_数据字典/
│ ├── ODS层数据字典.md
│ ├── DWD层数据字典.md
│ ├── DWS层数据字典.md
│ └── ADS层数据字典.md
├── 06_运维手册/
│ ├── 日常运维手册.md
│ ├── 故障处理手册.md
│ └── 性能优化手册.md
└── 07_项目文档/
├── 需求文档模板.md
├── 设计文档模板.md
└── 验收文档模板.md
7.3.2 文档更新机制
1. 谁开发,谁文档 - 开发人员负责编写和维护相关文档 - 代码变更时同步更新文档 2. 评审机制 - 重要文档需要团队评审 - 变更需要记录变更历史 3. 定期维护 - 每月第一个周五检查文档时效性 - 每季度全面更新一次 4. 文档质量检查 - 新员工能否看懂 - 能否指导故障处理 - 是否覆盖所有关键点
第八章:运维与监控规范
8.1 日常运维规范
8.1.1 值班巡检清单
## 数据仓库日常巡检清单 ### 每日巡检(09:00前完成) - [ ] 检查昨日数据任务完成情况 - [ ] 检查核心表数据质量 - [ ] 检查存储空间使用情况 - [ ] 检查系统资源使用情况 - [ ] 发送数据健康日报 ### 每周巡检(周一完成) - [ ] 检查任务依赖关系 - [ ] 检查数据生命周期 - [ ] 分析任务性能趋势 - [ ] 清理临时表和文件 - [ ] 备份重要配置和脚本 ### 每月巡检(每月5日前完成) - [ ] 统计月度数据质量 - [ ] 分析成本使用情况 - [ ] 优化慢查询和任务 - [ ] 更新文档和知识库 - [ ] 制定下月优化计划
8.1.2 故障处理流程
python
# 故障处理SOP
class FaultHandler:
def handle_data_delay(self):
"""处理数据延迟故障"""
steps = [
"1. 确认故障现象:查看任务运行状态",
"2. 定位故障点:检查失败任务日志",
"3. 分析故障原因:",
" - 资源不足?",
" - 代码错误?",
" - 依赖问题?",
" - 系统故障?",
"4. 制定处理方案:",
" - 重启任务(临时)",
" - 修复代码(根本)",
" - 调整资源(优化)",
"5. 执行处理方案:按优先级处理",
"6. 验证处理结果:检查数据质量",
"7. 记录故障信息:更新知识库",
"8. 制定预防措施:避免再次发生"
]
def handle_data_error(self):
"""处理数据错误故障"""
steps = [
"1. 立即冻结错误数据使用",
"2. 通知相关业务方",
"3. 回滚到正确版本",
"4. 修复错误数据",
"5. 重新计算受影响数据",
"6. 验证修复结果",
"7. 恢复数据服务",
"8. 复盘分析原因"
]
8.2 监控告警规范
8.2.1 监控指标定义
sql
-- 关键监控指标表
CREATE TABLE dim_monitor_metric (
metric_id STRING COMMENT '指标ID',
metric_name STRING COMMENT '指标名称',
metric_type STRING COMMENT '指标类型',
threshold_warning DECIMAL COMMENT '警告阈值',
threshold_critical DECIMAL COMMENT '严重阈值',
check_frequency STRING COMMENT '检查频率',
alert_channels STRING COMMENT '告警渠道'
);
INSERT INTO dim_monitor_metric VALUES
('METRIC_001', '任务准时完成率', '及时性', 0.95, 0.90, 'daily', 'dingding,email'),
('METRIC_002', '数据质量合格率', '准确性', 0.98, 0.95, 'daily', 'dingding,email,phone'),
('METRIC_003', '存储空间使用率', '资源', 0.80, 0.90, 'daily', 'dingding,email'),
('METRIC_004', '查询响应时间P95', '性能', 5.0, 10.0, 'daily', 'email'),
('METRIC_005', '任务失败率', '稳定性', 0.01, 0.05, 'hourly', 'dingding,phone');
-
实操工作流(参考):
-
创建配置表:运维工程师在Hive中执行此DDL,创建中央监控指标库。
-
配置指标:像初始化数据一样,插入一行行监控规则。例如,设定“任务准时完成率”低于95%发钉钉警告,低于90%打电话。
-
开发巡检程序:编写一个Python调度程序(参考之前的
DataQualityChecker),每天自动读取此表的所有记录。对于每一行,它:-
根据
metric_id执行对应的计算SQL(如计算当日任务完成率)。 -
将计算结果与
threshold_warning、threshold_critical对比。 -
根据突破的阈值和
alert_channels,调用对应的告警接口(钉钉机器人、邮件API、电话网关)。
-
-
-
核心指导意义:
-
变更无需发版:要调整“存储使用率”的告警阈值从80%改为85%,只需
UPDATE dim_monitor_metric SET threshold_warning=0.85 WHERE metric_id='METRIC_003';,无需修改和部署任何程序代码。 -
统一管理门户:所有监控项一目了然,避免遗漏。新员工能快速了解全局监控体系。
-
8.2.2 告警分级标准
P0级告警(必须电话通知):系统自动拨打值班员电话。值班员必须在10分钟内响应并处理,同时创建最高优先级故障工单。 1. 核心数据任务失败 2. 核心数据表数据为空 3. 数据质量严重问题(差异率>10%) 4. 系统资源严重不足(存储>95%) P1级告警(钉钉+邮件):在核心技术群触发@所有人的钉钉强提醒,并发邮件。要求30分钟内响应。 1. 重要数据任务失败 2. 数据质量问题(差异率5%-10%) 3. 性能严重下降(响应时间>10s) 4. 资源预警(存储>80%) P2级告警(邮件+日报):发送邮件给相关数据产品/开发负责人,并在每日运维晨会上通报。 1. 一般数据任务失败 2. 数据质量问题(差异率1%-5%) 3. 性能预警(响应时间>5s) 4. 资源使用异常 P3级提醒(周报):仅作为趋势指标,汇总到每周的数据健康度报告,供团队复盘。 1. 任务执行时间变长 2. 数据质量趋势下降 3. 资源使用趋势上升
8.3 成本控制规范
8.3.1 成本监控指标
sql
-- 成本分析报表
CREATE TABLE ads_cost_analysis_daily (
dt STRING COMMENT '日期',
cost_type STRING COMMENT '成本类型',
project_name STRING COMMENT '项目名称',
task_name STRING COMMENT '任务名称',
compute_cost DECIMAL(18,2) COMMENT '计算成本',
storage_cost DECIMAL(18,2) COMMENT '存储成本',
data_volume_gb DECIMAL(18,2) COMMENT '数据量(GB)',
cost_per_gb DECIMAL(18,4) COMMENT '每GB成本',
business_value_score INT COMMENT '业务价值评分',
cost_effectiveness DECIMAL(18,4) COMMENT '成本效益比'
)
COMMENT '成本分析日报';
-- 高成本任务识别
SELECT
task_name,
SUM(compute_cost) as total_cost,
AVG(cost_per_gb) as avg_cost_per_gb,
business_value_score,
cost_effectiveness,
CASE
WHEN cost_effectiveness < 0.5 THEN '优化优先级:高'
WHEN cost_effectiveness < 0.8 THEN '优化优先级:中'
ELSE '优化优先级:低'
END as optimization_priority
FROM ads_cost_analysis_daily
WHERE dt >= DATE_SUB('${bizdate}', 7)
GROUP BY task_name, business_value_score, cost_effectiveness
HAVING SUM(compute_cost) > 100 -- 周成本超过100元
ORDER BY optimization_priority, total_cost DESC;
-
实操工作流(参考):
-
数据采集:通过平台API或日志,每日采集每个计算任务的
CU耗时(转化为成本)、每个表的存储量,写入ads_cost_analysis_daily。 -
人工标记:定期(如每季度)由数据产品经理或业务方,对核心数据资产(表或任务)进行
business_value_score(1-10分)评分。 -
生成优化清单:每周运行规范中的高成本识别SQL。产出清单直接告诉管理者:“
task_xx任务每周花费500元,但业务价值评分仅3分,成本效益比0.15,属于‘高’优化优先级。”
-
-
核心指导意义:
-
从“花了多少”到“花在哪,值不值”:管理者可以据此决策:是优化一个高成本低价值的任务,还是为一个高价值任务增加预算?
-
驱动技术优化:将“成本优化”这个宏观目标,转化为工程师可执行的、明确的待优化任务清单。
-
8.3.2 成本优化措施
存储成本优化: 1. 设置合理的生命周期(热数据30天,温数据90天,冷数据转低频) 2. 定期清理临时表和中间表 3. 压缩存储格式(使用ORC/ZLIB) 4. 归档历史数据到廉价存储 计算成本优化: 1. 避免全表扫描,使用分区裁剪 2. 合并小文件,减少任务数 3. 优化SQL,减少数据倾斜 4. 合理设置任务并发数 5. 避开业务高峰期执行重型任务 开发成本优化: 1. 代码复用,避免重复开发 2. 使用模板和框架,提高开发效率 3. 自动化测试,减少错误成本 4. 知识共享,降低学习成本
第九章:附则
9.1 规范的执行与监督
1. 执行责任:数据团队负责人监督执行 2. 检查机制:代码Review时检查规范符合性 3. 违规处理:轻微违规提醒,严重违规记录 4. 例外审批:特殊情况需经团队负责人批准
9.2 规范的修订流程
1. 修订提议:任何团队成员可提出修订建议 2. 讨论评审:团队内部讨论修订内容 3. 试点验证:在小范围试点验证修订效果 4. 正式发布:修订通过后更新规范版本 5. 培训宣导:组织团队学习新规范
9.3 规范的解释权
本规范由数据仓库团队负责解释。 在执行过程中遇到本规范未涵盖的情况, 由数据团队负责人根据实际情况决定处理方式, 并记录案例作为后续规范修订的参考。
9.4 附录
附录A:常用缩写词典
ODS:操作数据存储(Operational Data Store) DWD:数据仓库明细层(Data Warehouse Detail) DWS:数据仓库汇总层(Data Warehouse Summary) ADS:应用数据服务层(Application Data Service) ETL:抽取、转换、加载(Extract, Transform, Load) ELT:抽取、加载、转换(Extract, Load, Transform) CDC:变更数据捕获(Change Data Capture) SCD:缓慢变化维度(Slowly Changing Dimension) P0/P1/P2:告警级别(Priority 0/1/2) SLA:服务级别协议(Service Level Agreement) SOP:标准操作程序(Standard Operating Procedure)
附录B:检查清单模板
## 数据开发检查清单 ### 表设计检查 - [ ] 表名是否符合命名规范? - [ ] 字段名是否符合命名规范? - [ ] 分区字段是否设置为dt? - [ ] 是否设置了合适的生命周期? - [ ] 是否添加了足够的注释? ### 代码开发检查 - [ ] SQL是否符合开发规范? - [ ] 是否添加了必要的注释? - [ ] 是否考虑了性能优化? - [ ] 是否处理了异常情况? - [ ] 是否支持幂等性? ### 任务配置检查 - [ ] 任务名是否符合规范? - [ ] 调度时间是否合理? - [ ] 依赖关系是否正确? - [ ] 超时时间是否设置? - [ ] 告警配置是否完善? ### 数据质量检查 - [ ] 是否嵌入了数据质量检查? - [ ] 是否考虑了数据一致性? - [ ] 是否记录了数据质量问题? - [ ] 是否有应急处理方案? ### 文档检查 - [ ] 是否更新了数据字典? - [ ] 是否编写了任务文档? - [ ] 是否记录了变更历史? - [ ] 知识库是否同步更新?
附录C:紧急联系人清单
| 角色 | 姓名 | 电话 | 钉钉 | 职责 |
|---|---|---|---|---|
| 数据负责人 | 张三 | 138xxxx8888 | zhangsan | 总体负责 |
| 高级工程师 | 李四 | 139xxxx9999 | lisi | 技术指导 |
| 中级工程师 | 王五 | 137xxxx7777 | wangwu | 开发实施 |
| 运维支持 | 赵六 | 136xxxx6666 | zhaoliu | 系统运维 |
| 业务接口人 | 孙七 | 135xxxx5555 | sunqi | 业务需求 |
文档版本历史
| 版本号 | 修订日期 | 修订内容 | 修订人 | 审批人 |
|---|---|---|---|---|
| V1.0 | 2025-01-01 | 初始版本创建 | 张三 | 李四 |
| V1.1 | 2025-03-15 | 增加成本控制规范 | 王五 | 张三 |
| V2.0 | 2025-06-01 | 全面优化,适配DataWorks | 张三 | 李四 |
规范发布:数据仓库团队
最后更新:2025年6月1日
生效日期:2025年6月1日
更多推荐

所有评论(0)