想象一家大型自助餐厅的后厨:角落里有一个巨大的冷藏库,所有食材不论贵贱都能囤放,这是“数据湖”;紧挨着灶台的备菜台,只摆放洗净切好、贴好标签的半成品,这是“数据仓库”。所谓“湖仓一体”,就是给冷藏库装上温控系统、玻璃门和标签管理,让备菜台与冷库真正打通。而 Trino、Spark SQL、Photon 三位“掌勺厨师”,各自用不同的策略为你把数据做成一道道菜——有的跑得快擅长小炒,有的耐得住性子炖大菜,有的握着高科技锅铲又快又好。这篇文章就带你走进这间后厨,看清三位厨师的真功夫,学会按需点单。

岗位关联

理解三大湖仓查询引擎的架构差异与性能边界,能让你在真实业务中做出更省钱的选型决策,也能在与数据平台团队协作时说到点子上。

目录
  1. 可视化演示
  2. 湖仓一体基础
  3. 引擎架构对比
  4. Trino 引擎
  5. Spark 引擎
  6. Photon 引擎
  7. 性能基准对比
  8. 优化策略
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态展示Trino流水线/Spark DAG/Photon向量化三种执行模型下SQL查询从coordinator经多stage到结果的数据流路径,切换引擎观察延迟与吞吐差异。

本节配有交互动效(进入视口后自动加载,约 3KB)。

湖仓一体基础

想象一家大型自助餐厅的后厨:角落里的巨型冷藏库可以囤放任何食材,不管是整扇猪肉还是没拆箱的冻虾,这是“数据湖”——存储便宜、格式随意,但想直接用它做菜就费劲了;而灶台边整齐的备菜台只放洗净切好、贴着标签的半成品,这是“数据仓库”——做菜快,但把每样食材都精细加工的成本很高。所谓“湖仓一体”(Lakehouse),就是给冷藏库装上玻璃门、温控和标签系统,让备菜台和冷库真正打通:既享受冷库的低成本,又拥有备菜台的秩序。

在真实的大数据世界,数据湖通常指基于 S3、OSS 等廉价对象存储,存放 Parquet、ORC 等原始文件,灵活但缺少约束;数据仓库则用严格 Schema 和治理流程保证数据质量,查询高效但建设周期长、成本高。湖仓一体架构在这两者之间取了平衡:在廉价存储之上叠加事务(ACID)、Schema 强制、索引与元数据管理,典型技术包括 Delta Lake、Iceberg、Hudi 等开放表格式。而无论哪种架构,真正把数据“端上桌”的是查询引擎——它们的角色就像后厨里的厨师,负责把食材变成菜品。

理解湖仓的存储与计算分离模式,可以从总体成本模型入手:

湖仓一体的精髓,就是像给冷库装上直达备菜台的传送带一样,让数据不必反复装卸。理解了这一点,后面三位厨师的功夫高低,就有了评判的场地。

Ctotal=Cstorage+Ccompute+Cnetwork\displaystyle C_{\text{total}} = C_{\text{storage}} + C_{\text{compute}} + C_{\text{network}}
  1. 总成本\( C_{\text{total}} \) 是湖仓架构的整体拥有成本,决定技术选型的预算边界。
    CtotalC_{\text{total}}
  2. 存储成本\( C_{\text{storage}} \) 是数据存放的费用,数据湖用廉价对象存储把这个数字压得很低。
    CstorageC_{\text{storage}}
  3. 计算成本\( C_{\text{compute}} \) 是查询引擎执行 SQL 所消耗的 CPU 与内存费用。
    CcomputeC_{\text{compute}}
  4. 网络成本\( C_{\text{network}} \) 是数据跨系统搬移的开销,湖仓一体通过计算下推减少“搬运”。
    CnetworkC_{\text{network}}

引擎架构对比

后厨里有三位风格迥异的厨师长:跑单小哥(Trino)接到订单就冲向冷库,脚步飞快但怀里抱不了太多食材;中央厨房团队(Spark SQL)喜欢先让帮工把成吨食材分批处理成半成品,再统一开火;特级厨师(Photon)握着高科技厨具,做起菜又快又好。三位在处理同一份订单时,策略、成本与瓶颈完全不同。

