【OceanBase】20.内存数据罗盘机制-转储详解

1.基于 LSM Tree 的实践:转储

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

2)分层转储
为了优化转储越来越慢的问题,引入了“分层转储”机制:
◼ 多层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

3)转储的基本概念
转储功能的引入,是为了解决合并操作引发的一系列问题
◼ 资源消耗高,对在线业务性能影响较大
◼ 单个租户MemStore使用率高会触发集群级合并,其它租户成为受害者
◼ 合并耗时长,MemStore内存释放不及时,容易造成MemStore满而数据写入失败的情况

4)转储的基本设计思路
◼ 每个MemStore触发单独的冻结(freeze_trigger_percentage)及数据合并,不影响其它租户
◼ 也可以通过命令为指定租户、指定observer、指定分区做转储
◼ 只和上一次转储的数据做合并,不和SSTable的数据做合并


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

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

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

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

8)转储对数据库的影响
转储的优势
◼ 每个租户的转储不影响observer上其它的租户,也不会触发集群级转储,避免关联影响
◼ 资源消耗小,对在线业务性能影响较低
◼ 耗时相对较短,MemStore更快释放,降低发生MemStore写满的概率

转储的副作用
◼ 数据层级增多,查询链路变长,查询性能下降
◼ 冗余数据增多,占用更多磁盘空间

9)手动触发转储
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 表中查询:

手动转储,在__all_rootservice_event_history表中可以查到具体的选项


10)OB合并触发方式-定时合并
由major_freeze_duty_time参数控制定时合并时间,可以修改参数控制合并时间:
alter system set major_freeze_duty_time='02:00';
show parameters like '%major_freeze_duty_time%'\G;

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

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

12)OB合并触发方式-手动合并.
可以在"root@sys"用户下,通过以下命令发起手动合并(忽略当前MemStore的使用率):
alter system major freeze;
◼ 合并发起以后,可以在"oceanbase"数据库里用以下命令查看合并状态:
select * from __all_zone; 
--或者 
select * from __all_zone where name = 'merge_status';

13)查看 OB 集群合并和冻结状态 __all_zone

--全局信息
frozen_time 冻结时间
frozen_version 版本号,从1开始
global_broadcast_version:这个版本已经通过各ObServer进行合并。
is_merge_error 合并过程中是否出现错误
last_merged_version:表示上次合并完成的版本
try_frozen_version 正在进行哪个版本的冻结
merge_list Zone的合并顺序

--Zone相关信息 
all_merged_version :zone最近一次已经合并完成的版本
broadcast_version :本zone收到的可以进行合并的版本
is_merge_timeout:如果在一段时间还没有合并完成,则将此字段置为1,表示合并时间太长,
具体时间可以通过参数 zone_merge_timeout 来控制
merge_start_time / last_merged_time 合并开始、结束时间
merge_status 合并状态

--合并状态
IDLE 未合并
TIMEOUT 合并超时
MERGING 正在合并
ERROR 合并出错

14)轮转合并
借助自身天然具备的多副本分布式架构,OceanBase引入了轮转合并机制
◼ 一般情况下,OceanBase会有3份(或更多)数据副本;可以轮流为每份副本单独做合并
◼ 当一个副本在合并时,这个副本上的业务流量可以暂时切到其它没有合并的副本上
◼ 某个副本合并完成后,将流量切回这个副本,然后以类似的方式为下一个副本做合并,直至所有副本完成合并

15)关于轮转合并的更多说明

◼ 通过参数 enable_merge_by_turn 开启或者关闭轮转合并
◼ 以ZONE为单位轮转合并,只有一个ZONE合并完成后才开始下一个ZONE的合并;合并整体时间变长
◼ 某一个ZONE的合并开始之前,会将这个ZONE上的Leader服务切换到其它ZONE;切换动作对长事务有影响
◼ 由于正在合并的ZONE上没有Leader,避免了合并对在线服务带来的性能影响

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

enable_manual_merge=on:--手动合并
enable_manual_merge=off:--自动合并 
enable_manual_merge=off,enable_merge_by_turn=on:--自动轮转合并
enable_manual_merge=off,enable_merge_by_turn=off:--自动非轮转合并 
enable_manual_merge=off,enable_merge_by_turn=on,merge_list/zone_merge_order=on--智能轮转合并 
enable_manual_merge=off,enable_merge_by_turn=on,merge_list/zone_merge_order=off--指定顺序的轮转合并 

17)设置轮转合并顺序
合并开始前,通过参数 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 = ''; -- 取消自定义合并顺序

18)OB轮转合并示例
假设集群中的设置是zone_merge_order = 'z1,z2,z3,z4,z5',zone_merge_concurrency = 3,
一次轮转合并的大概过程如下:
事件/调度/并发合并的ZONE/合并完成的ZONE
1. 开始合并。/z1,z2,z3发起合并/z1,z2,z3/
2. 一段时间后,z2完成合并。/z4发起合并/z1,z3,z4/z2
3. 一段时间后,z3完成合并。/z5发起合并/z1,z4,z5/z2,z3
4. 一段时间后,全部ZONE完成合并。///z1,z2,z3,z4,z5

