如何将Apache Ignite作为Apache Spark的外部数据源?相关问题咨询
技术方案解答
一、跨Ignite内存、HDFS存储的单条SQL查询实现
你之前读源码观察到的「Spark SQL转换为Ignite SQL、查询下发到Ignite节点由H2引擎执行」的机制,仅在查询完全基于Ignite缓存表的场景下触发,并不代表Ignite作为Spark外部数据源时存在“必须全量加载数据到内存、无法对接HDFS数据”的硬性约束。
实际落地时完全可以依托Spark原生的多数据源联邦查询能力,实现单条SQL同时扫描Ignite内存与HDFS数据的需求,具体落地路径:
- 在Spark Catalog层把不同存储位置的数据注册为可关联的数据集:
- 把全量存在Ignite内存的city表,通过Ignite的Spark数据源加载为可查询的Spark视图
- 拆分person表的存储来源:存储在Ignite中的热数据部分直接通过Ignite数据源加载为内存视图,存储在HDFS的冷数据部分通过Spark原生的HDFS数据源(Parquet/ORC格式)直接加载为HDFS侧视图
- 将上述两个person侧的视图通过
unionByName操作拼接为完整的person全量数据集,再与city的内存视图做关联,即可完全在单条Spark SQL中完成要求的查询逻辑。这种架构下根本不需要把包含HDFS数据的查询下推到Ignite的H2引擎执行,最优的职责分工是:Ignite仅承担小表、高频热数据的高速读取能力,Spark负责跨数据源的分片扫描、数据合并、关联计算——把全量在内存的city小表做广播分发,person的热数据从Ignite并行拉取、冷数据从HDFS并行扫描,两路数据在Spark计算节点侧完成合并后再与city表关联,性能反而比把全量数据塞入Ignite的方案更优 - 可以进一步优化实现业务SQL无感知的体验:配置自动同步规则,将高频访问的热person数据定期同步到Ignite缓存,每次查询时Spark自动路由热数据到Ignite读取、冷数据到HDFS读取,全程不需要业务侧修改原有的SQL写法。
二、Spark3.0版本适配Ignite的可行方案
目前开源版本的Ignite官方Spark连接器长期停留在Spark2.4版本,未推出对Spark3.0的稳定支持版本,直接使用官方连接器运行会遇到Spark3.0内部API的不兼容问题(核心是Spark3.0对DataSource V2接口、Catalog内部实现做过破坏性调整)。
适配方案按投入产出比从高到低排序:
- 优先做最小化的连接器适配补丁:目前社区已经有大量针对Ignite Spark连接器适配Spark3.0的二次修改实践,核心只需要调整几百行的适配层代码——即把原连接器中对接Spark2.4的DataSource V2接口的签名,替换为Spark3.0要求的接口定义,不需要修改核心的Ignite缓存对接、查询下推、序列化转换逻辑,改造成本极低,还能完整保留原连接器的列裁剪、谓词下推、并行查询的优化能力
- 不推荐直接全量重新实现适配逻辑:Ignite Spark连接器的核心功能逻辑(对接Ignite缓存、查询转换)并不会因为Spark版本迭代失效,只是外层对接Spark SQL框架的适配层存在兼容性问题,全量重写的投入产出比极低
- 兜底零改造方案:如果不想投入精力做连接器适配,完全可以绕开官方的Ignite-Spark连接器,直接使用Ignite原生的JDBC驱动,通过Spark的JDBC数据源接口对接Ignite,这种对接方式在所有Spark版本上都能稳定运行,仅会损失部分谓词下推的优化能力,对于存储全量小表(比如city表)的场景,这点性能损失完全可以接受。
内容的提问来源于stack exchange,提问作者Henrik
相关产品推荐
相关产品推荐

