Databend 源码阅读: Storage 概况和 Read Partitions

作者:zhyass | Databend Labs 成员,数据库研发工程师

❤️ 友情提示:代码演进较快,请注意文档的时效性哦!

引言

Databend 将存储引擎抽象成一个名为 Table 的接口,源码位于 query/catalog/src/table.rs

Table 接口定义了 readappendalteroptimizetruncate 以及 recluster 等方法,负责数据的读写和变更。解释器(interpreter)通过调用 Table trait 的方法生成物理执行的 pipeline

通过实现 Table 接口的方法,可以定义 Databend 的存储引擎,不同的实现对应不同的引擎。

Storage 主要关注 Table 接口的具体实现,涉及表的元信息,索引信息的管理,以及与底层 IO 的交互。

目录

包名作用
common/cache定义与管理缓存,包括磁盘缓存和内存缓存。类型包含表 meta 缓存、查询结果缓存、表数据缓存等。
common/index定义与使用索引,目前支持 bloom filter index、page index、range index。
common/locks管理与使用锁,支持表级别的锁。
common/pruner分区剪裁算法,包括 internal column pruner、limiter pruner、page pruner、topn pruner、range pruner。
common/table_meta表 meta 的数据结构定义。
hivehive 表的交互
icebergiceberg 交互
information_schema、system系统表定义
memory、null、random用于开发和测试的引擎
view视图相关
stagestage 数据源的读取
parquet把 parquet 文件作为数据源
fusefuse 引擎模块
fuse/src/iotable meta、index、block 的读写 IO 交互
fuse/src/pruningfuse 分区裁剪
fuse/src/statisticscolumn statistics 和 cluster statistics 等统计信息
fuse/src/table_functionstable function 实现
fuse/src/operationfuse 引擎对 table trait 方法的具体实现。并包含了如 ReadSource、CommitSink 等 processor 算子的定义

Read Partitions

以下以 fuse 引擎中 read partitions 的实现流程为例,简要分析 Storage 相关源码。

Partitions 的定义位于 query/catalog/src/plan/partition.rs

pub struct Partitions {
    // partitions 的分发类型。
    pub kind: PartitionsShuffleKind,
    // 一组实现了 PartInfo 接口的 partition,
    pub partitions: Vec<PartInfoPtr>,
    // partitions 是否为 lazy。
    pub is_lazy: bool,
}

Table 接口中的 read_partitions 通过分析查询中的过滤条件,剪裁掉不需要的分区,返回可能满足条件的 Partitions。

#[async_trait::async_trait]
impl Table for FuseTable {
    #[minitrace::trace]
    #[async_backtrace::framed]
    async fn read_partitions(
        &self,
        ctx: Arc<dyn TableContext>,
        push_downs: Option<PushDownInfo>,
        dry_run: bool,
    ) -> Result<(PartStatistics, Partitions)> {
        self.do_read_partitions(ctx, push_downs, dry_run).await
    }
}

Fuse 引擎会以 segment 为单位构建 lazy 类型的 FuseLazyPartInfo。通过这种方式,prune_snapshot_blocks 可以下推到 pipeline 初始化阶段执行,特别是在分布式集群模式下,可以有效提高剪裁执行效率。

pub struct FuseLazyPartInfo {
    // segment 在 snapshot 中的索引位置。
    pub segment_index: usize,
    pub segment_location: Location,
}

分区剪裁流程的实现位于 query/storages/fuse/src/pruning/fuse_pruner.rs 文件中,具体流程如下:

  1. 基于 push_downs 条件构造各类剪裁器(pruner),并实例化 FusePruner
  2. 调用 FusePruner 中的 pruning 方法,创建 max_concurrency 个分批剪裁任务。每个批次包括多个 segment 位置,首先根据 internal_column_pruner 筛选出无需的 segments,再读取 SegmentInfo,并根据 segment 级别的 MinMax 索引进行范围剪裁。
  3. 读取过滤后的 SegmentInfo 中的 BlockMetas,并按照 internal_column_prunerlimit_prunerrange_prunerbloom_prunerpage_pruner 等算法的顺序,剔除无需的 blocks。
  4. 执行 TopNPrunner 进行过滤,从而得到最终剪裁后的 block_metas
pub struct FusePruner {
    max_concurrency: usize,
    pub table_schema: TableSchemaRef,
    pub pruning_ctx: Arc<PruningContext>,
    pub push_down: Option<PushDownInfo>,
    pub inverse_range_index: Option<RangeIndex>,
    pub deleted_segments: Vec<DeletedSegmentInfo>,
}

