当前位置: 首页 > news >正文

聊聊OceanBase合并和转储

相比于Oracle、MySQL等传统的数据库,OceanBase数据库的存储引擎采用 LSM-Tree 的架构,这种存储引擎和之前所使用到的堆结构或B+树结构有很大的差别,今天我们就来聊聊 LSM-Tree 存储引擎所引入的合并和转储相关的功能特点。

OB 存储引擎的分层结构

LSM-Tree 存储引擎分为静态基线数据 (SSTable) 和动态增量数据 (MemTable)。这种架构本质上是一个基线加增量的存储引擎,SSTable 中存储的基线数据是只读的,一旦生成就不能修改,这部分数据是保存在磁盘上的;MemTable 是增量数据,应用程序数据的增量修改都保存在 MemTable,这部分数据是保存在内存中的。内存的数据并不是持久的,为了防止意外宕机导致内存数据丢失,在写入 MemTable 时还会同步将变更写入到在线日志,通过 Paxos 协议来保障数据的一致性。

MemTable 中的数据是按照 BTree 和 HashTable 的方式组织的,数据以B树结构进行存储,B树索引中的数据都是有序的,能够更好的支持范围查询,但对于点查等单行查询的场景,B树需要进行大量的主键检索,性能会比较差。为了满足点查等更多场景的需要,还增加了哈希索引结构,实现对单行查询的优化。每次事务执行时,MemTable 会自动维护B树和哈希索引之间的数据一致性。

![[Pasted image 20240915090506.png]]

用户表每个分区管理数据的基本单元是 SSTable,当 MemTable 大小达到某个阈值后,OceanBase 会将 MemTable 冻结,然后将其中的数据转存于磁盘上,转储后的结构就称为 SSTable。

OceanBase 将磁盘切分为大小 2MB 的定长数据块,称之为宏块,宏块是数据文件写 I/O 的基本单位,也是转储合并以及复制迁移等任务的基本粒度单位。

在宏块内部数据被组织为多个默认 16KB 大小的变长数据块,称之为微块,微块是数据文件读 I/O 的最小单位。数据最终是存储在微块中的,每个微块在构建时都会更加用户指定的压缩算法进行压缩,读取时会自动将数据解压后放入数据缓存中。

OB 存储引擎的合并转储

内存空间终究是有限的,这也意味着 MemTable 不可能无限保存在内存中,为此 LSM-Tree 存储引擎提供了转储和合并的机制,当 MemTable 的大小超过一定阈值时,需要将 MemTable 中的数据转存到 SSTable 中以释放内存,这一过程称之为 转储。转储会生成新的 SSTable,当转储的次数超过一定阈值时,或者在每天的业务低峰期,系统会将基线 SSTable 与之后转储的增量 SSTable 给合并为一个 SSTable,这一过程称之为 合并

合并

最简单的 LSM Tree 只有两层: C0 层 (MemTable) 和 C1 层 (SSTable),其合并过程如下:

  • 将所有 OBServer 上的 MemTable 数据做大版本冻结,其余内存作为新的 MemTable 继续使用;
  • 将冻结后的 MemTable 数据合并到 SSTable 中,形成新的的 SSTable,并覆盖旧的 SSTable;
  • 合并完成后,冻结的 MemTable 内存才可以被清空并重新使用。

按照合并宏块的不同,合并可以细化为全量合并、增量合并和渐进合并三种方式,其中:

  • 全量合并,是把所有的静态数据都读取出来,和动态数据合并。全量合并消耗 I/O 和 CPU 资源,合并时间长;
  • 增量合并,只会读取被修改过的宏块,和动态数据合并,对于未修改过的宏块,直接重用;
  • 渐进合并,每次全量合并一部分,若干轮次后整体数据被重写一遍。

为了满足不同场景的需求,OceanBase 支持多种方式的合并触发模式。

  • 定时合并,可以结合业务系统的特点,指定合并的触发时间,如凌晨2点;
  • 手工合并,可以在需要的时候手工触发合并,释放内存;
  • 自动合并,当租户 MemStore 内存使用率达到 freeze_trigger_percentage 参数设定值,并且转储次数达到 minor_freeze_times 参数设定值,则触发自动合并。需要注意的是,手工触发的转储并不会增加 minor_freeze_times 的计数。

