本文由巨杉数据库北美实验室资深数据库架构师撰写,主要介绍巨杉数据库的并发malloc实现与架构设计。原文为英文撰写,我们提供了中文译本在英文之后。

SequoiaDB Concurrent malloc Implementation

Introduction

In a C/C++ application, the dynamic memory allocation function malloc(3) can have a significant impact on the application’s performance. For multi-threaded applications such as a database engine, a sub-optimal memory allocator can also limit the scalability of the application. In this paper, we will discuss several popular dynamic memory allocator, and how SequoiaDB addresses the dynamic memory allocation problem in its database engine.

dlmalloc/ptmalloc

The GNU C library (glibc) uses ptmalloc, which is an allocator forked from dlmalloc with thread-related improvement. Memories are allocated as chunks, which is 8-byte aligned data structure containing a header and usable memory. This means there is at least an 8 or 16 byte overhead for memory chunk management. Unallocated memory is grouped by similar sizes and maintained by a double-linked list of chunks.

jemalloc

Originally developed by Jason Evans in 2005, jemalloc has since been adopted by FreeBSD, Facebook, Mozilla Firefox, MariaDB, Android and etc. jemalloc is a general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. In order to avoid lock contention, jemalloc uses separate memory pool “arenas” for each CPU, and threads are assigned to an arena to handle malloc requests.

tcmalloc

TCMalloc is a malloc developed by Google. It reduces lock contention for multi-threaded programs by utilizing thread-local storage for small allocations. For large allocations, mmap or sbrk can be used along with fine grained and efficient spinlocks. It also has garbage-collection for local storage of dead threads. For small objects allocation, TCMalloc requires just one-percent space overhead for 8-byte objects, which is very space-efficient.

Here is a test done to compare the performance of jemalloc and tcmalloc. The test involves 500 iterations of performing 1000 memory allocation, then free these 1000 memory. As seen both of them have very similar performance.

SequoiaDB Implementation

In SequoiaDB 3.4, it implements its own proprietary memory allocator, which is highly efficient and tailored for the memory usage within the SequoiaDB database engine. While jemalloc and tcmalloc are both excellent general purpose memory allocator, they cannot address all the challenges that are encountered within SequoiaDB. For example, the ability to trace memory requests is an important requirement in SequoiaDB engine, and this feature is lacking in existing third-party memory allocators. Figure 2 shows the architecture of the SequoiaDB memory model. There are three layers - thread, pool and OSS (Operating System Services).

OSS Layer

The OSS layer provides malloc API which requests memory from the underlying operating system. This is also where the pool layer gets the memory from.

Pool Layer

The pool layer is a global memory pool which contains segments of different size. A segment is a contiguous memory block that is allocated from the OSS Layer. Each segment is divided into fixed-size chunks. By default there are 32-byte, 64, 128…8092-byte chunk-size. Requests above the 8092-byte max chunk-size threshold will be serviced by the OSS layer.

Thread Layer

The thread layer is a thread-local cache, with each thread having its own private cache, therefore memory allocation can be done in a lock-free manner. Memory chunks are grouped together by their chunk size, implemented using a linked-list. Memory chunks are requested and cached from the pool layer up to a configured threshold. For memories exceeding this threshold, they are released back to the pool layer, and can be reused by other threads. This design helps limit the overall memory footprint. In addition, each thread has a single elastic-big-block, which is used to service requests above max chunk-size threshold. Therefore, in most cases requests can be fulfilled in the thread layer, which is efficient and fast.

In addition, the SequoiaDB memory model also has built-in memory-debugging capability to detect memory corruption. It also has a trace feature which can track down where memories are being requested from. On top of that, it is fully configurable, and allow deployment to be customized according to customers workload and environment.

以下为中文译本

介绍

在 C / C ++ 应用程序中,动态内存分配函数 malloc(3) 会对应用程序的性能产生重大影响。对于诸如数据库引擎之类的多线程应用程序,优化不足的内存分配器也会限制应用程序的可伸缩性。在本文中,我们将讨论几种流行的动态内存分配器,以及 SequoiaDB 如何解决其数据库引擎中的动态内存分配问题。

dlmalloc/ptmalloc

GNU C 库 (glibc) 使用 ptmalloc,它是从 dlmalloc 派生的具有线程相关改进的分配器。内存被分配为块,这是 8byte 对齐的数据结构,其中包含标头和可用内存。这意味着内存块管理至少有 8 或 16byte 的开销。未分配的内存按相似的大小分组,并由块的双向链接列表维护。

