前言:以下这份电商数据仓库开发规范以笔者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的加工逻辑时,必须同步编写质量检查逻辑。

  • 何时操作:在每天的任务开发调度执行中自动运行。

  • 实际工作流

    1. 开发时:你写订单DWD表脚本,需要增加quality_checkfiltered_data两个CTE。这迫使你思考:“这个表的核心质量规则是什么?”(如:订单ID非空、金额非负)。

    2. 运行时:任务处理今天(${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任务完成后,业务方查看数据前执行。

  • 实际工作流

    1. 配置任务:你将此DataQualityChecker类部署为一个每天早6点的调度任务。

    2. 自动巡检:任务启动后,会按配置逐一检查关键表(如dwd_order_fact_di)。它执行的不是行级检查,而是表级健康度检查

      • _check_not_empty:今天分区有数据吗?(避免空跑)

      • _check_no_null_key:关键字段有大量空值吗?

      • _check_data_fluctuation:今日订单量相比昨天暴跌50%吗?(配置阈值)

    3. 决策与告警:任何一项失败(‘passed‘: False),脚本会自动汇总结果,并触发告警(如发送钉钉消息给值班员:“警报:订单事实表今日数据量异常,较昨日下降60%”)。

  • 核心价值

    • 全局健康视图:在业务开始用数前,主动发现异常,防患于未然

    • 插件化扩展checks列表可随意增加新检查项(如添加_check_avg_amount_range检查客单价是否在合理区间),易于团队共建质量规则库。

    • 告警标准化:结构化的返回结果(check_nameactual_value等)让告警信息清晰明了,便于快速定位问题。

实际应用场景

设想场景:每日凌晨,订单DWD层任务成功运行。

  • 早晨6点DataQualityChecker 任务自动启动,对 dwd_order_fact_di 表当日分区进行检查。

  • 发现问题_check_data_fluctuation 方法发现当日订单总数环比下降超过50%(预设阈值),标记为‘passed‘: False

  • 触发告警:由于all_passedFalse,系统自动向数据值班人员发送钉钉告警:“数据波动异常:表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任务跑完),或当业务对数据有质疑时手动执行。

  • 实际工作流

    1. 编写稽核点:数据架构师或资深开发在设计dwd_order_fact_di时,就需定义其与上游ods_order_mysql_di的核心一致性稽核点(如:“已支付订单”的数量和金额在两层必须一致)。

    2. 自动化/手动执行:将此SQL配置为任务后置检查,或放入数据质量平台。它比较ODS层的“已支付订单”与DWD层标记为is_paid=1的订单。

    3. 解读结果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战报)产出前,或定期(如每周) 执行。

  • 实际工作流

    1. 定义核心指标:与业务方共同确认,GMV是必须万无一失的核心指标。

    2. 寻找独立数据源:约定从订单事实表支付流水表两个独立加工链路计算GMV。

    3. 执行交叉验证:运行此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');
  • 实操工作流(参考)

    1. 创建配置表:运维工程师在Hive中执行此DDL,创建中央监控指标库。

    2. 配置指标:像初始化数据一样,插入一行行监控规则。例如,设定“任务准时完成率”低于95%发钉钉警告,低于90%打电话。

    3. 开发巡检程序:编写一个Python调度程序(参考之前的DataQualityChecker),每天自动读取此表的所有记录。对于每一行,它:

      • 根据 metric_id 执行对应的计算SQL(如计算当日任务完成率)。

      • 将计算结果与 threshold_warningthreshold_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;
  • 实操工作流(参考)

    1. 数据采集:通过平台API或日志,每日采集每个计算任务的CU耗时(转化为成本)、每个表的存储量,写入ads_cost_analysis_daily

    2. 人工标记:定期(如每季度)由数据产品经理或业务方,对核心数据资产(表或任务)进行business_value_score(1-10分)评分。

    3. 生成优化清单:每周运行规范中的高成本识别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日

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