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

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的内存管理没有采用高深的技术,也没有做到通用或者最优,但是很好的满足了服务器程序开发的两个最主要的需求:可控性以及没有内存碎片。

时间: 2024-07-28 13:26:01

OceanBase分布式存储引擎公共模块——内存管理的相关文章

OceanBase分布式存储引擎公共模块——基础数据结构

OceanBase分布式存储引擎公共模块--基础数据结构 1.哈希表 为了提高随机读取性能,UpdateServer支持创建哈希索引,这个哈希索引结构就是LightlyHashMap,代码如下: template <typename Key, typename Value> class LightlyHashMap { public: //插入一个<key,value>对到哈希表 inline int insert(const Key& key, const Value&a

Apache Spark 内存管理详解

Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 Spark 内存管理的脉络,抛砖引玉,引出读者对这个话题的深入探讨.本文中阐述的原理基于 Spark 2.1 版本,阅读本文需要读者有一定的 Spark 和 Java 基础,了解 RDD.Shuffle.JVM 等相关概念. 在执行 Spark 的应用程序时,Spark 集群会启动 Driver

MongoDB源码概述——内存管理和存储引擎

原文地址:http://creator.cnblogs.com/ 数据存储: 之前在介绍Journal的时候有说到为什么MongoDB会先把数据放入内存,而不是直接持久化到数据库存储文件,这与MongoDB对数据库记录文件的存储管理操作有关.MongoDB采用操作系统底层提供的内存文件映射(MMap)的方式来实现对数据库记录文件的访问,MMAP可以把磁盘文件的全部内容直接映射到进程的内存空间,这样文件中的每条数据记录就会在内存中有对应的地址,这时对文件的读写可以直接通过操作内存来完成(而不是fr

MySQL · 引擎特性 · InnoDB 文件系统之IO系统和内存管理

综述 在前一篇我们介绍了InnoDB文件系统的物理结构,本篇我们继续介绍InnoDB文件系统的IO接口和内存管理. 为了管理磁盘文件的读写操作,InnoDB设计了一套文件IO操作接口,提供了同步IO和异步IO两种文件读写方式.针对异步IO,支持两种方式:一种是Native AIO,这需要你在编译阶段加上LibAio的Dev包,另外一种是simulated aio模式,InnoDB早期实现了一套系统来模拟异步IO,但现在Native Aio已经很成熟了,并且Simulated Aio本身存在性能问

[share]深入探讨PHP中的内存管理问题

一. 内存 在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = "hello world "; ?>"即可,并且该字符串能够被自由地修改.拷贝和移动.而在C语言中,尽管你能够编写例如"char *str = "hello world ";"这样的一个简单的静态字符串:但是,却不能修改该字符串,因为它生存于程序空间内.为了创建一个可操纵的字符串,你必须分配一个内存块,并且通过一个函数(

通过案例深入探讨PHP中的内存管理问题

问题  内存管理对于长期运行的程序,例如服务器守护程序,是相当重要的影响:因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要.本文将重点探讨PHP的内存管理问题. 一. 内存 在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = 'hello world '; ?>"即可,并且该字符串能够被自由地修改.拷贝和移动.而在C语言中,尽管你能够编写例如"char *str = "hello world ";&

深入探讨PHP中的内存管理问题

摘要 内存管理对于长期运行的程序,例如服务器守护程序,是相当重要的影响:因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要.本文将重点探讨PHP的内存管理问题. 一. 内存 在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = 'hello world '; ?>"即可,并且该字符串能够被自由地修改.拷贝和移动.而在C语言中,尽管你能够编写例如"char *str = "hello world ";&q

解析PHP中的内存管理,PHP动态分配和释放内存

本篇文章是对PHP中的内存管理,PHP动态分配和释放内存进行了详细的分析介绍,需要的朋友参考下   摘要 内存管理对于长期运行的程序,例如服务器守护程序,是相当重要的影响:因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要.本文将重点探讨PHP的内存管理问题. 一. 内存在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = 'hello world '; ?>"即可,并且该字符串能够被自由地修改.拷贝和移动.而在C语言中,尽管你能够

介绍Amazon分布式存储引擎Dynamo

Dynamo 是 Amazon 公司的一个分布式存储引擎. 那么这个什么引擎又是什么?首先,假设一个场景,你的网站要存储用户登陆的IP.这个问题怎么解决呢?传统的方法是用数据库.数据库提供了方便的操作接口,复杂的查询能力以及事物的保证.好,现在假设大家都很喜欢你的网站,访问的人越来越多.一个数据库已经处理不过来了.于是你安装了3台数据库主机,把用户分成了三类(男人,女人,IT人;总是有某种方法把用户分成数目大致差不多的几个部分吧).每次访问的时候,先看用户属于哪一类,然后直接访问存储那类用户数据