这种差异来自底层架构。Trino 采用 MPP(大规模并行处理)无状态架构:一个 Coordinator 负责解析 SQL、生成执行计划并调度任务,多个 Worker 并行执行、互不共享状态,就像一群跑单小哥各自独立取货。Spark SQL 采用 Driver + Executor 的弹性分布式架构:Driver 编排 DAG(有向无环图,把计算拆成有依赖关系的阶段),Executor 执行具体任务,阶段之间通过 Shuffle 交换中间数据,就像中央厨房里各操作台之间传递半成品。Photon 则是 Databricks 用 C++ 重写的 Spark 执行引擎,不改变 Spark 的调度模型,只把最底层的运算算子换成向量化版本,相当于给中央厨房换了一套高速厨具。

并行系统有一个经典定律——Amdahl 定律,它解释了为什么加机器不能无限提速:

就像炒菜时切配可以几十人分工,但颠锅只能一个人来。引擎再能加机器,调度那一瞬间的“颠锅”依然省不掉。理解了架构差异,接下来就能看懂三位厨师各自的拿手菜和软肋。

S(p)=1(1−f)+fp\displaystyle S(p) = \frac{1}{(1-f) + \frac{f}{p}}
  1. 加速比\( S(p) \) 是使用 \( p \) 个并行节点后相对单节点的提速倍数。
    S(p)S(p)
  2. 串行部分\( 1-f \) 是任务中不可并行的比例,如任务调度、结果合并,它决定了性能天花板。
    1−f1-f
  3. 并行部分\( f \) 是能被多个节点共同分担的比例,节点越多这部分耗时越低。
    ff
  4. 极限洞察当 \( p \to \infty \) 时,加速比趋近 \( 1/(1-f) \),串行比例成了永远迈不过去的坎。
    lim⁡p→∞S(p)=11−f\lim_{p \to \infty} S(p) = \frac{1}{1-f}

Trino 引擎

Trino 的化身是跑单小哥:你点一份“番茄炒蛋”,他箭步冲向冷库,抓来番茄和鸡蛋,三分钟上桌。但如果你点的是“满汉全席”——几十张大表 Join 的复杂查询——他怀里抱不下那么多食材,跑到一半东西撒了,只好空手而归。

Trino(源自 Presto 项目)是专为交互式查询设计的分布式 SQL 引擎。它的协调器(Coordinator)是无状态的,可以轻松横向扩展和故障恢复;Worker 则负责执行并行任务。它最亮眼的看家本领是联邦查询:一条 SQL 可以同时查询 MySQL、Hive、Iceberg、Elasticsearch 等多个数据源,就像跑单小哥能跑遍园区里所有仓库取货。这使得 Trino 成为湖仓架构中“即席分析”和“跨源关联”的首选。

Trino 的查询延迟由多个环节叠加而成,定位性能瓶颈时可以逐项拆解:

Trino 的短板在于:数据基本常驻内存处理,一旦聚合或排序的中间结果超过所有 Worker 的内存总和,查询就会报 OOM(内存溢出)错误。新版虽然支持溢写到磁盘,但默认关闭且性能远不如内存路径。所以,跑单小哥最懂“快”的哲学,也最怕“大”的订单。

Tquery=Tplan+Tschedule+Tio+Tcpu\displaystyle T_{\text{query}} = T_{\text{plan}} + T_{\text{schedule}} + T_{\text{io}} + T_{\text{cpu}}
  1. 总查询延迟\( T_{\text{query}} \) 是用户从提交 SQL 到看到结果的墙钟时间,是体验的直接指标。
    TqueryT_{\text{query}}
  2. 解析规划\( T_{\text{plan}} \) 是 SQL 解析和优化器制定执行计划的时间,通常在毫秒级。
    TplanT_{\text{plan}}
  3. 任务调度\( T_{\text{schedule}} \) 是 Coordinator 把拆分好的任务分发到各 Worker 的耗时。
    TscheduleT_{\text{schedule}}
  4. 数据读取\( T_{\text{io}} \) 是从远端存储读取数据的时间,大表扫描时往往是主要瓶颈。
    TioT_{\text{io}}
  5. 计算执行\( T_{\text{cpu}} \) 是过滤、聚合、Join 等 CPU 运算时间,取决于数据规模和算子效率。
    TcpuT_{\text{cpu}}

