更新时间:2026-07-24 GMT+08:00
分享

配置Spark Native引擎

配置场景

Spark Native引擎是通过使用向量化的C++加速库,实现对Spark算子性能加速的一种技术方案。传统的SparkSQL是基于行式数据,通过JVM的codegen来实现查询加速的,由于JVM对生成的java代码存在各种约束,比如方法长度,参数个数等,以及行式数据对内存带宽的利用率不足,因此存在性能提升空间。使用成熟的向量化的c++加速库后,数据采用向量化格式存在内存中,可以提高带宽利用率,并通过批量的数处理获得加速效果。

通过开启Spark Native引擎特性,获得SparkSQL的性能加速。配置Spark Native引擎后不支持Spark大SQL查询和删除。

使用约束

  • 本章节仅适用于MRS 3.6.0.1及之后版本。
  • 支持spark-sql以及spark-beeline任务。
  • 数据类型

    Spark 类型

    Substrait

    Velox

    计算

    Scan

    写入

    备注

    BooleanType

    bool

    BOOLEAN

    -

    ByteType

    i8

    TINYINT

    ParquetScan fallback

    ShortType

    i16

    SMALLINT

    -

    IntegerType

    i32

    INTEGER

    -

    LongType

    i64

    BIGINT

    -

    FloatType

    fp32

    REAL

    -

    DoubleType

    fp64

    DOUBLE

    -

    StringType

    string

    VARCHAR

    -

    BinaryType

    binary

    VARBINARY

    -

    DateType

    date

    DATE

    -

    TimestampType

    timestamp

    TIMESTAMP

    ⚠️

    ⚠️

    Parquet仅 INT96+dict;ORC scan/write不支持

    DecimalType(p,s)

    decimal

    DECIMAL/SHORT_DECIMAL/HUGEINT

    按精度选底层表示

    NullType

    nothing

    UNKNOWN

    -

    CharType(n)

    fixedChar

    VARCHAR

    ⚠️

    ORC scan强制 fallback

    YearMonthIntervalType

    intervalYear

    INTERVAL_YEAR_MONTH

    写入 Parquet/ORC/CSV 不支持

    ArrayType

    list

    ARRAY

    ⚠️

    element为 Struct/Array时scan fallback;native write不支持

    MapType

    map

    MAP

    ⚠️

    key为Struct或value 为Array时scan fallback;native write不支持

    StructType

    struct

    ROW

    ⚠️

    Parquet/CSV写入不支持;native write 不支持

    DayTimeIntervalType

    -

    -

    不支持

    CalendarIntervalType

    -

    -

    不支持

    UUIDType

    -

    -

    不支持

    VarcharType(n)

    -

    -

    不支持

    TimestampNTZType

    -

    -

    不支持

  • 数据格式

    名称

    读取

    写入

    Parquet

    ORC

    CSV/Text

    x

    Iceberg(Parquet/ORC)

  • 算子Fallback回Spark场景

    算子

    说明

    SubqueryExec / SubqueryBroadcastExec

    子查询保持行式执行

    AggregateInPandasExec

    Pandas聚合

    MapInPandasExec

    PandasMap

    FlatMapGroupsInPandasExec

    Pandas FlatMapGroups

    WindowInPandasExec

    Pandas窗口

    LocalTableScanExec

    本地表扫描(数据量极小,无需原生加速)

    CommandExec 系列

    DDL/DML命令(Show/Describe/Create/Alter 等)

    QueryStageExec

    AQE阶段边界节点

    CustomShuffleReaderExec

    AQE Shuffle读取

    CreateDataSourceTableAsSelectCommand

    CTAS始终回退

    InsertIntoHadoopFsRelationCommand(bucket)

    有bucket时不支持

  • 表达式Fallback回spark场景

    JSON 函数

    表达式

    限制

    from_json

    不支持enablePartialResults=false

    from_json

    不支持options参数

    from_json

    不支持大小写敏感(caseSensitive=true)

    from_json

    不支持schema中重复key

    from_json

    不支持corrupt record类型列

    to_json

    不支持options参数

    数组/高阶函数

    表达式

    限制

    array_filter + 带index的lambda

    不支持,

    • 带 index:不支持,回退Spark。

      SELECT filter(array(1, 2, 3), (x, i) -> i > 0);

    • 结果: [2, 3](i 是数组下标,从0开始)
    • 区别在于lambda函数的参数个数:

      - (x) -> ... — 1 个参数,只用元素值,Velox 支持

      - (x, i) -> ... — 2 个参数,第二个 i 是元素下标,Velox 不支持

    array_forall + 带index的lambda

    不支持,与array_filter限制相同

    array_exists + 带index的lambda

    不支持,与array_filter限制相同

    array_transform + 带index的 ambda

    不支持,与array_filter限制相同

    其他表达式

    表达式

    限制

    str_to_map

    仅支持mapKeyDedupPolicy=EXCEPTION

    unbase64 + failOnError=true

    不支持

    TryEval / ANSI 算术

    仅支持整型(Long/Int/Short/Byte)

    PreciseTimestampConversion 涉及 TimestampNTZType

    不支持

    HiveHash

    不支持

    Cast 从 ArrayType 到 String

    通过Rewrite规则间接支持

    base64

    需启用chunkBase64String

  • 文件系统

    名称

    是否支持

    OBS

    HDFS

    Pacific

  • 平台

    名称

    是否支持

    X86、ARM、X86与ARM混合部署

  • 使用方式

    名称

    是否支持

    spark-sql yarn模式

    spark-sql local模式

    spark beeline

  • 数据类型限制

    含以下类型的 schema 会导致算子验证失败并回退:

    不支持的类型

    影响范围

    TimestampNTZType

    所有含此类型的算子

    DayTimeIntervalType

    不在schema白名单

    UserDefinedType

    不支持自定义类型

  • Native Shuffle(spark.shuffle.manager=org.apache.spark.shuffle.sort.ColumnarShuffleManager),支持的压缩算法(spark.io.compression.codec)。

    名称

    是否支持

    lz4

    lzf

    x

    snappy

    x

    zstd

    gzip

    x

    bzip2

    x

