各位听众朋友们大家好现在是由我和任喬伟为大家做一个报告是关于在Bcash上来使用NVD我们做了什么以及我们从中学习到了什么我的名字叫李勇英文名字是Cole我是Linux内行里Bcash自己同等维护者也是Susie Linux公司内部的Linux产品中MD Read, DivisMap, Bcash和NVDim的维护者任喬伟他是英特尔中国区的软件工作室他在很多的开源项目上都参与过工作包括Linux内核OpenStack还有云相关的另外还有Self他在国内比较大家比较知名的工作是他是Linux内核修炼之道和Linux内纪的事的作者那么我们先介绍一下Bcash是什么给不熟悉的朋友们Bcash是Linux内核中的一个框设备层的cash他是在3.10中被摸到了主干内核里头然后在Linux5.3之后的版本它的稳定性在我看来达到了企业级Linux的稳定性它这个内核仔细统的功能是将SSD就固态硬盘和普通的磁盘组合在一起虚拟出来一个虚拟的框设备这个框设备可以格式化可以帮助文件系统那么如果有比较热的数据就偏反访问的数据的话这个数据就会被缓存在固态硬盘里当对这些热的数据进行访问的时候就会直接从固态硬盘里返回我们看起来就好像是在访问固态硬盘的挨物选民一样现在主要支持的开始模式有四种回写模式写透模式还有一个绕写模式和NANNAN就是不做任何的开始B开始现在主要支持的工作负载有四种第一种是数据库多数数据库还是有很好的时间和存储的局部性所以用开始以后性能提升效果还是非常明显第二个就是虚拟化虚拟化主要指的是虚拟机的虚拟化可以在虚拟机的外边使用B开始一些最常访问的IO直接就在SSD里头就返回了不用再去到后端的分布式存储里面去取数据它的性能会明显提升那么还有一个很热门的一个使用方式就是分布式存储比如Safe在Safe存储的直接使用B开始是绝大多数用Safe做性能加速的厂商的首选最后还有一个就是超轮盒超轮盒的这个进权里边的话有很多IO秘籍的英勇也是经常使用B开始来做性能加速的下面这个图标咱们可以看到这是我知道的给B开始社区报过Bug提过Patch他们在使用B开始的一些企业和机构著名的大型的企业和机构还是蛮多的简单来说就是说B开始的功能就是加速IO性这个IO性能力包括延迟LPS和敦读量它如何加速呢把频仿仿问的大容量的脚慢的快设备上那些热数据缓存在体积脚小的快设备上那么B开始是怎么工作的呢我们举个例子就以协请求落到开始设备上为例开始模式我们用Redback模式它的本质实际上就是使用了个B加数来索引所有被开始的LBA地址就磁盘上的LBA地址的范围来看这个数据是被开始在SSD上了还是没有被开始上对于新缓存的数据的话就需要构建一个新的BK然后把它插入到B加数里面就OK了那下面是BK的数据结构我们可以看一看它基本上典型的BK的话是有一个8字节的High8字节的Low还有一个弱干的8字节的Point弱干的意思就是说如果它没有胶原盒的话就是一个8字节如果有胶原盒的话就是两个8字节的Point第一个是LBA地址第二个是胶原盒在High这个成员里面它是一些和Key的缓存数据的属性相关的一些内容那么Low里面它放的是它所模拟的磁盘设备Biking后端磁盘上面的LBA地址PTR这个Point里面它放的是这个数据一旦被缓存在SSD上之后在SSD上的LBA地址那么这些Key会组装成一个一个的叫Bset这个Bset它是有一个头部定义了一些数据结构然后它后边放的就是那一堆的BK这些Bset它是有大小的比如说它是一个块一个Bcash定义的Block一个块的大小很多个Bset在一起后它形成一个Bitrate node就是Bitrate的节点这个Bitrate节点在Bcash里面的话通常是一个Barket size这个Barket也是Bcash格式化的时候定义的一个大小所有的Bset最多就是填充到一个Barket当Barket满了以后不能再放下还要再插入心里的时候那么这个Bitrate node就要分裂分裂成多个经常访问的Bitrate node会在内存里有一个副本来用来加速因为它插入删除搜索都会在内存里去做它如果修改这个Bitrate node的话就定义把它再刷回去因为插入Bitrate本身它不是一个原子型的操作吊垫或者是系统崩溃的时候可能就会出现远处的Bitrate那么为了解决不一致的问题的话就要使用到一个重复的日致RiduLog来维护所有的Bitrate的操作日致的话也一样日致区它也是分成一个一个的Barket的大小然后在Barket里面的话就会存很多数据结构叫Gset叫Jeralset这个Jeralset里面就像咱们下图显示的这样它有一个头部头部的后面整个这个位置就放的是按时间顺序放插入到各个Bitrate节点里的Bkey放在这里面当吊垫重启以后它就会重放根据Sequence之下会判断哪些Gset已经失效了然后把有效的就按照在它的后边放在正中位的顺序按那个顺序来重新再重新把它们再插回到它们应该去的那些Bitrate Note的里面这样来保证Bitrate的移植性然后Bitrate的节点还有Jeralset还有BitCache的数据在目前Linux那一盒主干的代码里面它都是存在SSD上而且它们共享了所有的数据Barket咱们可以看下图这个视力咱们可以看这个大的方块可以想象它就是一个SSD的空间那么红的这个区域就是Cache Device的Cyberblock后面这个橙色区域是Jeralset一Jeralset区域它是固定的就在这个区域后边的绿色区域和黄色区域黄色区域是可以认为它是BitCache的节点绿色区域它是Cache的数据可以看到就是BitCache的节点和BitCache的数据它们之间是相互交错在一起方并没有特定的区域这个BitCache的节点它在内存的那些副本也是可以被回收的当系统内存比较吃紧的时候系统的内存的管理器调用BitCache的供系统的其他字系统来使用那么一个典型的写请球它落到一个BitCache设备上的话通常是会有下来的这些IO参与进来第一个就是要把数据要写到Cache设备上的某一个Barket的理念而第二个就是我要去Cache设备上去把B加数的节点要读出来读到内存里面然后用它来去锁引这些BitCache的数据当这个数据被写好之后就要生成一个新的Bkey然后把它插入到BCache的日治里面然后在一个合适的时机把它一步的在flush到固态硬盘上去同时还有就是要把这个key要插入到BCache内部的B加数的节点上去然后也是并且把这个节点在一个合适的时机把它刷新到硬盘上去被Gernot被刷新到固态硬盘上去之后这个写请求就可以把那个调用者表示我写完了可以看到缓存一个写的数据的话SSD上有四个IO会参与进来一个是数据的三个是原数据虽然就是原数据的IO它是可以被聚合然后被病情的发射一步的发射到这个硬盘上去的但是数量还挺多的也就是说如果我们要是能够把原数据的IO的性能提升的话就可以很明显的提升整个Cache这个写数据的IO性能那么现在BCache在SSD上工作工作挺好的但是MVDM出现了之后我们就会想如果我们把原数据放到IO性能更好的MVDM上面去的话那是不是整体的IO性能会更好那目前MVDM占主导地位的生产厂商是Inter大家可以看到很多有关联的名字像Intel DCP MIMIntel AEPOptim MemoryAparch PassBallow Pass咱们可以看下面这个三角形这三角形是一个性能金字塔最上端的是CPU的Cache和DRAM然后就是C14内存MVD我们测试是比一个位置要小多了大概是在几百个大秒之间接下来就是存储设备存储设备最快的话就是和Optim Memory使用同样介质做的Optim SSD它性能很好然后就是通用了一些其他的Null的MVME接口的SSD最后面就是SATA的接口的SSD那么我们现在关注的就是在Processed Memory这一个地方其实要这要说一点就是MVDM其实已经存在了几十年了但是就是它要么就容量比较小要么就价格非常贵Intel的产品现在是真正是把相比以前来说真正的大容量和相对便宜的产品推出到市场上是它成为能够更逛换使用的可能NVME的SSD大概比SATA硬盘要速度要快出300多倍来所以我们用NVME的SSD来开始硬盘当命中热数据的时候就感觉好像它就好像跑在SSD上一样性能非常好NVME的性能又比通常的NVME的SSD它差不多又快了100倍左右所以我们就会想如果把它应用在Bcast里面会发生什么事情但是肯定任何的事情有好一面就有不好的一面它就有硬币的两面性Bcast上面使用NVME的话好处的话第一个就是它是非意识的写进去数据不会丢而且它是自己的选址它会更灵活一些而且它的延迟非常小它要比SSD延迟要好得多不足之处还是价格虽然已经比以前价格低了很多了但是相比于SSD它价格还是贵切第二个就是延迟虽然它比SSD延迟好了很多但是相对于系统的DRAM的延迟它还是挺大的所以我们不能把它真正当做内存使用把它还是得当做一个跨式给它使用第三个就是容量现在SSD的话基本上加用可以达到8个T左右NVME现在还没有到这么大的容量在把NVME用在Bcast上的时候我们制定了这么一个计划大概有分三步走形象来看就是这样就是物权主干内核的话如果我们看延迟的话它的延迟大概有四部分组成一个是所以Btree一个是写开这个数据一个是日日的IO最后一看又一步的Flash between nodes我们看延迟就可以看前三部分因为后面那个Gerno只要Flash了以后它就认为IO就完成了所以我们就看前三部分的延迟第一步我们把日日区把它先放到NVD模式这功课已经做完了做完以后效果咱们可以看Gerno那个地方变成一个J用小型字母J来表示它的延迟就会有减小但是实际我们测试没有这么明显因为它的IO是被聚合和并醒来的所以虽然日智这块它的IO的延迟会从数量级的降低但是把它放到整个系统里边看的话它就没有那么明显不会有数量级的提升目前我们正在做的是什么是把T的检查就是把Btree这块也要放到NVD模式上去那这样的话就是原数据Btree和Gerno都把它放到NVD模式上真正的延迟大头就只有Cache数据了这样看的话IO性能应该会再进一步提升这个我们正在做预计可能再有测试一段时间吧测试调试一段时间应该差不多做完了这个做完之后再下一步就是我们把Btree还有Cache的数据还有Gerno全部都放到NVD模式上去全部都放到NVD模式上以后那延迟就明显降低了这个我们后续再做到那么目前我们把Gerno放到NVD模式上就做完了所以我们做了一个反射码使用的机器是联想的ThinkSystemSR650这个机器的配置大概是有两个24号的处理器96G内存我们用了一个256G的Intel的NVD然后用一个4TB的NVMV SSD来做Cache然后把3个4TB的NVMV SSDBread0绑定好之后做成Backing然后Cache的模式Bcache的Cache模式使用的是Redback这个测试的时候的IO请求写请出的IO的大小大概是在512字节到4K之间咱们可以看看这个测试出来的性能数据曲线中蓝色的曲线是没有把Gerno放到NVD模式上去的性能曲线橙色的曲线是我们把Gerno放到了NVD模式上以后的曲线咱们可以看到在绝大多数情况下橙色曲线的数值都是高于蓝色曲线的简单的说平均下来大概能高5%左右就是不管是LPS还是吞吐量那么这里要注意的就是说Gerno只占了500兆左右的空间而这个Cache设备是4TB也就是说差不多我们用了相对于Cache设备1万分之1的空间的NVD得到了明显的有5%左右的性能提升所以看1万分之1对比5%感觉还是蛮划算的那我们是怎么实现的呢怎么把NVD模用在Bcache上面去存储Gerno呢因为很复杂的一些工作都被NVMPG的分配器做就是说我们怎么去管理NVD模的空间分配回收这个全都分配器做分配器后边的话Intel的认晓伟会给大家介绍分配器的器杰那对我们来说的话就只要是调一个两个函数就可能第一个函数就是Bcache,NVMPG,Lockpages就是我们如果想要得到一些NVDM的配置的时候我们就调这个函数然后就可以得到一大块的NVDM的空间它是一页为单位的二块空间我们不想用的时候就再调用Bcache,NVMPG,FreePages把它释放以后返回到分配器里面去那Bcache代码就是说我分配出来这么一大块空间分配出来之后呢在Bcache的SuperBlock里面有个数捷够它的成员叫D这是一个数组在用SSD做Cache的存Gerno的时候这个里面放的是每一个Gerno bucket在SSD上面的LBA地址然后我们把它改成了每一个存放Gerno的有Bucket的那么大的NVDM配置连续的NVDM配置的骑士的偏一辆当要去写这个Gerno的Gerno set的时候通常以前存在SSD上的时候是要包装一个BNO然后Ease又出下去那现在的话就不需要了现在我们就是调用MemCopy的函数把它copy完了之后然后再把LastLevelCacheFlash一下就OK了这样的话就连Crosser被送的代码也都直接跳过去这就实现了所以代码还是很简单的这个要感谢于NVMPG的分配器用这个分配器呢来管理MADM的Name Space的空间那我需要多少我就申请多少用就OK了然后根本不用去关心MADM里面是怎么去计算那些偏一辆我用了什么地方没有什么地方不用考虑这个非常方便那么我们在这个开发过程中间还是有很多第一手的体验我们学到了什么呢第一个就是NVDM虽然是内存的模块但是它真正在用起来写程序用起来的时候它还是一个存储设备它不是一个内存设备它的很多IO的特性它还是经常存储设备比如说延迟延迟还是有点大在几百那秒级别它相比内存还是大多了所以使用的时候还是要考虑到延迟的所以紧接着就是说它的原地更新就是有一个数据结构存在NVDM上我可以直接内存选址我要更改它的时候因为我一更改它它就那个更改就被存下来了它不像DRAMDRAM掉电之后就清零没有了那这个你更改只要你一更改它就存在里面掉电之后再重新回来这更改还在那么这个情况下的话就有一些更改它不是原子型如果你改了一部分另外一部分没改比如说这个数据结构头上如果有一个胶案盒的话那个胶案盒就错掉了所以这种情况下就要设计一些较为复杂的一致性的机制比如说要做journal或者是copyright这样的机制那这样的话原理更新的代价还是比较昂贵的第三个就是它的延迟延迟要比SSD好很多很多了但是还是没有好到可以直接拿来当内存用它非议室内存情况下的话因为我们写完之后它有可能还在CPU的last-level cache里面所以一定要再flush一下如果把写家flush全算上差不多就在100多个纳秒或者是稍微再多一些的纳秒级别了那相比于DRAM这个验识还是明显的所以不能忽略那么还有一个我们发现就是说即便NVDIN它用P-MAM的驱动或者是BTT这些的方式来使用可以当框之外来用但是还是使用直接访问接口就DEX还是会更好一些那如果直接用DEX的模式的话直接就在英文里面调用MemoryCopy加flush-cache这种方式就一下把那么多的代码的调用就全都调过去了性能会好很多那么还有一个就是说虽然NVDIN真正在进行读写的时候它的单位是开始烂的大小但是NVDIN在保证原子性的时候它的最小单位是一个字比如说在64位的机器上的话它就是一个64的BIT一个8字节这个是特别要注意的一个地方在任何情况下就是调电或者崩溃NVDIN只能保证我写进去的这8字节它要么全写进去要么全写进去这个开始烂的话有可能会数据不一致的所以它对开始烂的显示不保证原子性它只对一个字在字的长度对齐的位置上的一个字的长度的写它保证原子性那最后一个就是我们发现像我们在BitCache的Journal放到NVDIN上的时候这个Journal空间不大最多是500多兆小的话可能还更小一些如果把整个的NVDIN的Name Space都放上都给BitCache用的话太浪费了所以把NVDIN的空间把它持化然后用一个非议师内存页的页分配器把它管理起来这是个很好的想法经济性效率包括使用其他的程序的编写的容易程度收益都是非常明显好了 后面的话就是要涉及到NVMPG非议师内存的分配器的细节了这一块我就有请在英特尔的同事任乔伟为大家报告我们的工作可以分为两个部分合金的一部分是一个NVDIN的Page Alicator另外一部分是BitCache里面配合这个Alicator介绍进行的修改下面由我来简单介绍一下这个NVDIN的Page Alicator的一个实现这个Alicator主要有这么几个优势第一个是灵活性目前内核里面已有的NVDIN的solution比如KMEMORED DRIVER是吧NVDIN放到内核统一的MEMORED DRIVER进行管理这样的话内核所有的MODEL都会卸耳完整的DRAM以及NVDIN的空间做不到为某一个MODEL分配Specific的一块NVDIN的空间来使用而通过我们实现的这个新的Alicator一个MODEL可以按照自己需要的大小申请一块Specific的读属于自己的NVDIN的空间来使用这样也提高了NVDIN的使用的效率一个NVDIN的Name switch可以被多个MODEL来卸耳每个MODEL申请这个Name switch中Specific的一块空间来使用互不影响另外这个Alicator是一个简化的Body分配器只是对NVDIN定不进行页面的分配和释放并不做更多的LiOT的一个管理这是因为这个分配器有这样的一些特点Bcache作为它的用户在使用的时候极大地简化了对自身的修改概括来说我们这里所说的这个NVDIN的Page Allocator是一个Body-like的分配器仿照内存管理的Body算法以二的密切的形式分配和释放连续的页面而对于整个NVDIN的空间来说通过持化的方式划分成多个Name switch来进行管理目前的实现支持最多8个Name switch所以说可以简单理解为根据LiOT的大小整个Name switch整个MVDIN的空间分成两级来管理首先是Name switch然后是页面的Body算法这个分配器的多个用户可以share这个MVDIN的池子我们也记录了每个用户的MVDIN页面的使用情况通过特定的接口用户可以获得自己已经申请到的所有的页面另外这个分配器并不支持slab这样的对象力的一个管理也并不适合去要频繁的分配和释放的一些case这里简单介绍一下这个分配器的一个设计正如这里所显示的这样我们在MVDIN上设计了这样的几个structure首先每个MVDIN的Name switch上都有这样一个超级快描述了包括总的页面多少啊等这样这个Name switch的基本的一些信息当然这里面最重要的一个member是set header用来trace这个分配器所有用户的页面使用情况具体的用户由第二个结构head这样来对应set header这个结构里边这个hats的一个数组的每一项都对应了分配器的一个用户而后面的这两个req的相关的structure一来进行记录对用户对MVDIN页面的一个使用情况比如最后req的结构就是记录每次分配的时候页面的offset或者就是分配多少页面呢就能这样一些情况就这里面的order这段就是8D算法里面的二的密次正如通过这样的一个层次的一个设计我们可以traceMVDIN所有用户对MVDIN空间的一个使用过程从而可以在下次reboot的时候恢复出之前的一个状态正如前面所提到的目前我们已经初步实现了这个MVDIN的页面分配器并且通过这个分配器已经能够把bcatch的journal给存放在MVDINMVDIN上当然这些相关的patch还正在review还没有被cronus所冒击对于未来来说我们的工作主要也分成两个部分首先对于bcatch以及bcatch2来说的话需要把bcatch的数据给存放到MVDIN物上最后在一些合适的一些case里面能够把所有的bcatch的原数据以及数据本身给存在MVDIN物质上另外对于MVDIN的分配器来说未来的工作主要是需要进一步保证系统调件或者currency支扣的数据的一致性以及进行持续的性能力优化以后提升最后要感谢一下所有对这个工作有贡献的开发者和贡献者们我是在SUSI然后任乔伟和马建鹏是在inter另外还有两个人要提一下就是联想的叶怀盛和海洋虽然目前代码里面没有他们写的代码但是我们这个工作前前后后好几年了最开始我们和联想合作的时候的原型代码是他们做的他们的原型代码的验证了把MVDIN的页当做内存页来使用然后通过一个Buddy这样的分配器把他们管理起来然后其他的应用来调用这种思路是不是可行那么绕过通用的框设给接口直接使用Dex来访问是不是真的明天有新能提升这些验证工作是由他们来做的那么团圣和海洋他的工作做完之后给我们的验证指定了方向就是这个方向是可行的我们可以继续往下走所以后来的话就是我和Intel的任乔伟和马奖彭我们把后续的最终的实现工作开展起来临终得到了一定阶段的收获所以在这向各位开发者和贡献者们表示忠诚的感谢谢谢大家最后也非常感谢各位听众能花时间来听我们这个技术报告下面欢迎大家提问我们会认真仔细的回答谢谢大家