Spark 引擎

中央厨房团队的行事风格是“兵马未动,粮草先行”:凌晨先把几百公斤食材统一清洗、切配、分装,然后才轮到各灶台开火。所以它接小单反而有点慢,接大单却稳如泰山——这就是 Spark SQL 的性格画像。

Spark SQL 是 Apache Spark 面向 SQL 的入口,核心由 Catalyst 优化器和 Tungsten 执行引擎组成。Driver 把 SQL 解析成逻辑计划,经过优化后生成物理计划,再切分成多个 Stage;每个 Stage 内的任务由集群中的 Executor 并行执行,Stage 之间通过 Shuffle 跨节点交换中间数据。这个模型天然适合批量 ETL(数据清洗转换加载):读出海量数据,过滤、聚合、写出,一气呵成。

Spark 在“大”字面前非常从容——内存不够可以溢写磁盘,任务失败会自动重试。但这也让“小”查询显得不划算:Driver 启动、Stage 调度、Shuffle 洗牌都有固定开销。Shuffle 是理解 Spark 性能的关键所在,它的成本模型非常直观:

中央厨房的菜要在各操作台之间来回传递,传递的食材越多越慢。聪明的厨师会先把食材在小推车上合并(预聚合),再一次性送达。这就是为什么 Spark 工程师们总在 Shuffle 上做文章——省下的搬运时间,就是省下的真金白银。

Tshuffle=VB\displaystyle T_{\text{shuffle}} = \frac{V}{B}
  1. Shuffle 时间\( T_{\text{shuffle}} \) 是聚合或 Join 时跨节点搬运中间数据的总耗时。
    TshuffleT_{\text{shuffle}}
  2. 数据规模\( V \) 是参与搬运的数据量,与分区键分布和算子预处理程度直接相关。
    VV
  3. 传输带宽\( B \) 是集群网络聚合带宽,千兆或万兆网卡决定了搬运速度的上限。
    BB
  4. 优化启示要降低 Shuffle 时间,最有效的杠杆是减小 \( V \)——提前过滤、预聚合、广播小表都能显著瘦身。
    V↓⇒Tshuffle↓V \downarrow \Rightarrow T_{\text{shuffle}} \downarrow

Photon 引擎

特级厨师 C 师傅的秘诀不在手艺,而在装备:他手里的“多头锅铲”一次能同时兜起八块肉,砧板自带分类格,火候由温度计实时调节。同一道菜,别人忙活三分钟,他五十秒出锅。

Photon 是 Databricks 于 2022 年发布的向量化执行引擎,用 C++ 重写了 Spark 执行层的核心算子。它不改变 Spark 的 API 和调度模型,而是让底层运算从“逐行解释执行”变成“按批次向量计算”,并对 CPU 缓存、指令级并行做了极致的优化。用户只需在 Databricks 集群上打开 Photon 开关,原有的 Spark SQL 就能自动加速,就像给中央厨房免费换了一套进口厨具。

向量化执行的核心是 SIMD(单指令多数据)——一条 CPU 指令同时处理多个数据元素,而不是一次只处理一个。加速比的理论模型如下:

需要注意的是,Photon 只运行在 Databricks 平台,主要对 Delta Lake 上的数据加速;一旦遇到自定义 UDF(用户自定义函数),它会从向量模式退回行模式,加速效果大打折扣。特级厨师再厉害,也依赖自家厨房和熟悉的食材供应链——换到陌生灶台,他的“多头锅铲”就施展不开了。

Speedup=TscalarTvector≤SIMD_width\displaystyle \text{Speedup} = \frac{T_{\text{scalar}}}{T_{\text{vector}}} \leq \text{SIMD\_width}
  1. 标量耗时\( T_{\text{scalar}} \) 是逐行解释执行的时间,每条数据都要经历指令解析和跳转。
    TscalarT_{\text{scalar}}
  2. 向量耗时\( T_{\text{vector}} \) 是按批次批量计算的耗时,一次处理成百上千行数据。
    TvectorT_{\text{vector}}
  3. 理论上限\( \text{SIMD\_width} \) 是一条 CPU 指令同时处理的数据元素个数,如 AVX2 指令集对应 8 个 32 位整数。
    SIMD_width\text{SIMD\_width}
  4. 现实折扣内存带宽、分支预测、UDF 回退都会拉低实际加速比,工程上常见 1.8 倍到 8 倍。
    1.8≤Speedup≤81.8 \leq \text{Speedup} \leq 8