19)合并策略总结对比
合并策略:手动合并
调度策略:用户通过sql命令指定zone开始合并,需要用户自己控制并发度
如何开启:
	1.开启手动合并:alter system set enable_manual_merge = true;
	2.用户自主决定合并顺序和并发度,通过SQL命令调度zone合并,比如调度z1开始
	合并:alter system start merge zone = 'z1';
使用场景:纯手工操作,一般在业务每日合并出现问题、需要人工介入的情况下使用
注释:一旦开启,每一次合并都需要用户主动调度,除非关掉手动合并,开启自动合并

合并策略:自动非轮转合并  
调度策略:所有zone一起开始合并,没有并发度控制
如何开启:
	1.关闭手动合并:alter system set 	enable_manual_merge = false;
	2.关闭轮转合并:alter system set 	enable_merge_by_turn = false; 
使用场景: 当业务量比较小的情况下,合并中的zone也能支持业务流量时,则可以开
启自动非轮转合并,这样做能够避免用户跨表join请求变成分布式跨机查询
注释:每日合并会对业务请求产生一定的性能影响,需要业务进行确认

合并策略:自动指定顺序的轮转合并 
调度策略:用户直接指定轮转的顺序,RS只负责并发度控制
如何开启:各个版本实现有不同,具体看相关版本介绍
使用场景:一种特殊的轮转合并策略,一般不会使用,只有当智能轮转合并不满足业
务需求的情况下,才需要为集群定制特殊的合并调度策略
注释:在zone成员发生变更的情况下,自动指定顺序的轮转合并会失效,退化成智能轮转合并


合并策略:智能轮转合并
调度策略:RS根据一定策略依次调度zone合并,并进行并发度控制 
如何开启:
	1.关闭手动合并:alter system set 	enable_manual_merge = false;
	2.开启轮转合并:alter system set 	enable_merge_by_turn = true;

使用场景: 线上部署最常用的合并调度方案,轮转合并的过程中,RS会保证尽量不影
响业务的请求,通过切leader的方式,将用户读写路由到不在合并的zone中;

20)合并注意事项
--合并超时时间
◼ 由参数 zone_merge_timeout 定义超时阈值;默认值为'3h'(3个小时)
◼ 如果某个ZONE的合并执行超过阈值,合并状态被设置为TIMEOUT
--空间警告水位
◼ 参数 data_disk_usage_limit_percentage 定义数据文件最大可以写入的百分比(超出阈值后禁止数据迁入),
默认值90。
◼ 当数据盘空间使用量超过阈值后,合并任务打印ERROR警告日志,合并任务失败;需要尽快扩大数据盘物理空间,
并调大 data_disk_usage_limit_percentage 参数的值
◼ 当数据盘空间使用量超过阈值后,禁止数据迁入
◼ 参数 datafile_disk_percentage 定义数据盘空间使用阈值(占用data_dir所在磁盘总空间百分比),默认值90
◼ 参数 datafile_size 用于设置数据文件的大小,该配置项与 datafile_disk_percentage 同时配置时,
以该配置项设置的值为准,默认值为0

21)合并控制
合并线程数,由参数 merge_thread_count 控制
◼ 控制可以同时执行合并的分区个数;单分区暂不支持拆分合并,分区表可以加快合并速度。
◼ 默认值为0:表示自适应,实际取值为min(10,cpu_cnt * 0.3)。
◼ 最大取值不要超过48:值太大会占用太多CPU和IO资源,对observer的性能影响较大;
◼ 而且容易触发系统报警,比如CPU使用率超过90%可能会触发主机报警。
◼ 如对合并速度没有特殊要求,建议使用默认值0 。

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

select zone,svr_ip,major_version
from __all_virtual_partition_sstable_image_info
order by 1,2,3;

select /*+frozen_version(30)*/* from tmp1; 

23)查看合并记录和状态
通过__all_rootservice_event_history表,查看合并记录:
通过__all_zone表,查看当前合并状态:
	查看最近一次合并的版本号

24)转储&合并对比
--合并(Major freeze) 
集群级行为,产生一个全局快照,所有observer上所有租户的MemStore统一冻结。
MemTable数据和转储数据全部合并到SSTable中,完成后数据只剩一层,产生新的全量数据。
更新的数据量大(全部租户、全部observer、含SSTable),消耗较多的CPU和IO资源,MemStore内存释放较慢。
触发条件:单个租户的MemStore使用率达到 freeze_trigger_precentage,并且转储已经达到指定次数;
手工触发;定时触发。

--转储(Minor freeze)
以“租户+observer”为维度,只是MemTable的物化,每个MemStore独立触发冻结;
也可以通过手工命令,为特定的分区单独执行。
转储只与相同大版本的 Minor SSTable合并,产生新的MinorSSTable,所以只包含增量数据,
最终被删除的行需要特殊标记,不涉及SSTable数据,完成后有转储和SSTable两层数据。
更新的数据量小(单独租户、单独observer、不含SSTable),消耗的资源更少,可加快MemStore内存的释放。
触发条件:单个租户的 MemStore 使用率达到 freeze_trigger_precentage;手工触发

2.总结

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

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值