关于OceanBase中旁路导入的应用分享

背景

前段时间,在用户现场协助进行OceanBase的性能测试时,我注意到用户常常需要运用 insert into select 将上亿行的数据插入到一张大宽表里,这样的批量数据插入操作每次都需要耗时半个小时左右。对这一情况,我提议用户尝试采用旁路导入的方式,结果不到五分钟就就完成了相同数据量的导入。虽然当时我表面保持冷静,但内心却充满喜悦。用户方的DBA同事们也半开玩笑地表示:“看来我们即将失去因导入数据而赢得的咖啡时间红利了。”

昨晚负责旁路导入研发的剑鸣同学分享了一次关于旁路导入的技术讲座。我借此机会写了一篇学习笔记,详细梳理了旁路导入的大致思路,并总结了用户在使用过程中需要注意的要点。

​​​​​​​

设计思路

目前,OceanBase主流使用三种导入方式:load data、obloader 和 oms,这些方式都使用 insert 语句将数据写入 OceanBase。然而,使用 insert 语句写入数据需要经过 SQL、事务和存储。OceanBase 使用 LSM-Tree 结构进行存储。在这种存储结构中,insert 语句会先将数据写入内存表中,然后经过多轮转储和合并,才能最终存入最底层的 SSTable 中。这些过程消耗了大量的系统资源,特别是 CPU 资源,因此导入数据的速度不够理想。为了加快导入速度,我们采用了一种绕过中间步骤的技术,将需要导入的数据直接写入最底层的 SSTable 中,这种技术称为旁路导入。此外,旁路导入还可以用于加速一些需要大量写入 SQL 的操作,例如背景中提到的 insert into select 语句。旁路导入的语法详见官网中几个相关的语法,例如 load data。

1705632762

根据上图所示,数据导入可采用两种路径,上方深蓝色箭头所示的传统路径需要经过 SQL查询、事务处理、数据存储等一系列模块。而下方的浅蓝色箭头所示旁路导入路径主要是对导入的数据进行类型转换(按需),然后按照主键进行排序(按需),最后将排序后的数据写入到 major sstable 中。旁路导入是一条短路径,能减少不少系统资源消耗,加快导入速度。(上图中的 LSM-tree 指的是 Log-Structured Merge Tree, 一种基于内存和磁盘的数据结构,用于高效地插入、删除和查询大量数据。SSTable 指的是 Sorted String Table, 一种有序、持久化存储数据的数据结构,可支持高效的读写操作和范围查询。)

实现原理

现在的旁路导入是利用 DDL 来实现的,可以认为是一种特殊类型的 DDL。

所以主要的执行流程和 DDL 类似(DDL 的实现原理可以详见夏进的这篇博客《OceanBase Alter Table 原理介绍》),旁路导入的实现分为了几个步骤:

    1. 创建 hidden table,用于导入
    2. 给原表和 hidden table 加表锁
    3. 把原表的数据和新导入的数据合并后写入 hidden table 中
    4. 在 hidden table 中重建原表的索引和外键
    5. 交换原表和 hidden table 的 table_id(如果中间任何一步出现错误,不交换 table id 就可以保证原子性,只有当全部步骤都成功,才会交换 table id)
    6. 解表锁

如果原表不是空表,已经有一些数据了,就会把原表里的数据和导入数据一起整合到 hidden table 里面。

例如下图中 tablet 是原表的 tablet,tablet' 是 hidden table 的 tablet,旁路导入会把原表的 memtable、sstale,以及导入的数据一起归并到新的 hidden table 里。

1705632779

例如通过 load data 命令进行旁路导入,整体的数据流向是:类型转换、根据分区键转发到对应节点、在节点上按需进行排序,最后写入 major sstable。

1705632790

我们在这里还对数据类型转换的优化、数据排序、解析 csv 等过程都做了大量的优化。

对于数据类型转换:例如 csv 文件里的内容是 string,但是实际的列类型是 number(在 MySQL 模式下相当于 decimal),这时候就需要根据 number format 进行一个非常复杂的隐式类型转换,我们在这里对隐式类型转换中的 to_number 函数最常用的一些 number format 进行了非常极致的短路优化,性能比直接调用 to_number 能提升四五倍的样子。

对于数据的排序:因为 OB 都是索引组织表,所以如果对于无主键表,是不需要进行排序的(写入时一个隐藏的 increment pk 列会自动保证有序),直接写入 major sstable 就可以了,这也就是无主键表比有主键表的旁路导入速度还能再快上几倍的原因。对于有主键表,那就不得不按照主键进行排序了,如果输入的数据已经是有序的(例如 csv 文件中的数据就有序),我们还提供了一个选项,支持用户通过指定要导入的数据是否有序来决定能否进行优化,如果已经有序,内部就只会做归并排序。完全无序时才会走完整的排序流程,无序时为了充分利用内存资源,我们会对数据进行一个归并的外排,首先先利用最大可用内存对数据进行排序,然后落盘,最后再对磁盘上的各个有序的数据文件进行一个多线程的归并排序,这样不仅可以充分利用内存资源,还可以有效减少落盘的次数。

