您当前的位置:首页 > 电脑百科 > 数据库 > 百科

怎样让数据库再快一点?

时间:2020-10-09 09:49:53  来源:  作者:

本文来源:微信公众号:腾讯云数据库

原文地址:https://mp.weixin.qq.com/s?__biz=Mzg4NjA4NTAzNQ==&mid=2247488667&idx=1&sn=c1d3f497b2f31699a41ae6b4e8080feb

作者 张鹏义,腾讯云数据库高级工程师,曾参与华为Taurus分布式数据研发及腾讯CynosDB for PG研发工作,现从事腾讯云redis数据库研发工作。

存储体系结构

回顾一下计算机的存储体系结构。正如下图所示,计算机存储设备根据访问速度及容量等形成了一个金字塔形的层次结构。在这个层次结构中,从上到下,设备的访问时延越来越大,容量也越来越大,而每字节的造价也越来越便宜。在这个层次结构中,每一层都被看作是其下一层次的缓存。

怎样让数据库再快一点?

 

同时在这个层次结构中存在一个明显的分界线,如图中绿色的虚线。在分界线以上都是易失性的设备,掉电数据丢失,CPU通过load/store指令访问存储设备,即数据直接以cache line(64 byte)的粒度从寄存器中copy到存储设备中,或者从存储设备中copy到寄存器。而分界线以下都是可持久化的存储设备,通过向I/O控制器发送命令,以block的粒度将数据换入换出到DRAM中,然后才能直接被CPU访问。

随着近互联网的发展,数据密集型应用已然成为主流,其主要特点表现为数据容量大,对数据分析的实时性及数据存储的高效性提出了更高的要求,以spark、redis为代表的基于内存的数据分析与存储系统广受欢迎。

但是DRAM的容量受限于晶体管-电容式(1T1C)单元的密度,以及难以扩展的动态刷新(refresh)操作,DRAM的容量没办法做得很大,服务器上主流的DRAM一般为16G或32G,容量再大功耗相应也会增加。而且DRAM的价格比较高,数据不能持久化。

对于SSD等一些块设备来说,确实能够满足大容量持久化的要求,但是访问延迟却是DRAM的1000多倍,同时块设备存在随机访问能力比较差的问题。虽然近些年来出现了以rocksdb/leveldb为代表的LSM-Tree结构的存储系统从一定程度上解决了块设备低效的写问题,但同时又引入了一个比较严重的写放大问题。

SSD与DRAM的访问延迟差异导致在分界线处形成了一条巨大的鸿沟,持久化内存的出现正好给填补上了。

持久化内存在存储体系层次结构中的位置如下图所示,它位于DRAM与SSD之间,同时注意到它是横跨在分界线上的, 它模糊了传统层次结构中内存与外存的边界 ,它既具有DRAM一样的数据访问方式,也具有SSD一样的持久化特性。所以可以把它当成内存或者持久化的存储使用。

怎样让数据库再快一点?

 


怎样让数据库再快一点?

 

Intel optane DC persistent memory是Intel推出的基于3D Xpoint技术的持久化内存产品,其代号为Apace Pass (AEP)。AEP的物理封装为DIMM,直接插在内存插槽上,单条AEP的容量目前已经达到了512G,如上图所示,如果一半的插槽插上AEP,那么单个CPU内存容量很轻松的就可以扩展到3TB以上。IMC(integrated memory controller)与AEP之间以cache line大小的粒度传输数据,但是AEP的ECC(E rror correction code ) size为256字节,即AEP内部的controller与介质之间是以256字节(4个cache line)为单位进行读写。同时AEP的读写不对称,读性能明显优于写性能,所以应该避免频率的写入小对象。

AEP工作模式

AEP有两种工作模式:Memory Mode和App Direct Mode,如果细分就还有Storage Over App Direct。

怎样让数据库再快一点?

 

一、Memory Mode

根据AEP在存储层次结构中所处的位置,自然想到的是将DRAM作为AEP的缓存,AEP中的热数据缓存在DRAM中,这也符合计算机存储系统一惯的设计思想。在这种模式下AEP和DRAM共同组成了一块对上层透明且容量更大的易失性内存,这时系统的总容量等于AEP的容量,应用无需做任何额外的修改即可使用。DRAM到AEP的缓存算法由IMC(集成在CPU里的memory controller)硬件管理。

当前的缓存策略采用 direct-mapped-cache 算法实现, 数据以cache line的粒度换入换出,但是这种算法会把AEP中多块内存映射到DRAM中的同一个位置,以致于在某些场景下出现冲突不命中的情况可能比较严重。所以这么一个通用的算法并不能很好地将热数据从AEP中分离出来。

