多个Spark Session查询Hadoop表相同分区是否会导致查询变慢?
多Spark Session并发查询性能下降原因及优化方案
核心原因分析
- 集群资源与IO竞争
8个并发Session总计需要申请32个executor、32核CPU、128GB内存,若集群总可用资源小于该值,所有应用会进入资源调度排队队列,直接增加等待耗时。即使CPU、内存资源充足,所有Session都读取HDFS上完全相同的分区文件,会直接打满HDFS所在节点的磁盘IO、集群网络带宽,每个查询的IO请求都会出现排队,是耗时翻倍的核心原因。 - 重复的任务初始化开销
每个独立Spark Session都需要单独走一遍完整的查询生命周期:请求Hive元数据库获取表结构、执行分区裁剪、生成逻辑/物理执行计划、申请启动executor,这些开销单个不明显,8个Session并发时不仅会叠加自身初始化耗时,还可能导致Hive元数据库并发查询卡顿,进一步拉长耗时。单Session场景下上述步骤仅需执行1次,没有额外开销。 - 缓存无法复用
单Session查询时,首次读取的HDFS文件会缓存在executor所在节点的操作系统页缓存甚至Spark RDD缓存中,后续同数据查询可直接读内存,耗时大幅降低。多Session场景下不同Session的executor大概率被调度到不同节点,且各Session内存空间隔离,无法共享已读取的缓存数据,每个Session都需要从HDFS全量拉取目标分区数据,重复IO成本极高。 - 不必要的分区扫描开销
你的查询语句中partition_first_2_digit IN ('01', '02')属于冗余条件,目标user_id01234的前两位为01,仅需要扫描01二级分区即可,02分区完全没有目标数据。单Session场景下仅需要多扫描1次无效分区,多Session场景下8个Session各自都要扫描无效分区,放大了无用IO开销。
优化建议
- 相同查询的并发场景优先使用共享Session方案,比如部署Spark Thrift Server,所有查询复用同一个Spark上下文、元数据、executor资源和数据缓存,可完全避免多Session的重复开销。
- 优化查询语句,根据user_id自动裁剪二级分区:比如查询user_id为
01xxxx时,仅指定partition_first_2_digit = '01',直接砍掉无效分区的IO开销。 - 热查询的小尺寸目标分区可主动缓存:执行
CACHE TABLE T1 PARTITION (partition_date='17', partition_first_2_digit='01'),后续所有查询直接读内存,不需要访问HDFS。 - 调整资源调度策略,开启Spark的数据本地化配置,尽量将executor调度到HDFS数据块所在的节点,减少跨节点网络传输耗时。
内容的提问来源于stack exchange,提问作者Korntewin Boonchuay
相关产品推荐
相关产品推荐

