OpenGauss与NVM
  lYE0sTgD5uUi 2023年11月02日 52 0

OpenGauss与NVM

[openGauss](javascript:void(0);) 2023-08-07 18:00 发表于中国香港

以下文章来源于yanzongshuaiDBA ,作者yzshover

OpenGauss与NVM_hash表

yanzongshuaiDBA.

专注于MySQL、PostgreSQL等开源数据库

OpenGauss与NVM

NVM(非易失性内存),也叫PM(持久内存)具有可字节寻址、大容量、非易失型和堪比DRAM的速度等特性。随着英特尔傲腾产品的出世,现有数据库适配这种新型硬件显得更加有必要。

OpenGauss在这方面也做了探索,实现了DRAM-PM-DISK三层存储架构。当然,实现方式参考了2018年SIGMOD会议的一篇论文《Managing Non-Volatile Memory in Database Systems》,感兴趣可以查看。我们这里介绍下OpenGauss中的DRAM-PM-DISK三层存储架构。

1、当前存储架构问题

当前opengauss的架构是DRAM-DISK,也就是面向磁盘的数据库。当数据量大于shared_buffers时,共享内存的数据页淘汰流程就会称为瓶颈。甚至于导致共享内存淘汰数据页处的逻辑占用CPU较高,进而影响pagewriter线程刷写,让淘汰更慢,影响正常工作。

引入持久内存PM,形成buffer pool的三层DRAM-PM-DISK架构的设计,利用成本相对较低的PM对shared_buffers进行扩容,可减少淘汰流程的触发。并且,还通过数据页的访问频率来控制各个缓存层之间的页面迁移,实现热数据在DRAM,温数据在PM,冷数据在DISK。

2、OpenGauss启用PM的相关配置项

1)enable_nvm:启用nvm buffer管理。默认是false

2)nvm_buffers:设置nvm buffer大小,即BLCKSZ的个数

3)nvm_file_path:指定NVM的路径,因为NVM以-o dax方式挂载(跳过操作系统缓存)后,需要将其map到内存。

4)bypass_dram:控制by pass内存的概率

5)bypass_nvm:控制by nvm的概率

3、OpenGauss的DRAM-PM-DISK架构实现机制

OpenGauss与NVM_描述符_02

整体架构如上图所示,shared buffer pool由两部分组成:DRAM buffer pool和NVM buffer pool,统一由buffer管理器进行管理。用户后台线程可以访问DRAM也可以访问NVM。NVM中的页根据访问热度会迁移到DRAM。

3.1 buffer pool

OpenGauss与NVM_hash表_03

Buffer pool中的block分为3部分:DRAM部分、NVM部分和SEG buffer blocks。这里我们只关注DRAM和NVM。

(1)buffer pool的初始化

OpenGauss与NVM_描述符_04

在共享内存中申请BufferBlocks,若开启nvm,则通过nvm_init来初始化NVM的BufferBlocks。NVM通过mmap操作将NVM设备映射到内存。映射大小由nvm_buffers配置项控制:

#define TOTAL_BUFFER_NUM (SEGMENT_BUFFER_NUM + NORMAL_SHARED_BUFFER_NUM + NVM_BUFFER_NUM)#define NVM_BUFFER_NUM (g_instance.attr.attr_storage.NNvmBuffers):对应nvm_buffers

这里为什么不适应pmdk呢?pmdk在用户态管理NVM可以减少内存上下文的切换,比mmap更具有优势。

(2)BufferAlloc的申请

OpenGauss与NVM_hash表_05

1)ReadBuffer_common完成数据页的读取。通过BufferAlloc来判断是否在内存中命中需要的页,若命中则返回该内存块的描述符。未命中的话,就需要调用ReadBuffer_common_ReadBlock将磁盘上的页通过smgrread加载到内存。当然这里是加载到DRAM还是NVM,则由buf描述符来指定。需要观察BufferAlloc函数实现机制

2)BufferAlloc函数:开启NVM时,通过NvmBufferAlloc函数获取buf描述符

3)NvmBufferAlloc机制:

(1)因为NVM和DRAM都是内存,由t_thrd.storage_cxt.SharedBufHash哈希表统一管理,所以首先从这个hash表中查询需要的页,看下是否在内存

(2)若在hash表中没找到则表示没在内存中命中,则根据是否bypassnvm来决定使用哪块的buf描述符:bypassnvm:使用DRAM块的buf描述符;否则使用NVM处的描述符。

(3)若在hash表中找到,则表示内存中命中。进一步判断:Buf id位于[0,NvmBufferStartID)是DRAM的块,位于[NvmBufferStartID,SegmentBufferStartID)的是NVM的块。

(4)命中DRAM的块,直接使用

(5)命中NVM的块,bypassdram,直接使用

(6)命中NVM的块,非bypassdram,则需要将NVM的块拷贝到DRAM。这里同样使用memcpy,使用pmdk的函数效果更好。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

lYE0sTgD5uUi