• Offsets 获取该行的起始索引 start=offsets (x)


    获取数据列的第 x 行,通过 Offsets 获取该行的起始索引 start=offsets (x) 和下一行的起始索引 end=offsets (x+1),然后使用这两个索引通过 Bytes 获取具体数据对应的字节流 bytes.slice (start,end),最后按照字段类型做相应的转换即可。

    注:为方便表述,上面例子做了一定的简化,对于 Nullable 数据列,实际上还有 FixedLengthColumn 的数据结构,对应一段连续的 Bool 数据,用来表示对应行号的列数据取值是否为 Null,用来加速 Nullable 列的计算效率,减少数据列的存储空间。

    内存分配和管理设计

    由于 BE 端是通过 Memory Tracker 进行内存管理的,我们在实现 JNI Reader 时,由 Memory Tracker 统一进行内存的分配和销毁,避免直接使用 JVM Unsafe 分配 Native Memory,来保证内存统计的准确性,并防止出现错误的内存使用导致的各类问题。

    编程框架设计

    在编程框架上,我们完整定义了 JNI Connector 的 Java 接口,让开发者不需要进行复杂的 JNI 编程以及相关的内存管理,只需要继承 ConnectorScanner 抽象类,实现 open (), getNext (), close () 这三个抽象方法,然后在 BE 侧给出具体实现类的名称,便可以完整使用我们的 JNI Connector, 读取各类 Java 数据源的数据。

    混合使用 Native Reader 和 JNI Reader 设计

    在 Hudi Reader 的实现里,我们有一个优化方案。上文提到,我们在 Scan range 里添加了 useJNIReader 的字段。这个字段具体取值在 FE 端通过下面逻辑控制:

    判断当前表的数据类型:如果是 MOR 表,查询类型为 Snapshot,且该 File Slice 包含一个或一个以上的 Delta log,useJNIReader 便置为 True,其他情况都为 False。

    这样带来的效果是,对于同一个 MOR 表的 Snapshot 读取,BE 端实际上会同时混合使用两种不同的 Reader 去拿数据,使用 Native reader 读取不包含 Delta Logs 的 File Slice,使用 JNI Reader 读取包含 Delta Logs 的 File Slice,不同的 Reader 混合使用可以进一步提升读取效率,且这些加速对于用户都是透明无感知的。

    6、使用案例

    1. 创建 hudi catalog

    1. CREATE EXTERNAL CATALOG "hudi_catalog"
    2. PROPERTIES (
    3. "type" = "hudi",
    4. "hive.metastore.uris"= "thrift://xxx:9083" -- hive metastore地址
    5. );

    2. 执行查询

    select * from hudi_catalog.<db_name>.<table_name>;
    1. +------+------+---------------------+------------------------+--------------------+-----------------------+------------------------------------------------------------------------+
    2. | id | age | _hoodie_commit_time | _hoodie_partition_path | _hoodie_record_key | _hoodie_commit_seqno | _hoodie_file_name |
    3. +------+------+---------------------+------------------------+--------------------+-----------------------+------------------------------------------------------------------------+
    4. | 3 | 33 | 20220422111823231 | age=33 | id:3 | 20220422111823231_0_3 | 29d8d367-93f9-4bd3-aae4-47852e443e36-0_0-128-114_20220422111823231.orc |
    5. +------+------+---------------------+------------------------+--------------------+-----------------------+------------------------------------------------------------------------+

    7、性能测试

    测试环境:

    阿里云 EMR Presto 集群,阿里云 EMR StarRocks 集群

    硬件配置:

    Master: ecs.g7.4xlarge 16 vCPU 64 GiB

    Worker: ecs.g7.4xlarge 16 vCPU 64 GiB * 5

    软件配置:

    StarRocks 版本:master 分支(Hudi MOR 读取特性会在 2.5.0 正式发布)

    StarRocks 软件配置:默认配置

    Presto 版本:0.277

    Presto 软件配置:

    1. query.max-memory-per-node=40GB
    2. query.max-memory=200GB

    COW 表 Snapshot 查询 TPCH-100 测试结果

    对于 COW 表 Snapshot 查询,使用 StarRocks 相对 Presto 大约会带来 5 倍的性能提升。

    MOR 表 Snapshot 查询 TPCH-100 测试结果

    对于 MOR 表 Snapshot 查询,如上文描述,混合使用了 Native Reader 和 JNI Reader,因此,我们在 StarRocks 上测试读取不同比例更新数据(带有 Delta Logs 的 File Slice)的执行时间,来得到不同更新比例场景下的查询效率数据。从测试结果可以看出,更新数据比例越小,StarRocks 实际执行时使用 Native Reader 的比例也就越高,执行效率也越好。

    根据社区的经验,最常见的库表更新场景里,在 Hudi 表做 Compaction 操作前,带有 Delta Logs 的 File Slice 占整个表的比例大约在 20% 左右,在这种条件下,使用 StarRocks 相对 Presto 大约会带来 2-3 倍的性能提升。

    对于 MOR 表 Read Optimized 查询,StarRocks 内部执行原理和流程与 COW 表相同,性能提升数据也一致。

  • 相关阅读:
    实验七 循环神经网络(2)梯度爆炸实验
    postgresql简单导出数据与手动本地恢复(小型数据库)
    GPT-4:论文阅读笔记
    宏观经济学名词解释
    springboot+jxls复杂excel模板导出
    R语言隐马尔可夫模型HMM识别股市变化分析报告
    【什么是高斯分布?还有什么分布?他们的用途是什么?】
    JavaWeb——CSS的使用
    企业架构LNMP学习笔记26
    【WebLogic】Oracle发布2022年第三季度中间件安全公告
  • 原文地址:https://blog.csdn.net/zcypaicom/article/details/127883446