jemalloc

jemalloc 最初由 Jason Evans 于2005年开发,此后已被 FreeBSD,Facebook,Mozilla Firefox,MariaDB,Android 等采用。jemalloc 是通用的 malloc(3) 实现,主要特点是避免碎片化和可扩展的并发支持。为了避免锁竞争,jemalloc 为每个 CPU 使用单独的内存池“区域”,并且将线程分配给区域以处理 malloc 请求。

tcmalloc

TCMalloc 是 Google 开发的 malloc。通过利用线程本地存储进行小的分配,它减少了多线程程序的锁争用。对于较大的分配,可以将 mmap 或 sbrk 与细粒度且高效的自旋锁一起使用。它还具有垃圾收集功能,用于死线程的本地存储。对于小对象分配,TCMalloc 仅需要8个字节对象的百分之一的空间开销,这非常节省空间。

这是一个测试,用于比较 jemalloc 和 tcmalloc 的性能。该测试涉及500次迭代以执行1000个内存分配,然后释放这1000个内存。如图所示,它们两者的性能十分接近。

SequoiaDB的实现

在 SequoiaDB  中(以 SequoiaDB v3.4 作为例子),它实现了自己专有的内存分配器,该分配器高效且针对 SequoiaDB 数据库引擎中的内存使用量身定制。尽管 jemalloc 和 tcmalloc 都是出色的通用内存分配器,但它们无法解决 SequoiaDB 内部遇到的所有挑战。例如,跟踪内存请求的能力是 SequoiaDB 引擎的一项重要要求,而现有的第三方内存分配器缺少此功能。图2显示了 SequoiaDB 内存模型的体系结构。共有三层-线程,池和 OSS(操作系统服务)。

OSS Layer

OSS 层提供了 malloc API,该 API 向底层操作系统请求内存。这也是 PoolLayer 从中获取内存的位置。

Pool Layer

Pool Layer 是全局内存池,其中包含不同大小的段。段是从 OSS 层分配的连续内存块。每个段分为固定大小的块。默认情况下,有32字节,64、128…8092字节的块大小。超过8092字节最大块大小阈值的请求将由 OSS 层处理。

Thread Layer

线程层是线程本地缓存,每个线程都有其自己的专用缓存,因此可以无锁方式完成内存分配。内存块按其块大小分组在一起,使用链接列表实现。从 Pool Layer 请求内存块并将其缓存到配置的阈值。对于超过此阈值的内存,它们将释放回 Pool Layer 并可以由其他线程重用。

此设计有助于限制整体内存占用。此外,每个线程都有一个弹性大块,用于服务超过最大块大小阈值的请求。因此,在大多数情况下,可以在线程层中满足请求,这既高效又快速。

此外,SequoiaDB 内存模型还具有内置的内存调试功能,可以检测内存损坏。它还具有跟踪功能,可以跟踪从哪里请求内存。最重要的是,它是完全可配置的,并允许根据客户的工作量和环境自定义部署。

