datawarehouse相关
Created|Updated|工程实践
|Word Count:0|Reading Time:1mins|Post Views:
Author: magicliang
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles
2026-07-13
数据源 API 与谓词下推:让存储层帮忙过滤
上一篇解决了 AQE 的运行时优化。这一篇进入数据源层——Spark 如何把计算推到存储层执行。 查询优化不只发生在执行引擎内部。如果存储层能在读取数据时就过滤掉不需要的行和列,引擎需要处理的数据量会大幅减少。Spark 通过 DataSource API 和 Catalyst 的优化规则把这个能力标准化了:谓词下推(Predicate Pushdown)让存储层只返回满足条件的行,列裁剪(Column Pruning)让存储层只返回查询需要的列。 本文只抓一个问题:谓词下推和列裁剪如何从 Catalyst 的逻辑计划传递到数据源实现。 DataSource API 的两代演进 Spark 的数据源 API 经历了两代: 12345678910DataSource V1 (Spark 1.3+): 接口: InputFormat / OutputFormat + createRelation 谓词下推: 通过 PrunedFilteredScan trait 可选实现 局限: 批与流使用不同接口,能力与优化协商较分散DataSource V2 (Spark 2.3+, 重构...
2026-07-13
Adaptive Query Execution:运行时改写执行计划
上一篇解决了 DataFrame 和 Dataset 的 API 演进。这一篇进入运行时优化——Adaptive Query Execution(AQE)。 传统查询优化器的一个根本问题是:优化发生在执行之前,依赖的统计信息可能不准确或完全缺失。AQE 把优化推迟到执行过程中——在每个 Shuffle 边界,收集实际的数据统计信息,然后用这些精确的统计重新优化后续 Stage 的执行计划。 本文只抓一个问题:AQE 的三个核心优化分别解决什么问题,以及运行时优化的反馈循环如何工作。 图 1:AQE 使用已物化统计调整后续读取与 Join flowchart TB P[初始物理计划] --> S[执行 Exchange 并物化数据] S --> M[实际分区大小与行数统计] M --> C[合并小分区] M --> J[调整适用的 Join 策略] M --> K[拆分符合条件的倾斜分区] C --> R[后续 Task 读取] J --> R K --> R 图 1 的优化发生在已有物化结果之上。已经...
2025-07-29
经典面试问题的大数据解法——Spark 与 Flink 实战
“100 亿个数中找出最大的 1000 个”、“两个 10GB 的文件找出共同的 URL”——这些经典面试题的本质都是内存放不下。单机方案围绕分治展开,分布式方案则把分治思想映射到集群节点上。本文按问题类型组织,每类问题给出从单机到 Spark/Flink 的渐进式解法,并附上概率数据结构(布隆过滤器、HyperLogLog、Count-Min Sketch)在近似场景中的应用。 引言:大数据问题的共同特征 为什么"内存放不下" 面试中给出的数据规模往往是精心设计的——刚好跨过单机内存的边界: 数据规模 内存需求 典型服务器内存 能否放入内存 1 亿个 int 400 MB 16 GB ✅ 10 亿个 int 4 GB 16 GB ✅(但留给程序的余量不多) 100 亿个 int 40 GB 16 GB ❌ 10 亿个 URL(平均 100 字节) 100 GB 16 GB ❌ 上表只计算了裸数据大小。实际使用 HashMap、HashSet 等容器时,对象头、指针、负载因子会使内存占用膨胀 3-5 倍。 通用解题框架 123...
2026-07-13
内存管理与 Tungsten:堆外内存、序列化与代码生成
上一篇解决了 Shuffle 的物理机制。这一篇进入内存管理——Spark 如何突破 JVM 的内存瓶颈。 Spark 是一个 JVM 应用,天然受制于 Java 的内存模型:对象头开销大、GC 停顿不可控、序列化效率低。Project Tungsten 是 Spark 为解决这三个问题发起的底层优化计划,它从三条线同时推进——堆外内存管理、二进制数据格式、全阶段代码生成。 本文只抓一个问题:Tungsten 的三条优化线分别解决了什么问题,以及 Spark 的统一内存管理模型如何在执行内存和存储内存之间做动态调配。 下图展示了 Executor 的统一内存管理模型——Execution Memory 和 Storage Memory 之间的动态借用机制: Java 对象的内存开销 一个 Java 字符串 “abcd” 在堆内占多少字节? 12345678910111213java.lang.String 对象: 对象头: 12 bytes (64-bit JVM, 压缩指针) hash: 4 bytes (int) value[]: 4 bytes ...
2026-07-13
水位线与状态管理:流处理的时间语义
上一篇解决了 Structured Streaming 的基本模型。这一篇进入时间语义——事件时间、水位线和状态管理。 流处理中的"时间"不是一个简单的概念。一条消息有两个时间戳:事件时间(Event Time,事件实际发生的时间)和处理时间(Processing Time,Spark 收到消息的时间)。两者可能差距很大——网络延迟、消费积压、跨时区传输都会导致消息乱序到达。 本文只抓一个问题:Watermark 如何告诉 Spark “多晚的数据还值得等”,以及 State Store 如何持久化窗口状态。 事件时间 vs 处理时间 123456789101112事件发生 网络传输 Spark 收到 t=10:00:01 ~~~延迟 3s~~~ t=10:00:04 (Processing Time) t=10:00:02 ~~~延迟 1s~~~ t=10:00:03 t=10:00:03 ~~~延迟 8s...
2026-07-13
Structured Streaming:把流当成无界表
上一篇解决了数据源 API 和谓词下推。这一篇进入流处理——Structured Streaming。 Spark 的流处理经历了两代:DStream(基于 RDD 的离散化流)和 Structured Streaming(基于 DataFrame/Dataset 的结构化流)。DStream 已经停止演进,Structured Streaming 是当前唯一推荐的流处理 API。 Structured Streaming 的核心模型可以用一句话概括:把流数据看成一张不断追加新行的无界表,复用 Spark SQL 的 Catalyst 优化器和 Tungsten 执行引擎来处理。 本文只抓一个问题:无界表模型如何工作,以及 MicroBatch 执行引擎如何把连续的流切成离散的批次。 无界表模型 12345678传统流处理的心智模型: 消息 → 处理函数 → 输出 (一条一条处理,每条消息触发一次计算)Structured Streaming 的心智模型: 数据源不断追加行到一张"输入表" 查询在整张表上持续运行 结果写入一张"输出表&qu...
Announcement
人生只是,守株待兔









