OB有问必答 | OceanBase的内存管理是怎么做的?在实际的生产环境中是如何应用的?

简介: 本文介绍在实际的生产环境中OceanBase的内存管理策略

内存管理是C高性能服务器的核心问题。一些通用的内存管理库,比如Google TCMalloc在内存申请/释放速度、小内存管理、锁开销等方面都已经做得相当卓越了。然而,我们并没有采用。这是因为通用内存管理库在性能上毕竟不如专用的内存池,更为严重的是,它鼓励了开发人员忽视内存管理的陋习,比如在服务器程序中滥用C标准模板库(STL)。

在分布式存储系统开发初期,内存相关的Bug相当常见,比如内存越界,服务器出现Core Dump,这些Bug都非常难以调试。因此,这个时期内存管理的首要问题并不是高效,而是可控性,并防止内存碎片。

OceanBase系统有一个全局的定长内存池,这个内存池维护了由64KB大小的定长内存块组成的空闲链表。OceanBase的全局内存池实现简单,但内存使用率比较低,即使申请几个字节的内存,也需要占用大小为64KB的内存块。

因此,全局内存池不适合管理小块内存,每个需要申请内存的模块,比如UpdateServer中的memtable,ChunkServer中的缓存,等等,都只能从全局内存池中申请大块内存,每个模块内部再实现专用的内存池。每个线程处理读写请求时需要使用临时内存,为了提高效率,每个线程会缓存若干个大小分别为64KB和2MB的内存块,每个线程总是首先尝试从线程局部缓存中申请内存,如果申请不到,再从全局内存池中申请。

OceanBase的内存管理虽然没有采用高深的技术,但是已经很好地满足了系统初期的两个最主要的需求:可控性以及没有内存碎片。

那么,在实际的生产环境中OceanBase的内存管理策略是什么?

接下来我们为大家介绍三种最主要的场景:

1、OLTP场景
业务特点:读写RT敏感、数据一致性敏感、SQL多以key-value类型为主、范围查询及连表查询较少且也都走最优索引、读写比相差不大、业务存在明显高峰期。

场景解读:一般OLTP场景对读写RT要求严格,GB级OB库一般要求RT保证在10ms以内,TB级OB库甚至要求更低比如5ms。日常交易或者说事务要求严格保证数据一致性,如发生RT抖动,锁冲突骤增、极易发生业务数据错误。日常读写流量比基本上在3:1~1:1之间,且日常流量一般存在峰值,跟社会生活正常作息时间正相关。涉及行业一般有金融、电商、物流、社会各类服务业等。

配置推荐:对于此类场景的特点,一般需要将OB内存切换时间调整到最小,在日常流量峰值期间尽可能避免集群发生合并,而将日常合并时间尽量调整到业务低峰期保证集群合并对集群性能影响最小,具体推荐配置参数如下:
memory_limit=0(默认即可,即OB使用物理机操作系统内存上限由memory_limit_percentage参数决定)
memory_limit_percentage=80/90(根据物理机可用内存大小决定,512G以下的使用80%,512及以上的采用90%)
freeze_trigger_percentage=60~75%(根据读写比例判断,建议写越高则取数越趋近于memory_limit_percentage值,目的是能更多的存放dml数据到内存,减少转储和合并)
minor_freeze_times=3-8(根据每日dml量决定,转储可快速释放内存但也存在轻微抖动,转储速度取决于存储介质,ssd>hdd>sata)

2、OLAP场景
业务特点:读写RT可容忍在百毫秒甚至秒级、数据一致性不敏感(可容忍毫秒级节点间数据不一致,且分析型业务聚合计算数据都是万到百万级别量级)、SQL多以条件范围排序、连表聚合计算为主(此类AP查询SQL在OB中只需走分区键索引或主键即可)、读写比往往是读远小于写、仅读业务存在高峰期、写业务峰值往往有周期性或间歇性(主要原因为大多数AP类业务都有实时、离线周期性同步任务)。涉及行业一般有金融、电商、彩票、服务业、咨询、科学计算领域等,较AP类业务更常见。

配置推荐:对于此类场景的特点,一般需要将OB内存切换时间调整到尽可能小的程度以保证数据同步性能不受合并影响,但同时也要考虑到AP场景物理机存储介质对合并影响的问题。日常合并次数减少带来的一个问题就是合并时间也会增加(相比于每日开多轮转储和不开转储的情况)。所以这类场景需要结合存储介质进行决策,如采用ssd介质可相对增加转储次数,尽量将合并控制在数据同步低峰期;如采用sata慢速存储介质,可优化合并线程数并减少转储次数(类似于历史库场景),尽可能增加合并速度,减少合并对写入的影响。具体推荐配置参数如下:
memory_limit=0(默认即可,即OB使用物理机操作系统内存上限由memory_limit_percentage参数决定)
memory_limit_percentage=80(建议使用80的配置,保证更多内存分配到cache和sql线程等动态伸缩内存中,保证读数据正常返回)
freeze_trigger_percentage=60%(这里建议调小合并阈值,保证剩余内存能支持冻结后内存未释放期间的批量写入,从而不影响到同步写数据任务)
minor_freeze_times=3-5(该场景下建议ssd和hdd存储介质开启转储,转储可快速释放内存但也存在轻微抖动,转储速度取决于存储介质,ssd>hdd>sata,sata盘在此场景中不建议开启转储)