服务端配置参数

  1. 在Manager系统中,选择“集群 > 服务 > Spark > 配置”,单击“全部配置”,选择“Spark(服务) > Native”,配置如下参数:

    参数

    说明

    默认值

    spark.plugins

    Spark用到的插件,参数值设置为org.apache.gluten.GlutenPlugin。

    说明:

    如果已经配置了spark.plugins,则可以将

    org.apache.gluten.GlutenPlugin加到其中,用逗号","隔开。

    spark.gluten.memory.dynamic.offHeap.sizing.enabled

    是否开启Spark Native统一内存管理。设置为true,Native加速需要使用统一内存管理。

    true

    spark.shuffle.manager

    shuffle管理器。

    选择org.apache.spark.shuffle.mass.MassShuffleManager开启memartsstore远程shuffle服务。

    选择org.apache.spark.shuffle.sort.ColumnarShuffleManager开启native engine列式shuffle服务。

    选择org.apache.spark.shuffle.gluten.mass.MassShuffleManager开启native engine列式memartsstore远程shuffle服务

    sort

    spark.sql.orc.impl

    当需要开启Native读写ORC表时,需要设置为native。

    hive

  1. 单击“保存”,保存已经修改的配置,并重启过期的实例。
  2. 选择“概览 > 更多 > 下载客户端”,安装并使用该客户端。

客户端配置参数

  1. 如果已经按照服务端配置参数配置,并下载安装新的客户端,可跳过该章节。
  2. 在Spark客户端的“{客户端安装目录}/Spark/spark/conf/spark-defaults.conf”配置文件中进行设置,修改如下参数:

    参数

    说明

    默认值

    spark.plugins

    Spark用到的插件,参数值设置为org.apache.gluten.GlutenPlugin。

    说明:

    如果已经配置了spark.plugins,则可以将org.apache.gluten.GlutenPlugin加到其中,用逗号","隔开。

    spark.gluten.memory.dynamic.offHeap.sizing.enabled

    是否开启Spark Native统一内存管理。设置为true,Native加速需要使用统一内存管理。

    true

    spark.shuffle.manager

    shuffle管理器。

    选择org.apache.spark.shuffle.mass.MassShuffleManager开启memartsstore远程shuffle服务。

    选择org.apache.spark.shuffle.sort.ColumnarShuffleManager开启native engine列式shuffle服务。

    选择org.apache.spark.shuffle.gluten.mass.MassShuffleManager开启native engine列式memartsstore远程shuffle服务

    r

    sort

    spark.sql.orc.impl

    当需要开启Native读写ORC表时,需要设置为native。

    hive

  3. 在客户端目录下执行“source bigdata_env”刷新环境变量

使用说明

可通过检查执行计划的方式验证Native Engine是否开启,执行如下语句:

spark-sql -e "explain select * from database.data_source"

当执行计划中出现CHNativeColumnarToRow字样,即可认为Native Engine已经开启。

数据一致性校验工具