性能基准对比

大赛评委端来同一桌菜谱,要求三位厨师分别做出一整桌宴席,记录总时间和每道菜用时。结果发现:跑单小哥做凉菜快得惊人,但遇到需要慢火炖的大菜直接掀桌;中央厨房每道菜都四平八稳,总时长中规中矩;特级厨师做凉菜热菜都最快。

在数据领域,这套“宴席标准”就是 TPC-DS 基准测试——一套模拟真实决策支持负载的 99 条复杂 SQL,涵盖多表 Join、子查询、窗口函数等场景。评估引擎综合实力时,业界不用算术平均,因为少数慢查询会严重拉偏总分;更公平的做法是几何平均,它让每条查询都有平等的“投票权”:

工程实践的画像大致如下:交互式小查询(几秒内)中,Trino 与 Photon 接近,都明显快于原生 Spark;大规模批处理 ETL 中,Spark 和 Photon 的吞吐更高,Trino 容易内存不足;Photon 在 Delta Lake 上综合领先。成本层面,Photon 通过减少集群节点数压低账单,但软件许可与平台绑定必须计入总成本。选厨师不能只看“哪道菜最快”,要看你的宴席是什么风格——凉菜多选跑单小哥,包席量大选中央厨房,追求极致出餐效率且食材标准统一,选特级厨师。

GM=(∏i=1nQi)1/n=exp⁡(1n∑i=1nln⁡Qi)\displaystyle GM = \left( \prod_{i=1}^{n} Q_i \right)^{1/n} = \exp\left( \frac{1}{n} \sum_{i=1}^{n} \ln Q_i \right)
  1. 查询样本\( Q_i \) 是第 \( i \) 条查询的执行时间,代表一个具体业务场景的响应速度。
    QiQ_i
  2. 几何平均\( GM \) 是 n 个耗时乘积的 n 次方根,任何一条慢查询都会被计入,但不会被极端值绑架。
    GM=(∏i=1nQi)1/nGM = \left( \prod_{i=1}^{n} Q_i \right)^{1/n}
  3. 对数等价\( \exp \) 与 \( \ln \) 的写法便于程序稳定计算,避免连乘溢出。
    GM=exp⁡(1n∑i=1nln⁡Qi)GM = \exp\left( \frac{1}{n} \sum_{i=1}^{n} \ln Q_i \right)
  4. 对比含义对同样的 SQL 集合,\( GM \) 越小,引擎整体性能越强。

优化策略

无论是哪支厨师团队,好的后厨管理都有共通法则:把食材按类型分格存放、把用不上的边角料提前处理掉、减少操作台之间来回跑动。这些“后厨管理术”对应着大数据领域的经典优化手段,而且往往比换一个引擎更立竿见影。

查询慢常常不是引擎不行,而是数据布局太乱。最有效的三板斧:分区裁剪、谓词下推、数据布局排序。分区裁剪让引擎只读必要的分区,省掉大量无谓扫描。它的收益可以用一个简单的比例衡量:

除了分区,谓词下推把 WHERE 过滤条件下沉到 Parquet/ORC 读取层,直接跳过无关行组;Z-Order 排序让相似数据在文件内聚簇,配合列存统计信息实现跳跃读取;小文件治理则把大量几 MB 的碎片文件合并成 128MB 以上的大文件,减轻元数据压力与任务调度开销。冷库里每个货架都分好类、贴好标签,厨师报出菜名,帮工直奔对应货架端来食材——这就是分区与下推的智慧;把零碎香料合并成标准调料罐,就是小文件治理。