Memory Mode配置方法:


ipmctl create -goal memorymode=100 (ipmctl是Intel开发的一个管理持久化内存的工具)
reboot后 free -g 就可以看到系统内存容量等于AEP的总容量。

二、AppDirect Mode

应用可以不经过DRAM而直接访问AEP,用由应用自己管理,这种使用方式叫做AppDirect Mode。那么在这种模式下应用怎么访问AEP?SNIA(Storage Networking Industry Association)制定了一套编程模型,如下图所示,其中NVDIMM指非易失性内存模块,即AEP设备。

怎样让数据库再快一点?

 

传统的文件系统都有一层page cache, 访问数据时先将数据copy到page cache中,然后再copy到应用buffer 中。对于低延迟及可按字节寻址的AEP来说,没这个必要。Pmem-Aware File System指的是支持直接访问设备(DAX)的文件系统,DAX特性从IO路径上移除page cache, 同时允许mmap()直接建立到持久化内存的映射关系。目前ext4和xfs都已支持DAX特性。

AppDirect Mode配置方法:
ipmctl create -goal PersistentMemoryType=appdirect
reboot (reboot后就可以在/dev下看到pmem0,pmem1设备)
ndctl create-namespace -m fsdax -r 0
mkfs -t ext4 /dev/pmem0
mount -o dax /dev/pmem0 /mnt/pmem0 (-o dax开启DAX)

配置完成后就可以在/mnt/pmem0下创建、删除、读写文件了,但是一般不会直接这么使用。通常在/mtn/pmem0/上通过mmap建立memory-map file, 一旦映射建立后,用户虚拟地址空间通过MMU就直接映射到AEP的物理空间中,应用无需陷入内核态即可高效地以字节寻址的方式访问AEP。再借助于libmemkind库,就可像使用DRAM一样来使用AEP。Libmemkind将create/open file, mmap进行了封闭,并提供类malloc/free的接口在AEP上分配内存。所以应用需要显示通过类malloc/free接口决定哪些数据直接写到AEP,对已经代码要做一定的修改。

要注意的是mmap必须是以shared的方式建立映射,如果是以private的方式映射,更新数据时并不会写到介质上,而是写到进程私有的空间中(page cache中),然而这里AppDirect模式下是没有page cache的。这里引出了一个问题:如果进程在AEP中分配了一块内存,然后fork一个子进程,那么子进程也是能够看到父进程对这块内存的更新,因为两个父子进程的更新都会立即反映到同一块物理内存上。所以对于分配在AEP上的内存就没办法利用fork的copy on write机制来获取一致性的内存状态。(Redis正是利用fork的copy on write机制获取一对致性内存状态做备份操作)。

AppDirect下即可以将AEP当作易失性的内存使用也可以当作持久化的内存使用。当作易失性内存使用时,仅仅是我们不关注重启后AEP上的数据内容而已,并不是指掉电后AEP上的内容真的丢失了。如果当持久化的内存使用,则应用需要处理持久化及数据一致性等问题,下节详细讲。

三、Storage over App Direct

如上图中的第三、四条路径,分别对外提供block接口和标准的文件接口,应用无需额外的适配工作,这和使用SSD并没有什么区别,仅仅是延迟更小。但是这种使用方式软件栈上的开销所占的比例相当大,并不能发挥出很好发挥出AEP的极致性能,基本不用考虑这种用法,除非是已有代码确实不能改动但又想获得低延迟访问的情况。

当作持久化内存使用时应用需关注的问题

一、数据持久化

当一条store指令完成后,数据并没有立即写到DIMM介质上,很有可能还存在于cpu cache中或者Memory Controller的Write Pending Queue中,掉电后还是会造成数据丢失,也就说这里是一个异步的持久化过程。所以应用需要显示flush cpu cache和WPQ后才能说明数据确实已经持久化,当然在Intel平台上ADR模块掉电后会触发硬件中断到Memory Controller并flush WPQ中的数据到DIMM介质上。即Intel平台上关注cpu cache就好。clflush、clflushopt、clwb指令都是用于flush cpu cache, 其中clflushopt、clwb是为了提升持久化内存的flush效率新引入的,不一定所有平台都支持。其中clflush是串行flush, 而clflushopt可以并行flush, clwb与clflush类似,只是并不一定会立即失效cache line,提升后续读性能。

怎样让数据库再快一点?

 

由于CPU乱序执行和cpu cahe 并行flush问题可能会导致两个数据对象实际在介质上持久化的顺序与应用写入的顺序相反,如果说这两个数据数据对象具有因果关系,那就出大问题了。