数据一致性验证工具基于Shell脚本,通过调用Spark-shell启动Scala应用程序。该Scala程序实现了核心的比较逻辑,对比Spark执行查询和通过Spark Native方式执行查询时生成的表数据。Spark和Spark Native的查询结果

  1. 按照客户端配置参数开启Spark Native。
  2. 进入“{客户端安装目录}/Spark/spark/tool”目录,执行sh md5compare.sh --help可查看使用方法:
    md5compare.sh --dbname <name> --query-path <path> --spark_tbl_location <path> --native_tbl_location <path> --spark_tbl_name <name> --native_tbl_name <name> --clear_tbl_data <boolean> --driver_mem <MEM> --executor_mem <MEM> --executor_num <NUM> --executor_core <NUM>
    表1 参数说明

    参数

    是否必填

    参数说明

    --dbname <数据库名>

    必填

    执行 SQL 查询时使用的目标数据库

    --query-path < 文件路径 >

    必填

    SQL 查询脚本的路径,该文件仅支持单条SQL

    --spark_tbl_location < 目录路径 >

    可选

    Spark 查询结果的外部表存储目录,默认值为 /tmp/spark

    --native_tbl_location < 目录路径 >

    可选

    原生查询结果的外部表存储目录,默认值为 /tmp/native

    --spark_tbl_name < 表名 >

    可选

    存储 Spark 查询结果的临时表名称,默认值为 spark_data

    --native_tbl_name < 表名 >

    可选

    存储原生查询结果的临时表名称,默认值为 native_data

    --clear_tbl_data < 布尔值 >

    可选

    对比结束后是否删除临时表及外部表存储路径,默认值为 true

    --driver_mem < 内存值 >

    可选

    Driver 进程使用的内存大小,默认值为 4G

    --executor_mem < 内存值 >

    可选

    每个 Executor 进程使用的内存大小,默认值为 2G

    --executor_num < 数值 >

    可选

    启动的 Executor 进程总数量,默认值为 4

    --executor_core < 数值 >

    可选

    为每个 Executor 进程分配的 CPU 核心数,默认值为 1

  3. 执行示例:
    sh md5compare.sh --dbname tpcds_hive_spark2x_2 --query-path /opt/query/q1.sql --spark_tbl_location /tmp/spark --native_tbl_location /tmp/native --spark_tbl_name spark_data --native_tbl_name native_data --clear_tbl_data true --driver_mem 8G --executor_mem 4G --executor_num 2 --executor_core 2

针对Spark和Native Engine在处理decimal,float以及double时可能存在的小数部分的差异,一致性校验工具统一取到小数点后一位做比较。例如:3.14159,一致性工具在比较时取3.1做比较。

差异说明

开启native engine后,执行结果和spark runtime存在细微差异:

  1. 由于spark runtime和native engine在处理decimal的舍入规则不同,造成decimal结果最后一位可能存在差异。
  2. 读取json格式的binary类型数据时,由于Spark在写入时进行了base64编码:如 '0101' 写入json文件后为'MDEwMQ==',Spark runtime读取会base64解码,但native engine读取时未base64解码,需要unbase64()函数解码。
  3. Native Engine不支持SET TIME ZONE INTERVAL语法。

常见问题

问题一:Spark Native引擎运行时使用的内存比Spark高,更容易出现OOM,可考虑开启shuffle prefer spill和降低Batch Size大小。
  1. 服务端配置:
    登录Manager页面,选择“集群 > 服务 > Spark > 配置”,单击“全部配置”,选择“Spark(服务) > Native”,配置如下参数:

    参数

    说明

    默认值

    spark.gluten.sql.columnar.backend.ch.shuffle.preferSpill

    当shuffle内存达到门限时,是否溢写到磁盘

    修改配置为true

    false

    spark.gluten.sql.columnar.backend.ch.spillThreshold

    shuffle内存门限值, 当shuffle内存超过该值,会溢写磁盘

    建议设置为128M

    0

    spark.gluten.sql.columnar.maxBatchSize

    shuffle算子一个批次处理的行数, 影响Spark Native引擎中shuffle算子的内存占用

    可设置为1024

    4096

  2. 客户端配置:

    在Spark客户端节点的“{客户端安装目录}/Spark/spark/conf/spark-defaults.conf”配置文件中进行设置,新增如下参数:

    spark.gluten.sql.columnar.backend.ch.shuffle.preferSpill=true
    spark.gluten.sql.columnar.backend.ch.spillThreshold=128M
    spark.gluten.sql.columnar.maxBatchSize=1024

问题二:执行SQL任务时,如果Fallback Node过多,性能比Spark更差,可考虑使用动态开关关闭Spark native引擎

set spark.gluten.enabled=false;

调优指南

内存优化参数
  • 文件被切分成多个分片后,最大分片的大小(默认64MB):
    spark.gluten.sql.columnar.backend.ch.file.split.size=268435456
  • 内存超过executor限制是否抛出异常(设置为false可允许native超限使用内存以提升性能,但有被OOM killer结束executor进程的风险)。
    spark.gluten.sql.columnar.backend.ch.throwIfMemoryExceed = false
decimal溢出检查和精度
  • 是否允许var_sample, corvar_sample函数的精度损失:
    spark.gluten.sql.columnar.precision.loss.allowed = true
  • 是否开启decimal溢出检查,关闭可提升decimal计算性能:
    spark.gluten.sql.columnar.backend.ch.runtime_settings.decimal_check_overflow=false

即时编译

spark.gluten.sql.columnar.backend.ch.runtime_config.compile_expressions=1

相关文档