OceanBase分布式存储引擎公共模块——内存管理

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

OceanBase分布式存储引擎公共模块——内存管理

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

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

OceanBase系统有一个全局的定长内存池,这个内存池维护了由64KB大小的定长内存块组成的空闲链表,其工作原理如下:

  • 如果申请的内存不超过64KB,尝试从空闲链表中获取一个64KB的内存块返回给申请者;如果空闲链表为空,需要首先从操作系统中申请一批大小为64KB的内存块加入空闲链表。释放时将64KB的内存块加入到空闲链表中以便下次重用。
  • 如果申请的内存超过64KB,直接调用Glibc 的内存分配(malloc)函数,向操作系统申请用户所需大小的内存块。释放时直接调用Glibc的内存释放(free)函数,将内存块归还操作系统。

    OceanBase的全局内存池实现简单,但内存使用率较低,即使申请几个字节的内存,也需要占用大小为64KB的内存块。因此,全局内存池不适合管理小块内存,每个需要申请内存的模块,比如UpdateServer中的MemTable,ChunkServer中的缓存等,都只能从全局内存池中申请大块内存,每个模块内部再实现专用的内存池。每个线程会缓存若干个大小分别为64KB和2MB的内存块,每个线程总是首先尝试从线程局部缓存中申请内存,如果申请不到,再从全局内存池中申请。

class ObIAllocator
{
public:
    //内存申请接口
    virtual void* alloc (const int64_t sz) = 0;
    //内存释放接口
    virtual void free (void* ptr) = 0;
};
class ObMalloc : public ObIAllocator
{
public:
    //设置模块号
    void set_mod_id(int32_t mod_id);
    //申请大小为sz的内存块
    void * alloc (const int64_t sz);
    //释放内存
    void free (void* ptr);
}
class ObTCMalloc : public ObIAllocator
{
publilc:
    //设置模块号
    void set_mod_id(int32_t mod_id);
    //申请大小为sz的内存块
    void * alloc (const int64_t sz);
    //释放内存
    void free (void* ptr);
}

ObIAllocator 是内存管理器的接口,包含alloc和free两个方法。ObMalloc和ObTCMalloc是两个实现了ObIAllocator接口的全局内存池,不同点在于,ObMalloc不支持线程缓存,ObTCMalloc支持线程缓存。ObTCMalloc首先尝试从线程局部的空闲链表申请内存块,如果申请不到,在通过ObMalloc的alloc方法申请。释放内存时,如果没有超出线程缓存的内存块个数限制,则将内存块还给线程局部的空闲链表;否则,通过ObMalloc的free方法释放。另外,允许通过set_mod_id函数设置申请者所在的模块编号,便于统计每个模块的内存使用情况。

全局内存池的意义如下:

  • 全局内存池可以统计每个模块的内存使用情况,如果出现内存泄漏,可以很快定位到发生问题的模块。
  • 全局内存池可用于辅助调试。例如,可以将全局内存池中申请到的内存块按字节填充为某个非法的值(比如0xFE),当出现内存越界等问题时,服务器程序会很快在chu'xian'wen'ti'd出现问题的位置Core Dump,而不是带着错误运行一段时间后才Core Dump,从而方便问题定位。

总而言之,OceanBase的内存管理没有采用高深的技术,也没有做到通用或者最优,但是很好的满足了服务器程序开发的两个最主要的需求:可控性以及没有内存碎片。

目录
相关文章
|
4月前
|
存储 SQL 分布式数据库
OceanBase 入门:分布式数据库的基础概念
【8月更文第31天】在当今的大数据时代,随着业务规模的不断扩大,传统的单机数据库已经难以满足高并发、大数据量的应用需求。分布式数据库应运而生,成为解决这一问题的有效方案之一。本文将介绍一款由阿里巴巴集团自主研发的分布式数据库——OceanBase,并通过一些基础概念和实际代码示例来帮助读者理解其工作原理。
421 0
|
2月前
|
存储 数据采集 分布式计算
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
57 1
|
2月前
|
存储 缓存 数据处理
深度解析:Hologres分布式存储引擎设计原理及其优化策略
【10月更文挑战第9天】在大数据时代,数据的规模和复杂性不断增加,这对数据库系统提出了更高的要求。传统的单机数据库难以应对海量数据处理的需求,而分布式数据库通过水平扩展提供了更好的解决方案。阿里云推出的Hologres是一个实时交互式分析服务,它结合了OLAP(在线分析处理)与OLTP(在线事务处理)的优势,能够在大规模数据集上提供低延迟的数据查询能力。本文将深入探讨Hologres分布式存储引擎的设计原理,并介绍一些关键的优化策略。
149 0
|
5月前
|
Cloud Native Devops 数据库
云原生架构:未来软件开发的引擎深入理解操作系统的虚拟内存管理
【7月更文挑战第30天】在这篇文章中,我们将深入探讨云原生架构的概念,以及它如何改变软件开发的世界。我们将从云原生的基本概念开始,然后深入到它的关键技术和实践,最后讨论它对软件开发的未来影响。无论你是软件开发者,还是IT专业人士,这篇文章都将为你提供深入理解和掌握云原生架构的重要信息。 【7月更文挑战第30天】在数字世界的构建中,虚拟内存是操作系统不可或缺的一环。本文将探索虚拟内存的核心概念、工作机制及其对现代计算环境的重要性,同时揭示其背后的技术细节和面临的挑战。
54 3
|
4月前
|
Oracle 关系型数据库
分布式锁设计问题之Oracle RAC保证多个节点写入内存Page的一致性如何解决
分布式锁设计问题之Oracle RAC保证多个节点写入内存Page的一致性如何解决
|
4月前
|
SQL 监控 分布式数据库
【解锁数据库监控的神秘力量!】OceanBase社区版与Zabbix的完美邂逅 —— 揭秘分布式数据库监控的终极奥秘!
【8月更文挑战第7天】随着OceanBase社区版的普及,企业广泛采用这一高性能、高可用的分布式数据库。为保障系统稳定,使用成熟的Zabbix监控工具对其进行全方位监控至关重要。本文通过实例介绍如何在Zabbix中配置监控OceanBase的方法,包括创建监控模板、添加监控项(如TPS)、设置触发器及图形展示,并提供示例脚本帮助快速上手。通过这些步骤,可以有效监控OceanBase状态,确保业务连续性。
110 0
|
6月前
|
存储 搜索推荐 Java
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
微服务SpringCloud ES分布式全文搜索引擎简介 下载安装及简单操作入门
88 2
|
6月前
|
缓存 关系型数据库 MySQL
MySQL数据库——InnoDB引擎-架构-内存结构(Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer)
MySQL数据库——InnoDB引擎-架构-内存结构(Buffer Pool、Change Buffer、Adaptive Hash Index、Log Buffer)
113 3
|
6月前
|
关系型数据库 MySQL 数据库
深入OceanBase分布式数据库:MySQL 模式下的 SQL 基本操作
深入OceanBase分布式数据库:MySQL 模式下的 SQL 基本操作
|
6月前
|
存储 分布式数据库 数据库
深入OceanBase内部机制:分区构建高可用、高性能的分布式数据库基石
深入OceanBase内部机制:分区构建高可用、高性能的分布式数据库基石

热门文章

最新文章