- 数仓分层的好处
- 分层有没有什么坏处
- 看板加载时长缩短做了什么
- 数据治理只是涉及过下线表吗
- 数据倾斜讲讲
- 大表与大表join的数据倾斜---分桶
- 详细介绍一下上面说的分桶
- 分桶和shuffle的分区有什么区别?
- 在map阶段读取文件比较慢,排查思路?
- Clickhouse 和 Doris 了解多少
- SQL:Uid hobby1hobby2 :1、求各hobby人数 2、hobby相同的人数
1. 数仓分层的好处
考察知识点
- 数仓分层的核心价值(解耦、复用、维护性)
- 分层对数据质量、业务响应的支撑作用
- 分层与大数据处理效率的关联
参考回答
数仓分层(如ODS→DWD→DWM→DWS→ADS)通过“纵向拆分数据处理流程”,带来四大核心好处:
- 解耦数据生产与消费:业务需求变更(如新增报表指标)时,仅需修改上层DWS/ADS层,无需改动DWD等底层数据。例如,新增“用户复购率”指标,只需在DWS层基于现有DWD用户行为数据计算,无需重新处理原始日志,适配业务快速迭代。
- 提升数据复用性:DWD层的清洗后明细数据可支撑多个DWS主题表。如“用户明细”表可同时供“用户活跃”“用户消费”“用户留存”等多个汇总表使用,减少重复计算,降低集群资源消耗(重复计算减少60%以上)。
- 简化问题定位与维护:数据异常时(如报表数据错误),可按“ADS→DWS→DWD→ODS”逐层排查。例如,发现DWS层销售额异常,可快速定位到DWD层是否漏过滤无效订单,或ODS层数据同步是否异常,问题排查时间从天级缩短至小时级。
- 保障数据质量与安全:在DWD层集中进行数据清洗(去重、补全)、脱敏(手机号/身份证加密),确保下游所有应用使用“干净、合规”的数据。例如,用户手机号在DWD层统一脱敏为“138****5678”,避免敏感数据泄露,同时减少各层重复脱敏的工作量。
补充注意要点
- 分层不是“越多越好”:中小企业数仓可合并DWM与DWS层(称“DWS层”),避免过度拆分导致维护复杂;
- 核心是“按数据加工程度划分”:从ODS到ADS,数据粒度逐渐变粗、加工程度逐渐加深,避免层级混淆(如DWD层不做聚合,DWS层不存明细)。
2. 分层有没有什么坏处
考察知识点
- 分层带来的额外成本(开发、存储、链路复杂度)
- 分层对新手友好度、实时性的影响
- 分层设计不当的风险(过度设计、层级冗余)
参考回答
数仓分层虽有显著优势,但也存在三大固有坏处,需通过合理设计规避:
- 开发与维护成本增加:分层需设计各层表结构、编写ETL脚本、维护调度依赖(如DWS层依赖DWM层完成)。例如,一个简单的“日销售额报表”,需开发ODS同步、DWD清洗、DWS聚合3套脚本,开发工作量比“单表直接统计”增加2-3倍,且需专人维护分层文档(表结构、字段含义)。
- 存储冗余与资源消耗:各层数据独立存储,存在一定冗余。例如,DWD层的订单明细与DWS层的订单汇总表均存储“订单金额”字段,总存储量比“单表”增加30%-50%;同时,多层ETL任务(如DWD→DWM→DWS)会占用更多集群CPU/内存资源,尤其在数据量达TB级时,资源消耗显著。
- 链路变长影响实时性:分层链路(如ODS→DWD→DWM→ADS)比“单表直接输出”多2-3个加工环节,数据从产生到应用的延迟增加。例如,实时报表需求(T+0.5)下,分层链路可能导致报表生成延迟超1小时,需通过“减少非必要层级”(如跳过DWM层)优化。
- 新手学习成本高:新人需理解各层定位、字段流转逻辑(如某字段从ODS到DWS的加工规则),才能正确使用数据。例如,新人可能误将DWD层的“原始订单量”当作DWS层的“有效订单量”,导致分析错误。
补充注意要点
- 规避策略:通过“标准化分层模板”(如固定ODS/DWD/DWS/ADS四层)降低设计复杂度;用“分区表+生命周期管理”(如ODS层数据保留30天)减少存储冗余;
- 权衡场景:实时场景(如实时监控看板)可简化分层(ODS→DWS→ADS),牺牲部分复用性换取低延迟。
3. 看板加载时长缩短做了什么
考察知识点
- 看板加载慢的核心瓶颈(SQL效率、数据量、存储格式)
- 优化手段与大数据技术的结合(中间层、索引、存储)
- 优化效果的量化逻辑(加载时间、资源消耗)
参考回答
看板加载慢的核心瓶颈是“查询数据量过大”“SQL逻辑复杂”“存储格式低效”,通过四大手段可将加载时长从分钟级缩短至秒级:
- 基于中间层预聚合,减少查询计算量:将看板高频使用的指标(如“日活”“销售额”)在DWS层预聚合,避免直接查询DWD层明细数据。例如,原看板直接扫描DWD层1亿条用户行为日志计算“日活”(耗时5分钟),改为查询DWS层预计算的“日活汇总表”(仅10万条数据),加载时间缩短至10秒。
- 优化SQL逻辑与索引:
- 避免全表扫描:添加分区过滤(如
WHERE dt='20240901'
)、字段裁剪(仅查必要字段,不写SELECT *
); - 优化算子:用
approx_count_distinct
替代count(distinct)
(允许1%误差时,效率提升10倍),用JOIN
替代子查询
; - 加索引:ClickHouse/Doris等引擎为看板常用筛选字段(如
user_id
“date
”)建一级索引,查询扫描数据量减少80%。
- 避免全表扫描:添加分区过滤(如
- 优化存储格式与压缩:将看板依赖的表从Text/CSV转为ORC/Parquet列存格式(支持列裁剪、压缩),并启用Snappy压缩。例如,DWS层销售表用ORC+Snappy后,存储量减少70%,查询时仅需加载“销售额”“日期”等必要列,IO时间从30秒缩短至5秒。
- 升级查询引擎与资源配置:
- 替换引擎:将基于Hive的看板迁移至ClickHouse(列存+向量计算),复杂聚合查询速度提升5-10倍;
- 增加资源:为看板查询任务分配独立队列(如20个Executor、8G内存),避免与其他任务争抢资源,高峰期加载时间从2分钟稳定在20秒内。
补充注意要点
- 优先“减少数据量”:预聚合(DWS层)和过滤(分区/字段裁剪)是最有效的优化手段,比单纯升级硬件更经济;
- 避免“过度优化”:非核心看板(如周度报表)无需追求秒级加载,避免消耗过多资源。
4. 数据治理只是涉及过下线表吗
考察知识点
- 数据治理的完整范畴(不止表下线,含质量、规范、安全等)
- 表下线在治理中的定位(“清理冗余”的子集)
- 数据治理的核心目标与实战场景
参考回答
数据治理是“全生命周期管理数据资产”的体系,表下线仅为“数据清理”环节的极小部分,完整治理包含四大核心模块:
- 数据质量治理:通过DQC(数据质量控制)工具监控数据“准确性、完整性、一致性”。例如,监控DWD层订单表“
order_id
非空率≥99.9%”“pay_time
≥create_time
”,异常时触发告警并自动修复(如补全缺失的order_id
),数据准确率从85%提升至99.9%。 - 数据规范治理:统一数仓“表命名、字段命名、数据类型”标准。例如,规定表名格式为“
层级_业务域_表用途_粒度
”(如dws_trade_sales_day
,即DWS层交易域销售日表),字段类型统一(日期用datetime
,金额用decimal(10,2)
),避免“同一名词不同字段名”(如“用户ID”同时存在user_id
和uid
),新人上手效率提升50%。 - 数据安全治理:分级分类敏感数据,控制访问权限。例如,将用户表按“敏感级别”分为三级:一级(身份证/银行卡)仅管理员可查,二级(手机号/地址)需申请权限,三级(用户名/性别)公开访问;同时对一级数据加密存储(如AES加密),防止泄露。
- 数据生命周期治理:包含“表下线”但不限于:
- 表下线:清理长期(如1年以上)未使用的冗余表(如测试表、废弃报表的ADS表),释放存储(下线表占比达20%,释放存储300GB);
- 数据归档:将ODS层超3个月的原始日志归档至低成本存储(如S3归档层),查询时按需恢复,存储成本降低40%;
- 冷数据删除:DWS层超1年的历史汇总数据(如2022年销售额),经业务确认后删除,减少集群负载。
补充注意要点
- 表下线需“谨慎验证”:下线前需确认近3个月无查询记录(通过Hive/Spark日志排查),并通知相关业务方,避免误删在用表;
- 治理核心是“提升数据价值”:通过规范、质量、安全治理,让数据从“可用”变为“可信”,支撑业务决策(如治理后,业务方用数信心从60%提升至95%)。
5. 数据倾斜讲讲
考察知识点
- 数据倾斜的定义与核心现象(Task负载不均)
- 倾斜的常见原因(热点Key、空值、类型不匹配)
- 针对性解决方案与实战示例
参考回答
数据倾斜是大数据计算(Spark/Flink)中“某几个Task处理数据量远超其他Task”的现象,导致作业执行时间被拉长(长尾Task耗时是普通Task的5-10倍),甚至OOM报错。
(1)核心现象与识别
- 现象:Spark UI中,某Task的“Shuffle Read”数据量达10GB,其他Task仅100MB;或某Task执行时间超2小时,其他Task仅10分钟。
- 识别工具:Spark UI(Stage→Tasks→Shuffle Read Size)、Flink UI(Subtask→Records Processed)。
(2)常见原因
- 热点Key:某Key对应数据量过大(如“双11”期间,某爆款商品
goods_id=1001
的订单占比达15%),所有该Key数据分配到同一Task。 - 空值Key:大量数据的Join/Group By Key为null(如
user_id IS NULL
的订单占比10%),所有空值被分配到同一Task。 - 数据类型不匹配:Join Key类型不一致(如左表
user_id
为String,右表为Int),导致Hash值计算异常,某Task堆积数据。 - 算子不当:使用
groupByKey
(无Map端预聚合)替代reduceByKey
,或count(distinct)
处理高基数字段(如count(distinct user_id)
),导致数据集中。
(3)解决方案(Spark示例)
原因 | 方案 | 示例(SQL/代码) |
---|---|---|
热点Key | Key加盐+二次聚合 | 对热点Key加随机前缀(如1001_0 -1001_9 ),拆分后聚合,再合并结果。 |
空值Key | 过滤空值/空值加盐 | 无业务意义的空值直接过滤(WHERE user_id IS NOT NULL );需保留则加随机后缀(NULL_0 -NULL_9 )。 |
类型不匹配 | 统一数据类型 | LEFT JOIN ON a.user_id = CAST(b.user_id AS STRING) |
算子不当 | 替换高效算子 | 用reduceByKey 替代groupByKey ,用approx_count_distinct 替代count(distinct) 。 |
补充注意要点
- 优先“预防”:设计表时避免热点Key(如用户行为日志按“用户ID%100”分桶);
- 避免“过度优化”:若长尾Task耗时在可接受范围(如总作业30分钟,长尾Task5分钟),无需处理,避免增加代码复杂度。
6. 大表与大表join的数据倾斜——分桶
考察知识点
- 分桶Join解决大表Join倾斜的原理(预分区+局部Join)
- 分桶的核心配置(分桶字段、分桶数)
- 分桶Join与普通Shuffle Join的效率差异
参考回答
当两个大表(均超10GB)Join出现倾斜时,分桶Join通过“预分区+局部Join”解决问题,核心逻辑是:
- 预分桶:对两个大表(A表:订单表,B表:用户表)按相同Join Key(
user_id
)和分桶数(如100)分桶,确保相同user_id
始终进入同一分桶(bucket_id = Hash(user_id) % 100
)。 - 局部Join:Join时仅需对“相同分桶”内的数据进行局部Join(如A表桶0仅与B表桶0 Join,A表桶1仅与B表桶1 Join),无需跨分桶传输数据。
(1)解决倾斜的核心逻辑
- 均匀分配数据:通过合理分桶数(如100),将热点Key分散到多个分桶。例如,
user_id=10086
(热点Key)的数据被分配到桶8,仅占该桶数据的1%(而非普通Shuffle的15%),单个Task处理数据量从10GB降至100MB。 - 减少Shuffle数据量:普通Shuffle Join需传输两表全量数据(20GB),分桶Join仅需传输分桶内数据(每桶200MB,总20GB,但避免跨节点传输),Shuffle耗时减少60%以上。
(2)落地步骤(Hive示例)
- 插入数据:需开启分桶插入(
set hive.enforce.bucketing=true
),确保数据按分桶规则写入。
This post is for subscribers on the 网站会员 and 成为小万的高级会员 tiers only
Subscribe NowAlready have an account? Sign In