第3.2章:Doris-2.0数据导入——Compaction机制

news2025/1/11 20:03:09

目录

一、Compaction概述

1.1  LSM-Tree概述

1.2 Compaction概述

1.3 Rowset数据版本

1.4  Compaction优点

1.5 Compaction问题

1.5.1 Compaction速度低

1.5.2 写放大问题

1.6 Compaction调优

1.6.1 业务侧

1.6.2 运维侧

二、Compaction执行方式

2.1 Vertical Compaction

2.1.1 概述

2.1.2 原理

2.2 Segment Compaction

2.2.1 概述

2.2.2 原理

注:本篇文章阐述的是Doris2.0版本的compaction机制

一、Compaction概述

1.1  LSM-Tree概述

       LSM-Tree( Log Structured-Merge Tree)是数据库中最为常见的存储结构之一,核心思想是充分发挥磁盘连续读写的性能优势,以短时间的内存和IO磁盘开销换取最大的写入性能,数据以Append-only的方式写入Memtable ,达到阈值后冻结Memtable并Flush为磁盘文件,再结合compaction机制将多个小文件进行多路归并排序形成新的文件,最终实现数据的高效写入。为了降低读取时需要合并的数据量,基于LSM-Tree的系统会引入后台数据合并的逻辑,以一定策略定期的对数据进行合并,Doris中这种机制被称为Compaction。 Doris中每批次的数据写入会生成一个数据版本,因此Compaction机制就是异步将底层小的rowset数据版本合并成一个更大的版本。

1.2 Compaction概述

     Doris 通过类似 LSM-Tree 的结构写入数据,后台通过 Compaction机制不断将小文件合并成有序的大文件。对于单一的数据分片(tablet),数据会按照顺序写入内存(写缓存memstore),达到阈值后刷写到磁盘,这些文件保存在一个rowset中。在Doris中,Compaction机制根据一定的策略对这些rowset合并成有序的大文件,极大地提升查询性能。

    ps: Doris中数据组织如下图:

      将数据表按照分区分桶规则,切分成若干个数据分片(tablet)存储在不同的be节点上。每个tablet都有多个副本(默认是3副本)。compaction是在每个be上独立进行的,compaction逻辑处理的就是一个be节点上所有的数据分片tablet。

1.3 Rowset数据版本

    一个tablet中包含若干连续的rowset(rowset是逻辑概念),rowset代表tablet中一次数据变更的数据集合(数据变更包括了数据新增,更新或删除等)。rowset按版本信息进行记录,版本信息中包含了两个字段first和second,first表示当前rowset的起始版本(start version),end表示当前rowset的结束版本(endversion)。

    Doris的数据写入是以微批的方式进行的,每一个批次的数据针对每个tablet都会形成一个rowset(一个tablet是由多个rowset组成的)。每个rowset都有一个相应的起始版本(start version)和终止版本(end version)。对于新增的rowset,起始版本和终止版本是一样的,表示为[ 6-6]、[ 7-7]等。多个 rowset经过compaction会形成一个大的rowset。合并后的起始版本和终止版本是多个版本的并集,如[ 6-6]、[ 7-7]、[8-8]合并后变成 [6-8],如下图:

    有个疑问:单个tablet中的rowset版本个数过多会什么影响?

     主要影响两个方面,一个是be存储节点的内存占用,当rowset的版本过多时,be节点的table_meta部分(主要是其中的rowset元数据部分)占用的内存可能非常多。同时compaction任务就会消耗大量内存与磁盘IO,资源开销较大容易引起oom,影响集群稳定性;二是查询会变慢,查询过程需要对tablet中的数据进行解压处理,当rowset版本很多时,数据解压会变慢,导致查询scan的耗时增加。

1.4  Compaction优点

  • 使得数据更加有序

   每个rowset内部的数据是按主键有序的,但是rowset与rowset之间的数据是无序的,compaction会将多个rowset的数据从无序变成有序,提升数据再读取时的效率。

  • 消除数据变更

   数据以Append-only的方式写入,因此Delete,Update等操作都是标记写入,compaction会将标记的数据进行真正的删除或更新,避免数据再读取时进行额外的扫描及过滤。
  • 增加数据聚合度

  在aggregate模型上,compaction还可以将不同的rowset中相同key的数据进行预聚合,减少数据读取时的局和计算,进一步提升读取效率

1.5 Compaction问题

      虽然compaction在写入和查询性能方面发挥着关键作用,但是compaction任务执行期间的写放大问题以及随之而来的磁盘I/O和CPU资源开销,也会影响系统稳定性和性能。

   不用应用场景,数据写入需求,写入任务并行度,单次提交数据量的大小,提交频次的高低等因素影响compaction策略,不合理的compaction策略则会导致:

1.5.1 Compaction速度低

     在高频写入场景下,短时间内生成的rowset版本太快,如果compaction不及时,就会造成大量版本堆积,最终导致写入失败(-238:OLAP_ERR_TOO_MANY_SEGMENTS);

    理论上每次导入操作,不论是只导入一条还是十万、百万条,对于Doris来说,都是只生成一个新的roswet版本。那么在compaction效率有限的情况下,完全可以通过“攒微批+降频率”来规避roswet版本过多的问题。

1.5.2 写放大问题

   Compaction本质上是将已经写入的数据读取后,重新写回的过程(读取多个小文件,合并成有序的大文件后再写回),这种重复的数据写入被称为写放大。一个好的compaction策略应该在保证效率的前提下,尽量降低写放大系数,因为过多的compaction会占用大量的内存及磁盘io资源,影响Doris集群的稳定性及查询性能,可能会导致BE OOM。

1.6 Compaction调优

   针对上述的compaction问题,可以从业务侧及运维侧进行调优。

1.6.1 业务侧

  • 通过引导业务侧进行合理优化,对表设置合理的分区分桶,避免生成过多的数据分片
  • 引导用户尽量降低数据的导入频率,增加每批次的导入数据量,从而降低compaction压力
  • 引导用户避免过多的Delete 操作,Delete操作在底层会对数据标记成Delete版本

       Doris中的Compaction分为 Base Compaction 与 Cumulative Compaction。Cumulative Compaction(简称CC)会将新导入的小版本进行快速合并,但是CC无法处理 Delete版本,所以CC在合并过程中若遇到 Delete 操作就会终止,并将当前Delete操作版本之前的所有版本进行一次合并,之后Base Compaction(简称BC)将基线版本与CC处理的版本合并。当 Delete 版本特别多时, CC的步长也会相应变短,只能合并少量的文件,导致CC不能很好的发挥小文件合并效果。

1.6.2 运维侧

  • 针对不同的业务集群配置不同的 Compaction 参数

    有些业务是实时写入数据,查询该数据的需求较多,此时可以将Compaction开的大一点以达到快速合并目的,避免影响查询性能。
    而有些业务数据写入当天的分区,查询需求针对之前的分区,在这种情况下,可以适当的将Compaction 放的小一点,避免 Compaction 占用过大内存或 CPU 资源。在晚上的低峰阶段对新导入的小版本进行合并,这样对第二天查询效率也不会有很大影响。

  • 适当降低 Base Compaction任务优先级并增加Cumulative Compaction优先级

   上文已经介绍了Cumulative Compaction能够快速合并大量生成的小文件,而 Base Compaction 由于合并的文件较大,执行的时间也会相应变长,读写放大也会比较严重。所以调高Cumulative Compaction的优先级。

  • 增加版本积压报警

      当收到版本积压报警时,可以动态调大Compaction参数,尽快消耗积压版本。

二、Compaction执行方式

   在Doris-2.0版本中,存在两种Compaction执行方式:

  • Vertical Compaction:用以彻底解决Compaction的内存问题以及大宽表场景下的数据合并;

  • Segment Compaction:用以彻底解决数据导入过程中的Segment文件过多问题;

   Doris 1.2.2版本之前的compaction执行方式见:

 第3.2章:Doris数据导入——Compaction机制-CSDN博客

2.1 Vertical Compaction

2.1.1 概述

     在之前的版本中,Compaction 合并的基本单元为整行数据。由于Doris存储引擎采用列式存储,行Compaction 的方式对数据读取极其不友好,每次 Compaction 都需要加载所有列的数据,内存消耗极大,而这样的方式在宽表场景下也将带来内存的极大消耗。

   Vertical Compaction天然与列式存储更加贴合,使用列组的方式进行数据合并,单次合并只需要加载部分列的数据,因此能够极大减少合并过程中的内存占用。Vertical Compaction算法解决了大宽表场景下的 Compaction 执行效率和资源开销问题。可以有效降低Compaction的内存开销,并提升 Compaction 的执行速度。在实际测试中,Vertical Compaction 使用内存仅为原有 Compaction 算法的 1/10,同时 Compaction 速率提升 15%。

   Vertical Compaction 在Doris-2.0版本中默认关闭状态,开启和配置方法(BE 配置)

#可以开启Vertical Compaction合并功能
set enable_vertical_compaction = true 

# 每个列组包含的列个数,经测试,默认5列一组compaction的效率及内存使用较友好
set vertical_compaction_num_columns_per_group = 5

