OceanBase-【OBCP】认证-第二章 OB 存储引擎高级技术

第二章 OB 存储引擎高级技术

内存管理
内存数据落盘策略-合并和转储

LSM Tree 技术简介

LSM Tree(The Log-Structured Merge-Tree)核心特
点是利用顺序写来提高写性能
◼ 将某个对象(Partition)中的数据按照“key-value”
形式在磁盘上有序存储(SSTable)
◼ 数据更新先记录在MemStore中的MemTable里,然后
再合并(Merge)到底层的SSTable里
◼ SSTable和MemTable之间可以有多级中间数据,同样以
key-value形式保存在磁盘上,逐级向下合并



基于LSM Tree 的实践:合并

OceanBase中最简单的LSM Tree只有C0层(MemTable)和C1层(SSTable)。两层数据的合并过程如下:
1. 将所有observer上的MemTable数据做大版本冻结(Major Freeze),其余内存作为新的MemTable继续使用
2. 将冻结后的MemTable数据合并(Merge)到SSTable中,形成新的SSTable,并覆盖旧的SSTable
3. 合并完成后,冻结的MemTable内存才可以被清空并重新使用


合并的细化
合并按照合并的宏块的不同,可以细化为全量合并、增量合并,渐进合并三种方式:
◼ 全量合并:合并时间长,耗费IO和CPU。把所有的静态数据都读取出来,和动态数据归并,再写到磁盘中
◼ 增量合并:只会读取被修改过的宏块数据,和动态数据归并,并写入磁盘,对于未修改过的宏块,则直接重用
◼ 渐进合并:每次全量合并一部分,若干轮次后整体数据被重写一遍



基于LSM Tree 的实践:转储
为了解决2层LSM Tree合并时引发的问题(资源消耗大,内存释放速度慢等),OB引入了“转储”机制(C1层):
◼ 将MemTable数据做小版本冻结(Minor Freeze)后写到磁盘上单独的转储文件里,不与SSTable数据做合并
◼ 转储文件写完之后,冻结的MemTable内存被清空并重新使用
◼ 每次转储会将MemTable数据与前一次转储的数据合并(Merge),转储文件最终会合并到SSTable中


分层转储
为了优化转储越来越慢的问题,引入了“分层转储”机制:
◼ 多层compaction策略:新增L0 层:被冻结的MemTable 会
直接flush 为Mini SSTable,可同时存在多个Mini SSTable。
◼ 架构变化: 3层Vs 4层
⚫ 3层架构:memtable + minor sstable(L1) + major
sstable (L2)
⚫ 4层架构:memtable + mini sstable(L0) + minor
sstable(L1) + major sstable (L2)
◼ 参数minor_compact_trigger 控制L0层Mini SSTable 总数
◼ 参数major_compact_trigger 控制memtable dump flush次
数达到时触发major compaction


--------------------------------------------------------------

转储的基本概念
转储功能的引入,是为了解决合并操作引发的一系列问题
◼ 资源消耗高,对在线业务性能影响较大
◼ 单个租户MemStore使用率高会触发集群级合并,其它租户成为受害者
◼ 合并耗时长,MemStore内存释放不及时,容易造成MemStore满而数据写入失败的情况
转储的基本设计思路
◼ 每个MemStore触发单独的冻结(freeze_trigger_percentage)及数据合并,不影响其它租户
◼ 也可以通过命令为指定租户、指定observer、指定分区做转储
◼ 只和上一次转储的数据做合并,不和SSTable的数据做合并



转储相关参数
minor_freeze_times
◼ 控制两次合并之间的转储次数,达到此次数则自动触发合并(Major Freeze)
◼ 设置为0表示关闭转储,即每次租户MemStore使用率达到冻结阈值(freeze_trigger_percentage)都直接触发集群合并

minor_merge_concurrency
◼ 并发做转储的分区个数;单个分区暂时不支持拆分转储,分区表可加快速度
◼ 并发转储的分区过少,会影响转储的性能和效果(比如MemStore内存释放不够快)
◼ 并发转储的分区过多,同样会消耗过多资源,影响在线交易的性能



【转储适用的场景】

转储功能比较适用于以下场景

1. 批处理、大量数据导入等场景,写MemStore的速度很快,需要MemStore内存尽快释放
2. 业务峰值交易量大,写入MemStore的数据很多,但又不想在峰值时段触发合并(Major Freeze),希望能将合并延后

【转储场景的常用配置方法】

1. 减小freeze_trigger_percentage的值(比如40),使MemStore尽早释放,进一步降低MemStore写满的概率
2. 增大minor_freeze_times的值,尽量避免峰值交易时段触发合并(Major Freeze),将合并的时机延后到交易低谷时段的每日合并(major_freeze_duty_time)



转储对数据库的影响
转储的优势
◼ 每个租户的转储不影响observer上其它的租户,也不会触发集群级转储,避免关联影响
◼ 资源消耗小,对在线业务性能影响较低
◼ 耗时相对较短,MemStore更快释放,降低发生MemStore写满的概率
转储的副作用
◼ 数据层级增多,查询链路变长,查询性能下降
◼ 冗余数据增多,占用更多磁盘空间



手动触发转储