如下面这段代码,如果list->length修改后的值所在的cache line先被flush到介质,而在list->tail->next修改后的值还未flush到介质之前机器掉电,重启后根据list->length再去遍历list就可能会造成崩溃。

typedef struct List {
    int length;
    struct List* head;
    struct List* tail;
};


typedef struct Node {
    void * data;
    struct Node* next;
}Node;


void appendList(List* list, Node* node){
    list->tail->next = node;
    list->tail = node;
    list->length++;
}

正确的做法是在flush(&(list->length))之前加上fence指令确保持久化的先后顺序。

void appendList(List* list, Node* node){
    list->tail->next = node;
    list->tail = node;
    __mm_clwb(&(list->tail->next));
    __mm_clwb(&(list->tail));
    __mm_sfence();    //
    list->length++;
    __mm_clwb(&(list->length));
}

二、数据一致性

在X86平台上,仅不大于8字节的对象能够保证是原子写,大于8字节的数据对象可能写到一半出现机器掉电,重启后的数据是否完整无法得知。所以应用需要通过flag/redo log/undo log等方式判断数据是否完整,以及不完整时该怎么去处理,当然这势必会引入比较重的开销。

再比如将Redis的索引结构(hash table)及数据都写入到持久化内存中,那么当用户写入一条数据时,内部可能发生hash table扩容,hash entry搬迁等多个动作,要维护数据的一致性问题,那就也需要引入类似mini transaction的机制。所以把AEP当作持久化内存与易失性内存来使用时性能肯定是一定的差异的。

一旦考虑把AEP当作持久化的内存来使用时,所写下的每一行代码都考虑怎么处理数据一致性的问题,这并不是一件容易的事情。

为了简化持久化内存在AppDirect下的使用,Intel开发了 PMDK (Persistent Memory Development Kit)。我们可以直接在PMDK的基础上去开发自己的应用,但是这些通用的库也并不一定适合所有场景。

怎样让数据库再快一点?

 

下面这几个库用的比较多一些:

1. libpmem: 用来将数据持久化到介质上,以及提供一些优化的内存操作(memcpy, memset等)函数。


2. libpmemlog: 基于这个库可以用来写顺序追加的log等。


3. ibpmemobj: 这个库实现了一套事务机制,用来保证数据的一致性问题。

最后用一张图总结一下AEP的使用方式及在数据领域潜在的价值。

怎样让数据库再快一点?

 

本文来源:微信公众号:腾讯云数据库

原文地址:https://mp.weixin.qq.com/s?__biz=Mzg4NjA4NTAzNQ==&mid=2247488667&idx=1&sn=c1d3f497b2f31699a41ae6b4e8080feb

作者 张鹏义,腾讯云数据库高级工程师,曾参与华为Taurus分布式数据研发及腾讯CynosDB for PG研发工作,现从事腾讯云Redis数据库研发工作。