# 用于配置vertical compaction之后落盘文件的大小,默认值256M,即:
set vertical_compaction_max_segment_size = 256*1024*1024

2.1.2 原理

  Vertical Compaction的执行流程如下图:

 整体分为如下几个步骤:

  • 切分列组:将输入 Rowset 按照列进行切分,所有的Key列一组、Value列按 N 个一组,切分成多个 Column Group;

   N的个数可以通过参数调整:vertical_compaction_num_columns_per_group

上述参数代表:每个列组包含的列个数,经测试,默认5列一组compaction的效率及内存使用较友好。set vertical_compaction_num_columns_per_group = 5

  • Key 列合并:Key列的顺序就是最终数据的顺序,多个 Rowset的 Key列采用堆排序进行合并,产生最终有序的 Key 列数据。在产生 Key 列数据的同时,会同时产生用于标记全局序 RowSources。

  • Value 列的合并:逐一合并 Column Group 中的 Value 列,以 Key列合并时产生的 RowSources为依据对数据进行排序。

  • 数据写入:数据按列写入,形成最终的 Rowset 文件。

2.2 Segment Compaction

2.2.1 概述

   Segment Compaction主要应对单批次大数据量的导入场景。和Vertical Compaction的触发机制不同,Segment Compaction允许我们在导入数据的同时,针对一批次数据内的多个Segment进行的合并操作,以有效控制 Segment 文件的数量。

   Segment Compaction 在Doris-2.0版本中默认关闭状态,开启和配置方法(BE 配置)

#可以开启Segment Compaction合并功能
set enable_segcompaction = true;
#用于配置合并的间隔。默认每生成10个segment文件将会进行一次
set segcompaction_batch_size =10;
该参数一般设置为10-30,过大的值会增加segment compaction 的内存占用量。

2.2.2 原理

    在数据导入阶段,Doris 会先在内存中积攒数据,到达一定批次大小,Flush到磁盘形成一个个的Segment 文件。

    大批量数据导入时会形成大量的 Segment 文件进而影响后续查询性能,基于此原因,Doris 对一批次导入的 Segment 文件数量做了限制,如果触发阈值,会报错 -238 (olap_err_too_many_segments) ,同时终止对应的导入任务。

   此外,Doris引入Segment Compaction合并算法,允许我们在导入数据的同时,针对一批次数据内的多个Segment进行的合并操作,以有效控制 Segment 文件的数量。具体流程如下所示:

    例如:如果单批次新增的Segment 数量超过一定阈值(例如 10个),会触发合并线程去异步执行合并任务。通过将每10 个Segment合并成一个新的Segment 并删除旧 Segment,导入完成后的实际 Segment 文件数量将下降 10 倍。

   Segment Compaction会在数据导入的同时并行执行,在单批次大数据量导入的场景下,能够在不显著增加导入时间的前提下大幅降低文件个数,提升查询效率。

  ps:如果导入操作本身已经耗尽了内存资源时,不建议使用 segment compaction 以免进一步增加内存压力使导入失败。

参考文章:

最佳实践|Apache Doris 在小米数据场景的应用实践与优化

资源消耗降低 90%,速度提升 50%,解读 Apache Doris Compaction 最新优化与实现

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Unity】【VR开发】Unity云同步功能使用心得

【背景】 有时出差,旅行等等也带着电脑,晚上想要继续编辑项目,就需要用到云同步功能。目前实践下来,发现有些内容可以同步,有些内容则是不可以同步的,总结如下。 【如何云同步一个本地项目】 UnityHub的项目面板中有两个选项卡:项目和云端项目。 鼠标挪动到想要云同步…

Linux——信号(3)

经过前两部分的介绍,我们现在已经认识了信号是如何产生的,并且知道无 论信号是如何产生的,最终只能由操作系统来对特定进程发送信号,而发送 信号其实也就是写信号,往内核数据结构(pending表)中写…

STM32引脚重定义问题

最近在搞资源管理,发现有些引脚不能用 比如这个PE引脚。我想用他输出PWM,但是不能用,我也重定义了,还是不能用。回去翻看了技术手册。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //重映射引脚功能,需…

Java面试题:volatile专题

王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 今天是《面霸的自我修养》第4篇文章,我们一起来看看面试中会问到哪些关于volatile的问题吧。数据来源: 大部分来自于各机构(Java之父,Java继父,某灵,某泡,某客)以及各博主整理文档…

解决Ubuntu中vscode右键没有create catkin package

右键发现没有这个create catkin package 解决方案: 查了一会发现安装个拓展就可以了 效果:

最新Unity游戏主程进阶学习大纲(2个月)