Scan_ratio=Scan_partitionsTotal_partitions\displaystyle \text{Scan\_ratio} = \frac{\text{Scan\_partitions}}{\text{Total\_partitions}}
  1. 有效扫描比\( \text{Scan\_ratio} \) 是实际读取的数据量占全表数据的比例。
    Scan_ratio\text{Scan\_ratio}
  2. 命中分区\( \text{Scan\_partitions} \) 是经过 WHERE 条件过滤后仍需读取的分区数量。
    Scan_partitions\text{Scan\_partitions}
  3. 总分区数\( \text{Total\_partitions} \) 是整张表划分的全部分区数量。
    Total_partitions\text{Total\_partitions}
  4. 收敛效果按日期分区后查询“昨天”的数据,只需读取 1/365 的分区,扫描比例降到 0.3% 左右。
    Scan_ratio≈1365≈0.3%\text{Scan\_ratio} \approx \frac{1}{365} \approx 0.3\%

AI 应用场景

场景一:跨源实时 BI 报表(Trino)

阶段:数据探索与交互式分析

解决的问题:业务分析师既要查 MySQL 订单表,又要查数据湖中的行为日志。传统做法是先定时同步到数仓再出报表,数据延迟高,且需要维护两套连接。Trino 作为“跑单小哥”,一条 SQL 即可联邦查询多个数据源,实现秒级响应。

具体案例:某跨境电商团队用 Trino 连接 RDS 交易库与 Iceberg 湖,实时看板“今日 GMV 与用户活跃”直接从两个源 Join,报表从 T+1 延迟缩短到秒级,分析师自助取数不再排队。

场景二:离线批量特征管道(Spark SQL)

阶段:数据加工与批处理

解决的问题:ODS 层每天新增数百 GB 原始日志,需要清洗、去重、打宽表后供特征工程使用。交互式引擎扛不住这种吞吐压力,Spark SQL 作为“中央厨房”,通过分布式批处理和容错机制稳定扛下大规模任务。

具体案例:某推荐系统团队每天凌晨用 Spark SQL 运行特征管道:读取 Kafka 落地的行为日志,做 Session 切分、统计特征聚合,写回 Delta 表,供白天的模型训练与在线查询使用。

场景三:Delta 湖上查询提速(Photon)

阶段:查询加速与性能优化

解决的问题:BI 查询在 Delta 表上耗时 30 秒以上,加节点扩容成本高。开启 Photon 后无需修改任何 SQL,向量化执行引擎自动接管运算,显著降低延迟与集群资源消耗。

具体案例:某 SaaS 公司用 Databricks 跑月度经营分析,开启 Photon 后复杂报表平均提速 3.5 倍,集群从 20 台缩减到 12 台,季度账单下降 40%。

Python 演示

python41 行
import math  class Engine:    def __init__(self, name, fixed_sec, per_gb_sec, mem_limit_gb):        self.name = name        self.fixed_sec = fixed_sec        self.per_gb_sec = per_gb_sec        self.mem_limit_gb = mem_limit_gb     def query_time(self, data_gb):        if data_gb > self.mem_limit_gb:            return None  # OOM 内存不足 查询失败        return self.fixed_sec + self.per_gb_sec * data_gb  def geomean(times):    logs = [math.log(t) for t in times if t is not None]    return math.exp(sum(logs) / len(logs))  engines = [    Engine("Trino", fixed_sec=0.5, per_gb_sec=1.0, mem_limit_gb=50),    Engine("SparkSQL", fixed_sec=5.0, per_gb_sec=0.4, mem_limit_gb=200),    Engine("Photon", fixed_sec=2.0, per_gb_sec=0.15, mem_limit_gb=200),] sizes = [10, 20, 40, 80, 160]for e in engines:    times = []    for s in sizes:        t = e.query_time(s)        if t is None:            times.append(999)            print(f"{e.name}: {s}GB 查询失败 OOM")        else:            times.append(t)            print(f"{e.name}: {s}GB -> {t:.1f}s")    gm = geomean(times)    print(f"{e.name}: 几何平均 {gm:.2f}s")    print()
目的:用一个小型模拟器对比 Trino、SparkSQL、Photon 三个引擎在递增数据量下的耗时表现,并用几何平均给出综合性能排名,直观复现正文中的性能对比逻辑。
  1. class Engine:用一个类抽象三种查询引擎,参数差异代表引擎的架构特点。
  2. if data_gb > self.mem_limit_gb: return None模拟内存超限时查询失败,对应 Trino 大查询的 OOM 风险。
  3. return self.fixed_sec + self.per_gb_sec * data_gb耗时模型:固定开销加随数据量线性增长的部分。
  4. Engine("Trino", fixed_sec=0.5, per_gb_sec=1.0, mem_limit_gb=50)Trino 启动快但单 GB 成本高、内存上限小。
  5. logs = [math.log(t) for t in times if t is not None]对耗时取对数,为几何平均做准备,失败查询记为大值。