1705632806

其他的优化由于篇幅关系,这里就不再详细描述了。

使用时需要注意的一些地方

用户在日常使用中,如果不了解目前旁路导入一些要注意的地方,很可能会遇到各种问题,以下就是使用旁路导入时需要注意的几个点:

1. 旁路导入期间会加表锁,表无法被写入其他数据,整个过程中表是只读的。

2. 旁路导入的实现是 DDL 而非 DML,这点要特别留意!

(1)按理说 insert into select 可以在事务里面的,但是例如 Oracle 的 DDL 如果出现在事务中,就会在 DDL 执行结束之后提交事务,然后再继续处理事务中的后面的内容,DDL 类似于事务中的一个 barrier。因为 DDL 在事务中的特殊表现,所以我们暂时不支持旁路导入出现在多行事务中,只能出现在 autocommit 的单行事务中,否则会报错 not supported。

(2)还有一个要注意的点是 DDL 框架比较重,导入 1 行数据可能就需要 2s,所以不适合用于导入量特别小的数据(例如 100M 以下的数据)。

(3)由于 DDL 实现逻辑的限制(在 RS 上会有一段儿逻辑需要串行执行),暂时不能很好地支持大规模多条旁路导入并行。比如并发执行几百个普通的 insert into select 是没问题的,但是并发执行几百个旁路导入的 insert into select,可能就会有一堆 DDL 排队等着 RS 的调度了。

这几个点确实给使用上带来了一些麻烦,不过我们后面会把它的实现方式给改成 DML。

3. 功能上支持增量导入,但是性能上可能不会特别理想。因为旁路导入的目标表如果在导入前已有数据,那么已有数据会被重写一遍。如果导入一个已有数据量很大的表,增量需要把原来的数据重写一遍,这时候可能并不划算。

4.如果租户的内存特别大,或者说数据量比 memtable 还要小,那内存的 memtable 就能兜住全部要导入的数据,旁路导入可能就没啥优势了。因为旁路导入是要写磁盘的,肯定比不过只写内存不需要转储、合并的场景

5. 4.2 版本 lob 列还不支持走旁路导入,不过后面即将发布的 4.3 版本已经支持了。

6. 使用 INSERT INTO SELECT 语句旁路导入数据时,只支持 PDML(Parallel Data Manipulation Language,并行数据操纵语言),非 PDML 不能用旁路导入,详见官网。

总结

最后总结一下,OB 目前的旁路导入功能,最适用于:

  1. 大表的首次导入场景;
  2. 10 GB~TB 级别的数据迁移场景;
  3. 还有就是 CPU 和 内存都不是特别充裕的场景,因为旁路导入的执行路径很短,可以省掉非常多的 CPU 开销。

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

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

相关文章

Class Re-Activation Maps for Weakly-Supervised Semantic Segmentation

摘要: 提取类激活映射(CAM)可以说是为弱监督语义分割(WSSS)生成伪掩码的最标准步骤。然而,我们发现伪掩码不理想的关键是在CAM中广泛使用的二进制交叉熵损失(BCE)。具体来说,由于BCE的池化方式是对类别求和,CAM中的每个像素可能对…

Java | 时间日期API

大家好,我是程序员影子 一名致力于帮助更多朋友快速入门编程的程序猿 今天来聊一聊关于Java 中的时间日期API 一、使用LocalDate和LocalTime Java 8 引入了java.time包,其中LocalDate和LocalTime类用于处理日期和时间。 import java.time.LocalDate…

Linux课程____进程管理

记录工作日志 script 240319.log CTRLd 退出 cat 240319.log //查看 一、查看进程 1.静态 ps -aux ps -elf 2.动态 top 3.pgrep 查看特定条件的进程 pgrep -l “log” pgrep -l "ssh" pgrep -l -U redhat 4.pstree 查看进程树 pstree -aup 所有…

【Linux更新驱动、cuda和cuda toolkit】

目录 1. 更新显卡驱动1.1. 查看当前显卡驱动版本1.2. 删除原始显卡驱动1.3. 删除CUDA Toolkit1.4. 在NVIDIA官网找到2080Ti对应的最新驱动程序 2. 更新CUDA Toolkit2.1. 下载CUDA Toolkit2.2. 安装.run2.3. 添加环境变量2.4. 检查是否安装好了 最近需要更新服务器的显卡驱动和C…

10 Internet基本服务(3)

1.SMTP 邮件传递过程3 阶段 (1)连接建立阶段 在这一阶段,SMTP 客户机请求与服务器的25 端口建立一个TCP 连接。一旦连接建立,SMTP 服务器和客户机就幵始相互通拫自己的域名,同时确认对方的域名;&a…

目标检测——PP-YOLOv2算法解读