pub struct PruningContext {
    pub limit_pruner: Arc<dyn Limiter + Send + Sync>,
    pub range_pruner: Arc<dyn RangePruner + Send + Sync>,
    pub bloom_pruner: Option<Arc<dyn BloomPruner + Send + Sync>>,
    pub page_pruner: Arc<dyn PagePruner + Send + Sync>,
    pub internal_column_pruner: Option<Arc<InternalColumnPruner>>,
    // Other Fields ...
}

impl FusePruner {
    pub async fn pruning(
        &mut self,
        mut segment_locs: Vec<SegmentLocation>,
        delete_pruning: bool,
    ) -> Result<Vec<(BlockMetaIndex, Arc<BlockMeta>)>> {
        ...
    }
}

剪裁结束后,以 Block 为单位构造 FusePartInfo,生成 partitions,接着调用 set_partitions 方法将 partitions 注入 QueryContext 的分区队列中。在执行任务时,可以通过 get_partition 方法从队列中取出。

pub struct FusePartInfo {
    pub location: String, 
    pub create_on: Option<DateTime<Utc>>,
    pub nums_rows: usize,
    pub columns_meta: HashMap<ColumnId, ColumnMeta>,
    pub compression: Compression,
    pub sort_min_max: Option<(Scalar, Scalar)>,
    pub block_meta_index: Option<BlockMetaIndex>,
}

Conclusion

Databend 的存储引擎设计采用了抽象接口的方式,具有高度的可扩展性,可以很方便地支持多种不同的存储引擎。Storage 模块的主要职责是实现 Table 接口的方法,其中 Fuse 引擎部分尤为关键。

通过对数据的并行处理,以及数据剪裁等手段,可以有效地提高数据的处理效率。鉴于篇幅限制,本文仅对读取分区的流程进行了简单阐述,更深入的解析将在后续的文章中逐步展开。

关于 Databend

Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分析的新式数仓。期待您的关注,一起探索云原生数仓解决方案,打造新一代开源 Data Cloud。

👨‍💻‍ Databend Cloud:databend.cn

📖 Databend 文档:databend.rs/

💻 Wechat:Databend

✨ GitHub:github.com/datafuselab…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/153332.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java springboot在当前测试类中添加临时属性 不影响application和其他范围

目前 我们的属性基本都写在 application.yml 里面了 但是 如果 我们只是想做一下临时变量的测试 有没有办法实现呢&#xff1f; 显然是有的 这里 我们还是先在application.yml中去写一个 test属性 下面加个prop 然后 我们尝试在测试类中 获取一下这个属性 直接用 Value 读取…

华为Matebook X Pro 2022款 i7 集显(MRG-W76)原装出厂Windows11预装系统21H2

下载链接&#xff1a;https://pan.baidu.com/s/12ru9lUeQ7mWd5u1KLCM0Pg?pwdc7pi 提取码&#xff1a;c7pi 原厂系统自带指纹、面部识别、声卡、网卡、显卡等所有驱动、出厂主题壁纸、Office办公软件、华为电脑管家等预装程序&#xff0c;如图 由于时间关系,绝大部分资料没…

2023-11-16 android 编译提示module freg.default missing dependencies:

一、错误如下&#xff1a; 二、原因 2.1 Andriod.bp 编译的so模块可以被 Android.bp 和 Android.mk 编译依赖。 2.2 Android.mk 编译的so模块仅可以被Android.mk编译的模块依赖&#xff0c;无法被Android.bp编译的模块依赖。 三、参考文章 【Android编译报错&#xff1a;miss…

终于解决!!!the pgadmin4 server could not be contacted

今天尝试用geoserver发布arcgis的gdb数据&#xff0c;说是要用到postgis&#xff0c;于是就安装了&#xff0c;结果刚安装好就遇到这个问题了&#xff0c;pgadmin报错打不开&#xff0c;裤子都没脱就告诉我有错误了&#xff0c;这tm不是欺负老实人吗&#xff0c;于是就开始百度…

第08章 面向对象编程(高级)

一 关键字&#xff1a;static class Circle{private double radius;public Circle(double radius){this.radiusradius;}public double findArea(){return Math.PI*radius*radius;} }创建两个Circle对象&#xff1a; Circle c1new Circle(2.0); //c1.radius2.0 Circle c2new C…

美团面试题

文章目录 1.线程池有几种实现方式?2.线程池的参数含义?3.锁升级的过程?4.i++ 如何保证线程安全?5.HashMap和ConcurrentHashMap有什么区别?6.@Autowired和@Resource区别?7.说说常用的设计模式8.Redis为什么这么快?9.索引的种类?如何优化?1.线程池有几种实现方式? 线程…

爱上C语言:操作符详解(下)

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;生活本来沉闷&#xff0c;但跑起来就有风 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请…