3、历史库场景
业务特点:读RT与TP类型业务无太大差异,对数据一致性敏感,但对写RT不敏感,SQL类型与TP类业务相似,多为key-value查询,偶尔有统计及聚合类SQL但量不大。读业务存在高峰期,写业务无绝对峰值但存在规律性(同步数据任务为主)。涉及行业及使用场景场景的有金融行业的冷备库、电商行业订单类冷备库等,主要作用为存放有价值的冷数据,提供数据回溯、历史记录查询、历史数据统计等,需保证读RT在毫秒级,写流量持续稳定,存储数据量级一般在TB甚至PB级,故一般存储介质采用sata盘。

配置推荐:根据此类场景的特点,需要控制OB在内存切换时不影响读性能,同时由于存储介质带宽比较低,故还需控制合并效率,参数如下:
memory_limit=0(默认即可,即OB使用物理机操作系统内存上限由memory_limit_percentage参数决定)
memory_limit_percentage=80(根据物理机可用内存大小决定,512G以下的使用80%,512及以上的采用90%)
freeze_trigger_percentage=80%(这里建议将合并阈值调到跟memstore参数一致,保证每日合并次数尽可能少)
minor_freeze_times=0(该场景多为sata盘,sata盘在此场景中不建议开启转储)
sys_bkgd_io_percentage = 90(调整系统IO线程占比到90,保证合并时数据盘带宽能开到最大)
merge_thread_count= 48(默认为0,即由租户线程自动分配合并线程,将其调整到48,使更多线程参与到合并中保证合并时间不会太久)

总结来说,使用OceanBase的过程中需要根据使用场景以及物理机型去调整内存管理参数,使集群性能与业务要求达到最佳匹配,在充分发挥出OceanBase内存表查询低RT的优势的同时,保证了在高可用前提下设备的最大利用率,在性能和性价比之间达到最佳均衡。

相关文章
|
4月前
|
DataWorks API 数据库
DataWorks操作报错合集之在使用 OceanBase (OB) 作为数据源进行数据集成时遇到报错,该如何排查
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
3月前
|
存储 SQL 缓存
揭秘Java并发核心:深度剖析Java内存模型(JMM)与Volatile关键字的魔法底层,让你的多线程应用无懈可击
【8月更文挑战第4天】Java内存模型(JMM)是Java并发的核心,定义了多线程环境中变量的访问规则,确保原子性、可见性和有序性。JMM区分了主内存与工作内存,以提高性能但可能引入可见性问题。Volatile关键字确保变量的可见性和有序性,其作用于读写操作中插入内存屏障,避免缓存一致性问题。例如,在DCL单例模式中使用Volatile确保实例化过程的可见性。Volatile依赖内存屏障和缓存一致性协议,但不保证原子性,需与其他同步机制配合使用以构建安全的并发程序。
69 0
|
21天前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
22天前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
45 2
|
19天前
|
运维 JavaScript Linux
容器内的Nodejs应用如何获取宿主机的基础信息-系统、内存、cpu、启动时间,以及一个df -h的坑
本文介绍了如何在Docker容器内的Node.js应用中获取宿主机的基础信息,包括系统信息、内存使用情况、磁盘空间和启动时间等。核心思路是将宿主机的根目录挂载到容器,但需注意权限和安全问题。文章还提到了使用`df -P`替代`df -h`以获得一致性输出,避免解析错误。
|
3月前
|
数据采集 Rust 安全
Rust在网络爬虫中的应用与实践:探索内存安全与并发处理的奥秘
【8月更文挑战第31天】网络爬虫是自动化程序,用于从互联网抓取数据。随着互联网的发展,构建高效、安全的爬虫成为热点。Rust语言凭借内存安全和高性能特点,在此领域展现出巨大潜力。本文探讨Rust如何通过所有权、借用及生命周期机制保障内存安全;利用`async/await`模型和`tokio`运行时处理并发请求;借助WebAssembly技术处理动态内容;并使用`reqwest`和`js-sys`库解析CSS和JavaScript,确保代码的安全性和可维护性。未来,Rust将在网络爬虫领域扮演更重要角色。
73 1
|
3月前
|
JavaScript 前端开发 Java
JavaScript内存泄露大揭秘!你的应用为何频频“爆内存”?点击解锁救星秘籍!
【8月更文挑战第23天】在Web前端开发中,JavaScript是构建动态网页的关键技术。然而,随着应用复杂度增加,内存管理变得至关重要。本文探讨了JavaScript中常见的内存泄露原因,包括意外的全局变量、不当使用的闭包、未清除的定时器、未清理的DOM元素引用及第三方库引发的内存泄露。通过了解这些问题并采取相应措施,开发者可以有效避免内存泄露,提高应用性能。
47 1
|
2月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
68 0
|
3月前
|
缓存 算法 Java
聚焦Java应用程序的内存管理和调优技巧
在现代软件开发中,性能优化对提升用户体验和系统稳定性至关重要。本文聚焦Java应用程序的内存管理和调优技巧。从理解Java内存模型入手,深入探讨堆内存的管理与优化,揭示如何避免内存泄漏,利用工具检测问题,并介绍高效字符串处理及数据结构选择的方法。同时,解析垃圾回收机制及其调优策略,包括不同回收器的选择与配置。此外,还介绍了调整堆大小、运用对象池和缓存技术等高级技巧。通过这些方法,开发者能有效提升应用性能和稳定性。
44 1