PP-YOLO系列,均是基于百度自研PaddlePaddle深度学习框架发布的算法,2020年基于YOLOv3改进发布PP-YOLO,2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet,2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列,所以放一起解…

Fork - 将 GitHub 的某个特定仓库复制到自己的账户下

Fork - 将 GitHub 的某个特定仓库复制到自己的账户下 1. ForeverStrongCheng/OpenCV-tutorials2. Fork -> ForeverStrongCheng/R2CNN_Faster-RCNN_TensorflowReferences 访问仓库页面,点击 Fork 按钮创建自己的仓库。 Fork 是将 GitHub 的某个特定仓库复制到自己…

BetterDisplay Pro for Mac(显示器校准软件) v2.0.11激活版

BetterDisplay Pro是一款由waydabber开发的Mac平台上的显示器校准软件,可以帮助用户调整显示器的颜色和亮度,以获得更加真实、清晰和舒适的视觉体验。 软件下载:BetterDisplay Pro for Mac v2.0.11激活版 以下是BetterDisplay Pro的主要特点&…

【No.8】蓝桥杯工具函数模板|迭代器|vector|queue|map|set|银行问题|费里的语言|快递分拣(C++)

迭代器讲解线性表的使用队列的使用集合(set)的使用映射(map)的使用 迭代器(Iterator) 迭代器是 C 的知识,但是下面讲容器就要用到这一点,所以我们必须要提前讲一下。迭代器的知识点…

ideaSSM 工程车辆人员管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 工程车辆人员管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具 有完整的源代码和数据库&…

uniapp 云开发省钱之调整函数执行内存大小

我这个5块钱一个月的服务空间配置: 现在还只有少量的用户和自己测试之用,目前消耗的情况: 云函数的使用量还是挺高的,目前还是正好能覆盖一个月的使用量,等用户量上来肯定是不行的,所以得想想办法压榨一下云…

玩转C语言——深入理解指针

一、指针概念 1.1 内存和地址 在开始学习指针前,我们先来讲一个例子,假如你身处一栋楼中,你点了一份外卖,那么,外卖员如何能找到你?有两种方法。法一:直接一间一间找,这样做不仅消耗…

【Auth Proxy】为你的 Web 服务上把锁

Auth Proxy 一个极简的用于 Web 服务鉴权的反向代理服务 极其简约的 UI对你的真实服务无任何侵入性支持容器部署,Docker Image 优化到不能再小(不到 9MB)GitHub:https://github.com/wengchaoxi/auth-proxy 效果 我在 http://lo…

幻兽帕鲁游戏搭建(docker)

系列文章目录 第一章: 幻兽帕陆游戏搭建 文章目录 系列文章目录前言一、镜像安装1.创建游戏目录2.拉取镜像3.下载配置文件4.启动游戏 二、自定义配置总结 前言 这段时间一直在写论文还有找工作,也没学啥新技术,所以博客也很长时间没写了&am…

【YOLOv5改进系列(2)】高效涨点----Wise-IoU详细解读及使用Wise-IoU(WIOU)替换CIOU

WIOU损失函数替换 🚀🚀🚀前言一、1️⃣ Wise-IoU解读---基于动态非单调聚焦机制的边界框损失1.1 🎓 介绍1.2 ✨WIOU解决的问题1.3 ⭐️论文实验结果1.4 🎯论文方法1.4.1☀️Wise-IoU v11.4.2☀️Wise-IoU v21.4.3☀️…

原子操作好多问

一. 何谓"原子操作": 原子操作是指在执行过程中不会被中断或干扰的操作,是不可分割的操作单元,要么全部执行成功,要么全部不执行。 二. 为什么关注原子操作: 关注原子操作是为了确保多线程并发访问共享资源时的数据一致性&#xf…

算法笔记p335堆

目录 堆定义堆建堆(以大顶堆为例)删除堆顶元素插入元素 堆排序排序思路代码实现 堆 堆是一颗完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子结点的值。 大顶堆:父亲结点的值大于或等于孩子结点…

jmeter之并发和顺序执行与特殊线程组-第四天

1.jmeter的并发执行 并发执行:多个线程同时执行,不能确定谁先结束 以上案例中http请求里面没有写任何内容,只是为了看这个并发执行的效果 2.jmeter的顺序执行 顺序执行:多个线程顺序执行 再测试计划中勾选“独立运行每个线程组…

VBA之Word应用:利用Bookmark属性返回选择区域的开始和结束位置

《VBA之Word应用》(版权10178982),是我推出第八套教程,教程是专门讲解VBA在Word中的应用,围绕“面向对象编程”讲解,首先让大家认识Word中VBA的对象,以及对象的属性、方法,然后通过实…

什么是子网掩码、ip地址的网段?如何区分?

IP地址优化网写了很多相关的文章。 有些朋友对于子网掩码、IP地址网段等还不太了解,我们来看看网友经常问到的一些相关问题。 255.255.255.192 的位掩码是什么? 1.什么是子网掩码? 在了解IP地址的网段之前,我们先来了解一下子网…