ALTER SYSTEM MINOR FREEZE
[{TENANT[=] (‘tt1' [, 'tt2'...]) | PARTITION_ID [=] 'partidx%partcount@tableid‘}]
[SERVER [=] ('ip:port' [, 'ip:port'...])];

◼ 可选的控制参数
	⚫ tenant : 指定要执行minor freeze的租户
	⚫ partition_id : 指定要执行minor freeze的partition
	⚫ server : 指定要执行minor freeze的observer
	
◼ 当什么选项都不指定时,默认对所有observer上的所有租户执行转储
◼ 手动触发的转储次数不受参数minor_freeze_times的限制,即手动触发的转储次数即使超过设置的次数,也不会触
发合并(Major Freeze)



查看转储记录
MemStore使用率达到freeze_trigger_percentage而触发的租户级转储,在__all_server_event_history表中


转储相关参数

major_compact_trigger /minor_freeze_times

• 控制两次合并之间的转储次数,达到此次数则自动触发合并(Major Freeze)。
• 设置为 0表示关闭转储,即每次租户MemStore使用率达到冻结阈值(freeze_trigger_percentage)
都直接触发集群合并。

minor_merge_concurrency
• 并发做转储的分区个数;单个分区暂时不支持拆分转储,分区表可加快速度。
• 并发转储的分区过少,会影响转储的性能和效果(比如MemStore内存释放不够快)。
• 并发转储的分区过多,同样会消耗过多资源,影响在线交易的性能。





OB合并触发方式-定时合并

由major_freeze_duty_time参数控制定时合并时间,可以修改参数控制合并时间:
alter system set major_freeze_duty_time='02:00';


OB合并触发方式-MemStore使用率达到阈值自动合并

当租户的MemStore内存使用率达到freeze_trigger_percentage参数的值, 并且转储的次数已经达到了minor_freeze_times参数的值,会自动触发合并。
◼ 通过查询(g)v$memstore视图来查看各租户的memstore内存使用情况
◼ 查转储次数:gv$memstore, __all_virtual_tenant_memstore_info 中freeze_cnt 列

OB合并触发方式-手动合并

可以在"root@sys"用户下,通过以下命令发起手动合并(忽略当前MemStore的使用率):
alter system major freeze;


◼ 合并发起以后,可以在"oceanbase"数据库里用以下命令查看合并状态:
select * from __all_zone; 或者select * from __all_zone where name = 'merge_status';


三种合并触发方式

• 定时合并 (自动合并)
• MemStore使用率达到阈值自动合并 (自动合并)
• 手动合并



OB合并方式:MemStore使用率达到阈值自动合并

当租户的 MemStore内存使用率达到freeze_trigger_percentage参数的值, 并且转储的次数已经达到了
major_compact_trigger/minor_freeze_times参数的值,会自动触发合并:

• 通过查询(g)v$memstore视图来查看各租户的memstore内存使用情况。

• 可以修改以下参数的值来影响触发合并的时机:

alter system set freeze_trigger_percentage = 40;
alter system set major_compact_trigger = 100;





OceanBase每日合并策略
合并调度
手动合并自动合并
自动轮转合并自动非轮转合并
智能轮转合并指定顺序的轮转合并

可通过以下几项控制每日合并的策略
◼ enable_manual_merge: OB的配置项,
指示是否开启手动合并
◼ enable_merge_by_turn: OB的配置项,
指示是否开启自动轮转合并
◼ zone_merge_order: 指定自动轮转合
并的合并顺序

OB轮转合并示例
假设集群中的设置是zone_merge_order = 'z1,z2,z3,z4,z5',zone_merge_concurrency = 3,一次轮转合并的大概
过程如下:

合并版本
设置SSTable中保留的数据合并版本个数
◼ 由参数max_kept_major_version_number控制,默认值为2。
◼ 调大参数值可以保留更多历史数据,但同时占用更多的存储空间。
◼ 在hint中利用frozen_version(<major_version>)指定历史版本。




设置轮转合并顺序

• 合并开始前,通过参数zone_merge_order设置合并顺序;只对轮转合并有效。

• 场景举例
假设集群中有三个zone,分别是z1,z2,z3,想设置轮转合并的顺序为"z1 -> z2 -> z3",步骤如下:

alter system set enable_manual_merge = false; -- 关闭手动合并
alter system set enable_merge_by_turn = true; -- 开启轮转合并
alter system set zone_merge_order = 'z1,z2,z3'; -- 设置合并顺序

• 取消自定义的合并顺序

alter system set zone_merge_order = ''; -- 取消自定义合并顺序



合并注意事项

合并超时时间

• 由参数zone_merge_timeout定义超时阈值;默认值为'3h'(3个小时)。

• 如果某个ZONE的合并执行超过阈值,合并状态被设置为TIMEOUT。

空间警告水位

• 由参数data_disk_usage_limit_percentage定义数据盘空间使用阈值,默认值90。

• 当数据盘空间使用量超过阈值后,合并任务打印ERROR警告日志,合并任务失败;需要尽快扩大数据盘物理空
间,并调大data_disk_usage_limit_percentage参数的值。

• 当数据盘空间使用量超过阈值后,禁止数据迁入。



查看合并记录和状态:

__all_rootservice_event_history表,查看合并记录:
__all_zone表,	查看当前合并状态:




小结
◼ OB的LSMTree可以分为C0层(MemTable)、C1层(Minor SSTable)、C2层(Major SSTable)
◼ OB内存通过双索引结构和数据压缩,提高数据的查询性能
◼ 合并和转储之前,都需要做一次冻结,然后根据参数设置决定冻结之后是转储还是合并
◼ 合并可以细分为全量合并、渐进合并、增量合并三种方式,同一个数据库,这三种方式对资源的消耗程度递减
◼ 为了优化转储越来越慢的问题,引入了“分层转储”机制,为了提高转储速度,加快内存释放速度,被冻结的
MemTable 会直接flush 为Mini SSTable
◼ 轮转合并可以轮流为每份副本单独做合并,减少业务影响,但同时也存在合并时间变长、切主过程中影响长连接等
问题
◼ 合并和转储特点的比较,两者互补共同组成了OB数据完整的落盘策略

  

posted @ 2024-08-26 18:40  上帝_BayaiM  阅读(20)  评论(0编辑  收藏  举报