【巨杉数据库SequoiaDB】巨杉Tech | 巨杉数据库的并发 malloc 实现的更多相关文章

  1. 【巨杉数据库SequoiaDB】24 Hours , 数据库研发实录

    出场人物: ​ ​ 08:10 ​ 小H,是巨杉数据库引擎研发的一名工程师.7:20 天还蒙蒙亮,小H就起床了,点亮了心爱的光剑,开始了新的一天. ​ 在08:10时候,他已经洗漱完,锻炼好身体,倒好 ...

  2. 【巨杉数据库SequoiaDB】巨杉Tech | 分布式数据库千亿级超大表优化实践

    01 引言 随着用户的增长.业务的发展,大型企业用户的业务系统的数据量越来越大,超大数据表的性能问题成为阻碍业务功能实现的一大障碍.其中,流水表作为最常见的一类超大表,是企业级用户经常碰到的性能瓶颈. ...

  3. 【巨杉数据库SequoiaDB】巨杉Tech | 四步走,快速诊断数据库集群状态

    1.背景 SequoiaDB 巨杉数据库是一款金融级分布式数据库,包括了分布式 NewSQL.分布式文件系统与对象存储.与高性能 NoSQL 三种存储模式,分别对应分布式在线交易.非结构化数据和内容管 ...

  4. 【巨杉数据库SequoiaDB】巨杉Tech | 巨杉数据库数据高性能数据导入迁移实践

    SequoiaDB 一款自研金融级分布式数据库产品,支持标准SQL和分布式事务功能.支持复杂索引查询,兼容 MySQL.PGSQL.SparkSQL等SQL访问方式.SequoiaDB 在分布式存储功 ...

  5. 【巨杉数据库SequoiaDB】社区分享 | SequoiaDB + JanusGraph 实践

    本文来自社区用户投稿,感谢小伙伴的技术分享 项目背景 大家好!在春节这段时间里,由于一直在家,所以花时间捣鼓了一下代码,自己做了 SequoiaDB 和 JanusGraph 的兼容扩展工作. 自己觉 ...

  6. 【巨杉数据库SequoiaDB】为“战疫” 保驾护航,巨杉在行动

    2020年,我们经历了一个不平静的新春,在这场大的“战疫”中,巨杉数据库也积极响应号召,勇于承担新一代科技企业的社会担当,用自己的行动助力这场疫情防控阻击战! 赋能“战疫”快速响应 巨杉数据库目前服务 ...

  7. 【巨杉数据库SequoiaDB】巨杉数据库 v5.0 Beta版 正式发布

    2020年疫情的出现对众多企业运营造成了严重的影响.面对突发状况,巨杉利用长期积累的远程研发协作体系,仍然坚持进行技术创新,按照已有规划­­推进研发工作,正式推出了巨杉数据库(SequoiaDB) v ...

  8. 【巨杉数据库SequoiaDB】省级农信国产分布式数据库应用实践

    本文转载自<金融电子化> 原文链接:https://mp.weixin.qq.com/s/WGG91Rv9QTBHPsNVPG8Z5g 随着移动互联网的迅猛发展,分布式架构在互联网IT技术 ...

  9. 【巨杉数据库SequoiaDB】巨杉数据库荣获《金融电子化》“金融科技创新奖”

    巨杉助力金融科技创新 2019年12月19日,由<金融电子化>杂志社主办.北京金融科技产业联盟协办的“2019中国金融科技年会暨第十届金融科技及服务优秀创新奖颁奖典礼”在京成功召开.来自金 ...

随机推荐

  1. 2020牛客寒假算法基础集训营4 E:最小表达式

    E:最小表达式 考察点 : 贪心,高精度 坑点 : 高精度一定不要写错,一定一定不要写错 剩下的就是细节问题 侃侃 : 1.字符串长度达到 5e5,如果要涉及到加法,乘法,普通的肯定会爆 long l ...

  2. vs 中明明包含了头文件所在路径,但是却找不到头文件

    vs基本不会出错,那么出错的只能是自己了. 哎,又被自己给蠢死了. 你可能在上面两个地方添加好了include 目录,但是却依然编译失败,失败的提示是找不到头文件所在路径,这是为什么呢. 很简单,因为 ...

  3. 用赋值表达式作为bool值

    enum Status { stOk, stQuit, stError }; int main() { Status status; int n; bool b1 = (status = stOk); ...

  4. Mac安装Mysql-python遇到的坑,被这俩报错反复摩擦:'my_config.h' file not found 和 IndexError: string index out of range

    最后Stackoverflow上面的大神解决了问题: Link brew install mysql brew unlink mysql brew install mysql-connector-c ...

  5. mysql添加远程权限

    mysql -u root -p grant all privileges on *.* to root@'%' identified by "password"; flush p ...

  6. javascript HierarchicalTaskAnalysis-hta编程(.hta)

    main.hta  code: <script>window.resizeTo(400,300);</script> <head> <hta:applicat ...

  7. FastDFS 原理介绍

    1 功能简介         FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适 ...

  8. 学习CSS之如何改变CSS伪元素的样式

    一.CSS伪元素 CSS 伪元素用于向某些选择器设置特殊效果. 伪元素的用法如下: selector:pseudo-element {property:value;} CSS 类也可以和伪元素搭配使用 ...

  9. 解决pycharm打开html页面一直刷新

    顺序——> File ——>Project:项目名——>project Structure 右侧的 + Add ContentRoot下面只保留本项目路径,其他全删了 方法2(推荐) ...

  10. 【转】Redis内部数据结构详解 -- skiplist

    本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...