此外,在合并过程中还支持轮转合并,利用分布式多副本的特点,轮流为每份副本单独做合并。

转储

合并是集群性的全局操作,合并过程时间较长,系统整体的资源消耗也很高,对于业务侧影响比较大,因此 OceanBase 又引入了转储机制。每个 OBServer 节点的租户可以独立决定自己 MemTable 的冻结操作,主备分区不需要保持一致。转储过程中的主要操作如下:

  • 将 MemTable 数据做小版本冻结后写到磁盘上单独的转储文件里,不与 SSTable 数据做合并;
  • 转储文件写完之后,冻结的 MemTable 内存被清空并重新使用;
  • 每次转储会将 MemTable 数据与前一次转储的数据合并,最终合并到 SSTable 中。

通过转储引入中间层,避免单个租户 MemStore 使用率过高触发集群级的全量合并,使得其他租户成为受害者。

转储的触发方式分为自动触发和手工触发两种。当 MemStore 内存使用率达到设定阈值,会触发自动冻结,然后系统内部再调度转储;此外也可以通过手工的方式发起转储动作,手工转储支持指定租户、分区和 OBServer 进行转储。

合并和转储相关的参数

为了便于大家查阅,相关的合并和转储参数汇总如下。

参数名称参数描述默认值
minor_freeze_times控制两次合并之间的转储次数,设置为0表示关闭转储功能100
minor_merge_concurrency并发做转储的分区个数0,表示并发线程数为 min[10,cpu_cnt]
freeze_trigger_percentage设定租户MemStore使用率阈值,达到设定值则触发合并70,V4.0之后调整为20
major_freeze_duty_time指定每日定时合并的时间02:00
enable_merge_by_turn是否开启轮转合并False
enable_manual_merge是否开启手工合并False
zone_merge_order指定自动轮转合并的合并顺序NULL
zone_merge_timeout定义合并的超时时间3h
data_disk_usage_limit_percentage定义数据文件最大可写入的百分比90
datafile_disk_percentage定义磁盘空间使用阈值90

http://www.mrgr.cn/news/27614.html

相关文章:

  • 嵌入式交叉编译:glib(未成功)
  • jdk1.7的hashmap为什么会出现死循环问题
  • Lambda常用方法
  • Vue3 动态获取 assets 文件夹图片
  • 能源革命持续发力,华普微隔离器助力储能行业“向绿向新”
  • SPIRiT-Diffusion:基于自一致性驱动的加速MRI扩散模型|文献速递-基于深度学习的病灶分割与数据超分辨率
  • 无线通信感知/雷达系统算法专业技术栈
  • 155K Star,Python 入门到进阶最佳学习资源
  • 算法参数对拥塞控制的影响
  • 攻击者如何在日常网络资源中隐藏恶意软件
  • 【STM32系统】基于STM32设计的SD卡数据读取与上位机显示系统(SDIO接口驱动、雷龙SD卡)——文末资料下载
  • Python [ GUI编程自学 ],虽然但是,还是想出一个系列
  • 跨境电商代购新纪元:一键解锁全球好物,系统流程全揭秘
  • 使用 PyCharm 新建 Python 项目详解
  • c语言写的环形队列
  • 基于BiGRU+Attention实现风力涡轮机发电量多变量时序预测(PyTorch版)
  • 三种mybatis表的列名和对象属性名不一致处理方法
  • java项目之基于工程教育认证的计算机课程管理平台(源码+论文)
  • F5设备绑定EIP
  • 【Vue】2
  • 国风编曲:了解国风 民族调式 五声音阶 作/编曲思路 变化音 六声、七声调式
  • Qt:懒汉单例(附带单例使用和内存管理)
  • 【软考】扩充的ER模型
  • Autosar E2E通信保护简介
  • QT添加图标标题和打包项目
  • 差分算法搞不懂?这篇文章带你飞