常见误区

误区听说 Trino 是秒级响应,那把 ETL 和报表都换成 Trino 跑,是不是就能彻底告别慢查询了?

正解Trino 的“快”指的是交互式小查询场景。它把数据拉进内存计算,大表 Join 时容易内存溢出;Spark 通过溢写磁盘和任务重试把超大任务稳稳扛住。选引擎要看负载类型,跑单小哥再快也接不了满汉全席。

为何常见:人们习惯用“响应快”这一个维度衡量引擎,忽略了数据规模、稳定性和容错能力等关键因素。

误区Photon 听起来和 Presto 一样是个独立引擎,是不是可以单独下载部署,接上自己的数据就能用?

正解Photon 不是独立引擎,而是 Databricks 平台内 Spark 执行层的向量化加速组件。它必须运行在 Databricks 环境并配合 Delta Lake 才能发挥最大价值,无法脱离平台单独使用。

为何常见:厂商宣传总强调“提速 N 倍”,容易让人误以为它是一个可以随处插拔的独立产品。

误区我把数据都放到 S3 上用 Parquet 格式存储,这不就是湖仓一体了吗?

正解只有文件格式远远不够。湖仓一体还需要 ACID 事务、Schema 强制、索引和元数据管理等能力,这些由 Delta Lake、Iceberg、Hudi 等表格式提供。否则只是“数据沼泽”,连改个文件名都可能破坏数据一致性。

为何常见:概念走红后,很多人把“数据湖”和“湖仓一体”画上等号,忽略了中间那一层关键的表格式治理能力。

误区Photon 官方 Demo 里查询提速好几倍,那我打开开关,所有 Spark SQL 是不是都能享受同等加速?

正解Photon 对扫描、过滤、聚合、Join 等标准算子提升明显,但遇到自定义 UDF 或特殊表达式时会退回行模式,甚至出现性能回退。实际加速比通常在 1.8 到 8 倍之间,具体取决于工作负载是否“吃”向量化。

为何常见:Demo 展示的都是最理想的场景,用户误把上限当成平均值。

误区我的 Spark SQL 跑得很慢,是不是换个更快的新引擎就能彻底解决?

正解很多时候瓶颈来自数据倾斜、小文件过多、缺少分区裁剪等数据治理问题。同样的 SQL,先做分区和文件合并,提升往往比换引擎更明显。引擎只是锅,菜好不好吃还得看食材切得好不好。

为何常见:人总是倾向于找“银弹”方案,而不是做枯燥的数据治理和调优。

面试题

Q1. 湖仓一体(Lakehouse)的核心特征是?

单选题 · easy

  • A.只存储非结构化文件
  • B.数据湖上提供事务治理← 正确答案
  • C.完全替代传统数据仓库
  • D.不支持任何 SQL 查询

答案:B。湖仓一体的核心是在数据湖的低成本存储之上叠加 ACID 事务、Schema 强制、索引等“仓库级”能力,对应后厨给冷库加装管理系统。A 只描述了数据湖,C 太绝对,D 完全错误。

Q2. Trino/Presto 最擅长哪种场景?

单选题 · easy

  • A.小时级 ETL 批处理任务
  • B.交互式跨源联邦查询← 正确答案
  • C.大规模机器学习训练
  • D.亚秒级实时流计算

答案:B。Trino 的定位是交互式联邦查询,像跑单小哥一样轻装快跑,一个 SQL 查多个数据源是它的招牌。A 是 Spark 的强项,C 属于训练框架,D 属于流处理引擎。