Tags:数据库   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
安装环境Linux服务器:Centos 6 64位Oracle服务器:Oracle11gR2 64位 系统要求说明:内存必须高于1G的物理内存;交换空间,一般为内存的2倍(1G的内存可以设置swap 分区为3G大小);硬...【详细内容】
2021-12-27  Tags: 数据库  点击:(2)  评论:(0)  加入收藏
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的HasorDB 是一个全功能数据库访问工具,提供对象映射、丰...【详细内容】
2021-12-22  Tags: 数据库  点击:(5)  评论:(0)  加入收藏
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22  Tags: 数据库  点击:(3)  评论:(0)  加入收藏
读取SQLite数据库,就是读取一个路径\\192.168.100.**\position\db.sqlite下的文件<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/...【详细内容】
2021-12-16  Tags: 数据库  点击:(21)  评论:(0)  加入收藏
测试的目的和原因,公司有很多程序员,每个程序员对数据库和表结构都有自己的理解。而且每个程序员的理解往往是以效率考虑。既然都是为了效率考虑,那么我就来测试一下究竟哪种使...【详细内容】
2021-12-08  Tags: 数据库  点击:(14)  评论:(0)  加入收藏
当你们考虑项目并发的时候,我在部署环境,当你们在纠结使用ArrayList还是LinkedArrayList的时候,我还是在部署环境。所以啊,技术不止境,我在部环境。今天这篇文章缕一下在同一台服...【详细内容】
2021-12-08  Tags: 数据库  点击:(16)  评论:(0)  加入收藏
概述DBConvert Studio 是一款强大的跨数据库迁移和同步软件,可在不同数据库格式之间转换数据库结构和数据。它将成熟、稳定、久经考验的 DBConvert 和 DBSync 核心与改进的现...【详细内容】
2021-11-17  Tags: 数据库  点击:(26)  评论:(0)  加入收藏
说明Web应用程序,MySQL数据库,数据库中有三张表:health_patient(病人表)、health_patient_account(病人账户表)、 health_patient_medical_history(病例表),视图需求是,页面分页展示病...【详细内容】
2021-11-05  Tags: 数据库  点击:(32)  评论:(0)  加入收藏
1. 介绍1.1 介绍今天开始我们来学习Java操作MySQL数据库的技巧,Java操作MySQL是借助JdbcTemplate这个对象来实现的。JdbcTemplate是一个多数据库集中解决方案,而我们今天只讲...【详细内容】
2021-11-05  Tags: 数据库  点击:(30)  评论:(0)  加入收藏
互联网时代,不论是个人还是组织,都将数据视为一项重要的资产。为了便于存储、管理,企业常常会为各项数据建立一个数据库,如果没有做好安全风险防护,一旦数据库被攻占,企业将迎来很...【详细内容】
2021-10-28  Tags: 数据库  点击:(50)  评论:(0)  加入收藏
▌简易百科推荐
1增1.1【插入单行】insert [into] <表名> (列名) values (列值)例:insert into Strdents (姓名,性别,出生日期) values (&#39;开心朋朋&#39;,&#39;男&#39;,&#39;1980/6/15&#3...【详细内容】
2021-12-27  快乐火车9d3    Tags:SQL   点击:(1)  评论:(0)  加入收藏
最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫, 不知道各种写法孰优孰劣,该选用哪种写法,以及各种写法的优缺点,本文以一个简单的查询...【详细内容】
2021-12-23  linux上的码农    Tags:sql   点击:(9)  评论:(0)  加入收藏
《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的HasorDB 是一个全功能数据库访问工具,提供对象映射、丰...【详细内容】
2021-12-22  GitHub精选    Tags:HasorDB   点击:(5)  评论:(0)  加入收藏
作者丨Rafal Grzegorczyk译者丨陈骏策划丨孙淑娟【51CTO.com原创稿件】您是否还在手动对数据库执行各种脚本?您是否还在浪费时间去验证数据库脚本的正确性?您是否还需要将...【详细内容】
2021-12-22    51CTO  Tags:Liquibase   点击:(3)  评论:(0)  加入收藏
场景描述:由于生产环境的表比较复杂,字段很多。这里我们做下简化,只为说明今天要聊的问题。有两张表 tab1,tab2: tab1 数据如下: tab2 数据如下: 然后给你看下,我用来统计 name=&#3...【详细内容】
2021-12-20  Bald    Tags:SQL   点击:(5)  评论:(0)  加入收藏
前言知识无底,学海无涯,知识点虽然简单,但是比较多,所以将MySQL的基础写出来,方便自己以后查找,还有就是分享给大家。一、SQL简述1.SQL的概述Structure Query Language(结构化查...【详细内容】
2021-12-16  谣言止于独立思考    Tags:SQL基础   点击:(13)  评论:(0)  加入收藏
前言作为一名测试工程师,工作中在对测试结果进行数据比对的时候,或多或少要和数据库打交道的,要和数据库打交道,那么一些常用的 SQL 查询语法必须要掌握。最近有部分做测试小伙...【详细内容】
2021-12-14  柠檬班软件测试    Tags:SQL   点击:(15)  评论:(0)  加入收藏
话说C是面向内存的编程语言。数据要能存得进去,取得出来,且要考虑效率。不管是顺序存储还是链式存储,其寻址方式总是很重要。顺序存储是连续存储。同质结构的数组通过其索引表...【详细内容】
2021-12-08  小智雅汇    Tags:数据存储   点击:(17)  评论:(0)  加入收藏
概述DBConvert Studio 是一款强大的跨数据库迁移和同步软件,可在不同数据库格式之间转换数据库结构和数据。它将成熟、稳定、久经考验的 DBConvert 和 DBSync 核心与改进的现...【详细内容】
2021-11-17  雪竹聊运维    Tags:数据库   点击:(26)  评论:(0)  加入收藏
一、前言 大家好,我是小诚,《从0到1-全面深刻理解MySQL系列》已经来到第四章,这一章节的主要从一条SQL执行的开始,由浅入深的解析SQL语句由客户端到服务器的完整执行流程,最...【详细内容】
2021-11-09  woaker    Tags:SQL   点击:(35)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条