过完年了,很多同学开始重新规划自己的职业方向,找更好的机会,准备升职或加薪。今天给那些工作了1~5年的开发者梳理”游戏开发客户端主程”的学习大纲,帮助大家做好面试准备。适合Unity客户端开发者。进阶主程其实就是从固定的几个方面搭建好完整的知识体…

【Spring】创建和使用

目 录 一.创建 Spring 项目1.1 创建⼀个 Maven 项目1.2 添加 Spring 框架依赖1.3 手动创建启动类 二.将 Bean 对象存储到 Spring2.1创建Bean对象2.2将 Bean 存储到 Spring 三.获取并使用 Bean 对象3.1 创建 Spring 上下文3.2 获取指定的 Bean 对象3.3 使用 Bean 四.总结 经过前…

Elasticsearch:创建自定义 ES Rally tracks 的分步指南

作者:Alejandro Snchez 按照这个综合教程学习如何制作个性化的 Rally tracks ES Rally 是什么?它的用途是什么? ES Rally 是一个用于在 Elasticsearch 上测试性能的工具,允许你运行和记录比较测试。 做出决策可能很困难&#x…

体感互动游戏定制开发:创新与技术的交融

体感互动游戏是一种结合体感技术和游戏娱乐的新型形式,为玩家提供了更加身临其境的游戏体验。而要开发一款成功的体感互动游戏,需要一支跨学科的团队,他们将创新与技术有机地结合,以满足用户的需求和期待。 首先,游戏…

钉钉小程序 没有调用该接口的权限

钉钉小程序 没有调用该接口的权限 problem 钉钉官方自带免登陆小程序 后端接口报错 {"errcode":60011,"errmsg":"没有调用该接口的权限,接口权限申请参考:https://open.dingtalk.com/document/orgapp-server/add-api-permiss…

Flutter插件开发指南02: 事件订阅 EventChannel

Flutter插件开发指南02: 事件订阅 EventChannel 视频 https://www.bilibili.com/video/BV1zj411d7k4/ 前言 上一节我们讲了 Channel 通道,但是如果你是卫星定位业务,原生端主动推消息给 Flutter 这时候就要用到 EventChannel 通道了。 本节会写一个 1~…

C++ 二维差分 二维前缀和逆运算 差分矩阵

输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c ,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c 。 请你将进行完所有操作后的…

mfc140u.dll文丢失导致应用程序无法正常,有哪些解决办法

mfc140u.dll是Microsoft Foundation Classes(MFC)的一个重要组件,它提供了许多用于开发Windows应用程序的功能和工具。然而,当系统或应用程序升级、恶意软件感染或文件损坏以及用户错误操作等情况发生时,mfc140u.dll文…

力扣238和169

一:238. 除自身以外数组的乘积 1.1题目 1.2思路 1.3代码 //左右乘表 int* productExceptSelf(int* nums, int numsSize, int* returnSize) {int* answer (int*)malloc(numsSize*sizeof(int));int i 0;int left[numsSize],right[numsSize];left[0] 1;for(i 1;…

打码半年,开源一款自定义大屏设计软件!

hi,大家好,我是Tduck马马。 最近我们开源了一款大屏软件-TReport,与大家分享。 TReport是一款基于Vue3技术栈的数据可视化系统,支持静态、动态api等数据源;可用于数据可视化分析、报表分析、海报设计使用。 提供自定…

☀️将大华摄像头画面接入Unity 【1】配置硬件和初始化摄像头

一、硬件准备 目前的设想是后期采用网口供电的形式把画面传出来,所以这边我除了大华摄像头还准备了POE供电交换机,为了方便索性都用大华的了,然后全都连接电脑主机即可。 二、软件准备 这边初始化摄像头需要用到大华的Configtool软件&#…

哈希(哈希散列数据结构)---底层原理

Day02: 1.哈希散列数据结构:底层实现就是:数组链表(红黑树) map的put方法和get方法。 2.数组方法和链表存取数据的区别 数组方法:法随机访问快 链表:增删改效率快。 3.哈希结合了链表和数组的特性。 …

Sora后观察:AI大模型产业落地的八个锚点

在正在进行的2024年,国内大模型也将更下沉和落地,在技术上的突破之外,也会出现更多的向下的产业兼容和产业实践案例,作为新质生产力推动产业数字化转型的航船加速前进。 作者|斗斗 编辑|皮爷 出品|产业家 “电影讲述了一名…

关于深度学习和大模型的基础认知

这年头,作为一个技术人,话头里没有“大模型”,和人聊天都聊不下去。为了让自己和大家能更好的参与话头,特撰写此文,提供一些对大模型的基础认知能力(门外汉,浅尝辄止)。旨在解自己的…