《C++ Primer》第9章 顺序容器(二)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 9.3 顺序容器操作&#xff08;P305&#xff09; 9.3.1 向容器中添加元素&#xff08;P305&#xff09; 使用push_back 除 array 和 forward_list 外&#xff0c;每个顺序容器都支持 push_back &#xff1a…

在windows下vs c++运行g2o的BA优化程序示例

目录 1、前言2、准备工作安装git安装vcpkg&#xff08;1&#xff09;下载&#xff08;2&#xff09;安装&#xff08;3&#xff09;集成至vs 安装cmake 3、安装g2o4、安装opencv&#xff08;1&#xff09;下载&#xff08;2&#xff09;双击安装&#xff08;3&#xff09;环境变…

Java反射机制开发经验总结

原创/朱季谦 反射是框架底层的灵魂&#xff0c;无论是Spring还是Dubbo&#xff0c;底层都大量使用到反射机制。 可以说&#xff0c;反射是Java开发当中一个绕不过的坎。 我曾经在实际项目当中有经常用到反射机制&#xff0c;故而将学会的反射用法做一些汇总笔记&#xff0c;当…

超详细的Jmeter随机参数各种搭配

前言 参数配置应该有三种场景&#xff0c;具体其他的我还没想到&#xff0c;那到底是哪三种呢&#xff1f;如果你也对这个问题感兴趣的话&#xff0c;那就让我们一起往下看吧&#xff01; 一、两个固定值之间随机生成一个值&#xff0c;应用场景没有限制 1、最简单的两个值之…

Spring lOC的注解使用与开发

Spring Spring IoC注解式开发为什么使用注解Spring注解的使用Value注解Autowired注解全注解式开发 Spring IoC注解式开发 为什么使用注解 注解的存在主要是为了简化XML的配置&#xff0c;注解的开发能大大提高我们的开发效率的&#xff0c;但它在一定程度上违背了OCP原则。 …

锐捷软件开机自启动

http://t.csdnimg.cn/h6k9R win键搜索任务计划程序 打开&#xff0c;在windows创建任务&#xff1a;

MAC地址_MAC地址格式_以太网的MAC帧_基础知识

MAC地址 全世界的每块网卡在出厂前都有一个唯一的代码,称为介质访问控制(MAC)地址 一.网络适配器(网卡) 要将计算机连接到以太网&#xff0c;需要使用相应的网络适配器(Adapter)&#xff0c;网络适配器一般简称为“网卡”。在计算机内部&#xff0c;网卡与CPU之间的通信&…

【智能家居项目】FreeRTOS版本——将裸机程序改造成FreeRTOS程序 | DHT11温湿度传感器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 如上图所示是裸机版本的智能家居项目总体框架结构&#xff0c;这篇文章开始&#xff0c;本喵要…

服装供应链管理的革新利器—超高频RFID技术

一、行业概述 服装行业一直被视为低技术含量的劳动密集型产业&#xff0c;但实际上&#xff0c;科学技术在整个行业的发展中起着至关重要的作用&#xff0c;从服装面料的制作到服装设计、生产制作、物流到终端销售&#xff0c;科技力量贯穿于每一个环节。然而&#xff0c;传统…

Codeforces Round 908 (Div 2——AB)

A. Secret Sport 题目 AB二人玩游戏&#xff0c;每一局&#xff08;plays&#xff09;游戏会有一个获胜者&#xff0c;首先获胜X局&#xff08;play&#xff09;的玩家得一分&#xff08;赢得一轮sets&#xff09;。率先获得Y分的玩家获得最终胜利。 给你整场游戏的每局&…

树状图PPT怎么做?用这个树状图制作软件轻松拿捏!

在我们的日常工作和学习中&#xff0c;PPT已经成为了我们常见的展示方式。 在制作PPT时&#xff0c;树状图PPT是非常重要和常用的一种&#xff0c;并且在商务、教育等领域都非常受欢迎。那么&#xff0c;究竟什么是树状图PPT&#xff0c;如何使用树状图制作软件来快速绘制树状…

2022年12月 Scratch(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 小明想在开始表演之前向大家问好并做自我介绍,应运行下列哪个程序?( ) A: B: C: D: 答案:D 外观积木配合显示时间,才能看清楚内容。 第2题 舞台有两个不同的背景,小猫角色的哪个

网站提示Internal Server Error的原因和解决方法分享

解决方法 登陆FTP或文件管理器,检查站点目录文件权限设置,将文件夹权限设置为755,单个文件权限设置为644。 这样设置644后,问题就可以解决,同时也不会影响网站的所需要的写入权限,满足网站正常运行。如果你的站点中有很多权限都要需要设置,为了提高效率。 应用导致分析…