Q3. Spark SQL 的本质定位是?

单选题 · easy

  • A.通用联邦查询引擎
  • B.分布式批处理引擎← 正确答案
  • C.单机内存数据库
  • D.非关系型文档数据库

答案:B。Spark SQL 是分布式批处理引擎的 SQL 接口,擅长海量数据的离线加工与 ETL,如同后厨的中央厨房。A 是 Trino,C、D 与分布式批处理定位无关。

Q4. Photon 大幅提速的主要原因?

单选题 · mid

  • A.使用 GPU 替代 CPU
  • B.C++ 向量化批量执行← 正确答案
  • C.增加集群物理节点
  • D.压缩存储的数据量

答案:B。Photon 用 C++ 重写执行层,按批次进行 SIMD 向量化运算,而非逐行解释执行,就像多头锅铲一次翻动八块肉。A 不对,Photon 用的是 CPU 的 SIMD 指令;C 是扩容;D 是存储优化。

Q5. 关于 Spark Shuffle 的正确说法?

多选题 · mid

  • A.网络带宽越高传输越快← 正确答案
  • B.减少中间数据可降低成本← 正确答案
  • C.Shuffle 只在单机执行
  • D.预聚合能减少数据量← 正确答案

答案:ABD。Shuffle 时间 = 数据量 / 带宽,A、B 正确;C 错误,Shuffle 发生在跨节点的网络传输中,就像操作台之间传菜;D 正确,预聚合(combiner)先在小范围内合并,显著减少传输量。

Q6. 减少查询扫描量的有效手段?

多选题 · mid

  • A.分区裁剪跳过无关文件← 正确答案
  • B.谓词下推到存储层← 正确答案
  • C.数据倾斜加盐分区
  • D.Z-Order 聚簇排序← 正确答案

答案:ABD。分区裁剪只读命中分区,谓词下推让过滤在存储层提前执行,Z-Order 让相似数据聚簇、配合列存跳读,这三者都能减少扫描量。C 数据倾斜加盐是均衡计算负载,并不减少读取的数据量。

Q7. 关于 Spark SQL 执行模型的正确说法?

多选题 · mid

  • A.Driver 负责任务调度← 正确答案
  • B.Stage 间通过 Shuffle 传递← 正确答案
  • C.只支持批量处理模式
  • D.Catalyst 生成执行计划← 正确答案

答案:ABD。Driver 统一调度任务,Stage 之间通过 Shuffle 交换中间数据,Catalyst 优化器负责生成并优化执行计划,都对。C 错误,Spark 通过 Structured Streaming 也支持流式处理,并非只能批处理。

Q8. Amdahl 定律指出并行加速的极限由什么决定?

单选题 · hard

  • A.任务可并行比例 f← 正确答案
  • B.所有节点内存总和
  • C.数据压缩算法效率
  • D.磁盘每秒读写次数

答案:A。Amdahl 定律说明加速比极限是 1/(1-f),串行部分决定了性能天花板。就像炒菜时切配可多人分工,但颠锅只能一个人来,这个“颠锅”就是不可并行的 f 的来源。

Q9. TPC-DS 对比用几何平均而非算术平均的原因?

单选题 · hard

  • A.避免极端查询时间主导← 正确答案
  • B.数学实现过程更简单
  • C.让整体成绩显得更好
  • D.方便隐藏失败查询记录

答案:A。几何平均对极端值不敏感,任何一条查询过慢都会被计入总分,但不会被少数极端值绑架整体印象。算术平均会被一条超慢查询严重拉偏,相当于评委因为一道菜失败就否定整桌宴席。

Q10. 在 Photon 上运行含自定义 UDF 的 SQL 时会怎样?

单选题 · extreme

  • A.自动转为向量化代码
  • B.退回行模式加速失效← 正确答案
  • C.直接拒绝执行任务
  • D.秒级报错终止查询

答案:B。Photon 无法识别任意自定义 UDF(用户自定义函数),遇到时会从向量化批量模式退回逐行模式,导致加速效果大幅缩水。它不会自动改写 UDF,也不会拒绝或报错,而是“降级”运行,就像特级厨师遇到不熟悉的食材,只能改用普通锅铲慢慢做。