闪存会怎样改变会议系统架构构

1575人阅读
之一:管理和使用--对内和对外的接口
总的说来吧,任何事情都有两套机 构,一套是为使用而设置的,另一套是为管理而设置的,比如一个网站,普通的页面是为了让用户访问的,而一般还要有一系列的后台管理页面。 vm_struct的pages字段就是管理机构,而pte就是使用机构,当然管理时也可以用pte来查找,但是那样就太麻烦了,于是专门设置一个一个结 构进行vm_struct的管理。简单说,pte方式是提供给一套机制的,那就是MMU机制,MMU将不一致的用户访问集中到了一致的访问方式,那就是不 管cpu访问什么数据,什么类型的数据,都要通过MMU找到pgd的物理地址,然后按照 pmd,pte的方式找到最终页面,pte机制是被动被查找的,所有的支持mmu的操作系统都要使用这种机制,比如 linux,windows,bsd...;反过来.pages是内核主动管理vm_struct使用到的策略,不同的操作系统用到的机制不 同,linux中的方式想必很多人已经看过了,windows内核中引入了分页池和非分页池来管理内存,效果和linux一样,但是没有linux的如此 直观,简单。其实c语言的结构体不都是用来管理的吗?所以说vm_struct中的每一个字段都是用来进行管理。可以看一下一些很简单的嵌入式设备的内存 管理,它们不用结构体,直接在平坦模式的内存上分割一块自己用。
pte方式的查找是MMU寻址用的,现代的32位CPU,很多都是有MMU的,也就是说cpu执行的时候只认虚拟地址,而pte方向的查找就是mmu用来 将虚拟地址映射到物理地址的;而.pages 的方式是内核用来管理这个vm_struct的,比如用户要释放一个addr指示的虚拟地址,内核要做的就是释放页面,而pte方式的查找只是为了mmu 而设置的,用来访问该虚拟地址的,要管理这个区域就要.pages了,用户释放addr导致的结果就是内核挨个释放.pages数组的页面,这个问题就好 比vm_area_struct中vm_next字段的管理作用一样,和vm_struct不同的是,后者是内核空间的分配,是必然要映射物理页面的,而 前者是用户空间的分配,靠缺页中断来映射页面,因此也就没有了.pages类似的和页面相关的字段。按照最小冗余的观点,.pages和pte的数据是冗 余的,指向同样的数据,那么可以去除.pages字段,然后管理vm_struct内存的时候去查pte,那么问题有二,第一,一实体身兼两职违反了 unix中每次只做好一件事的原则,违反了最小化正交原则;第二,如果用这种方式,虽然节省了一些空间,但是vm_struct的维护将和pte紧密耦 合,也就是说会变成体系结构相关的机制,这在跨平台和代码结构上也是很不好的。对内的接口用来管理,对外的接口用来使用,管理实体是确定的,因此管理的数 据结构也不用具有一般性,只要管理实体认识就可以,但是对外的接口就必须做到统一,因为使用者不统一,正好比中国和美国都期望国泰民安,很具有一般化,这 就是对外的接口,而对内的接口就是政体,不管是中央集权的还是三权分立的都可以用,很具有特殊性。
linux内核的运行实体本质上就是在做管理工作,有了这种管理工作,上层的应用程序才可以看到一个多道程序的视图,应用程序之所以可以将一切进行,而且 那么显然,比如访存,比如IO,比如XX,并且各个应用程序不会互相冲突,原因就是内核在底层通过这些美妙的数据结构进行了管理,每一个操作系统都需要进 行这种管理,这些管理在应用程序看来是一种服务,在机器看来是一种策略,不同的操作系统按照标准必须提供相同的服务,接口本身就是机制,比如Posix或 者Win32,而实现这种接口的细节就是内核的策略了,各个不同的系统内核的策略是不同的。
之二:再谈我的child-run-first补丁的思想
我 曾经提交过一个child-run-first的内核补丁,有人认为在子进程在初始运行之前被调度到别的cpu上后也要想办法让子进程优先运行,我觉得没 有这个必要,为了减少不必要的写时复制竟然要引入那么复杂的机制实在是不应该,因为会影响到那个cpu上正在运行的进程,如果父进程和刚刚创建的子进程在 同一个cpu上竞争,那么仅仅涉及到父子竞争不会牵扯第三方,但是一旦由于负载均衡或者别的什么原因子进程在开始运行前被调度到一个不同的cpu上,那就 会牵扯到第三方,因为可能那个cpu上的当前进程刚刚开始投入运行,新的子进程如果抢占它,将对它不公平,如果不抢占它但是还是实现子进程先运行的话,那 势必会影响创建子进程的那个可怜的父亲,父亲会为了孩子而等待,这种代价太大了。实际上两个实体怎么都好办,一旦涉及第三方就会造成混乱,比如只有两个人 的情况下,一旦闻到了屁的味道,那么肯定可以定位到谁放了屁,但是如果是三个人在一起闻到了屁的味道,谁又能确定是谁放了屁呢?
之三:物理内存和虚拟内存的一一映射
linux 内核的一一线性映射关系使得内核运行十分高效,试想一下pgd的分配,cr3中的值就是pgd的物理地址,注意是物理地址,因为它是提供给MMU用 的,MMU正是用这套机制将虚拟地址对应为物理地址的,如果cr3中的是虚拟地址的话,谁来处理它呢?这是一个先有鸡先有蛋的问题,因此cr3中的是物理 地址,进一步说,在pgd分配的时候就要很快的知道pgd的物理地址,内核很善于管理页面,而页面在内存的排布也是线性的,因此内核很容易根据页面定位到 物理地址,但是内核管理数据的时候要用虚拟地址,内核也是程序,只不过具有一些特权罢了,它也是使用虚拟地址的,为了内核的高效,这就需要内核可以快速的 从物理地址定位了一个虚拟地址或者反过来,于是就有了物理地址和虚拟地址的一一映射这一说,用户一般习惯内存地址从0开始,这样的话就将前3G定为用户空 间,最后1G定位为内核空间,所有的进程共享这1G的内核空间,好像一个叉子一样,共享一个把手。内核希望使得管理效率高而采用了一一映射,这样内核很容 易从页面定位到物理地址,为了执行程序或者读写内核内存,又可以从物理地址快速定位到虚拟地址。但是为何不将用户空间的虚拟内存和物理内存也来一个一一对 应呢?不能这样,因为现代操作系统提供分时特性而支持多道程序并行,如果是一一映射,那么映射的是谁的虚拟内存呢?即使这样,用户空间的内存管理效率也不 差,linux的缺页中断非常高效
之四:windows盘符将文件树变宽,linux的树型文件系统将文件树变深
windows盘符想必 几乎每个人都明白,而linux没有盘符,其实windows虽然没有盘符它也是树形结构,拥有c,d,e,f四个盘符的系统的文件树的第一级就是一棵四 叉树,而且每棵子树的容量是不容易动态改变的,但是却可以再第一级增加新的子树从而变成5叉树直至n叉树,最后就是这棵大树越来越茂密,总之 windows的盘符限制了文件系统向深发展;linux的文件树却没有任何限制,不论纵还是深两个方向都能伸缩自如,即使你的一块磁盘只剩下一个一点空 间,你只需要建立一个空目录,然后将一块新磁盘或者分区挂在上面就可以了,很方便的,linux的文件系统的构造善于引导用户使用每一块空间,却不主张用 户将磁盘分区,linux认为分区是导致磁盘碎片化的根源,因此总是鼓励用户使用一个整磁盘工作,另外linux还善于让用户享受另一个极端,就是只将磁 盘分出最小的一部分,然后需要的时候再用fdisk挂载新的磁盘空间,毕竟linux没有什么系统目录。
之五:linux的内核和用户空间的两个世界
linux 明确区分了内核和用户空间,它们简直就是两个世界,内核启动阶段,没有任何用户空间的事情要做,而一旦内核启动完毕了,/sbin/init执行了,那么 用户空间的程序根本就不知道是刚启动完内核还是刚刚把所有进程杀掉只留下init,是的,没有办法区分它们,内核启动完毕后。/sbin/init开始接 管一切,从此系统开始了漫漫长路,init进程作为老老祖父开始开启一切用户空间的一切,包括shell,甚至加载模块...,init进程的特殊性在于 它可能是内核直接启动的,因此它是内核信任的,你可以指定任意的init进程,用init=XXX传递给内核,如果不传递,内核默认执行/sbin /init,这一点十分灵活,linux只靠一个内核和一个用户进程就能活着,内核和用户空间最小化了依赖,内核想要完全启动,需要一个init进程,而 用户空间需要内核提供系统调用接口,它们除了系统调用之外互不依赖的。用户空间哪怕再重要的事情,内核也不会负责的,内核的责任就是初始化好一个大环境, 一个稳定的大环境,一套稳定而又安全的机制,然后它就不管别的了,别的如何使用它那都是策略问题,它只是静静地在那里提高稳定底层服务,正是由于这个机制 和策略分离的特性才使得linux拥有了那么多的特性不一的发行版,你甚至可以将/目录下的目录全部删除,只保留一个vmlinuz的内核和一个 initrd,或者将必要驱动编译进内核而连initrd也不用,只要一个内核,然后放一个什么库也不用的hello kitty程序在/下,然后指定init进程为这个hello kitty进程,然后启动,不错...windows的发行版多吗?也不少?番茄花园,XX政府版...其实windows的官方发行版就是微软的版本, 别的任凭你再改,顶多改个图片和主题还能改什么?windows的启动过程决定了其内核和用户空间的紧密连续,最起码需要ntldr,另外还需要 hal.dll,还有ntoskrnl.exe等等很多模块,另外还有一些dll,注册表文件,甚至一些服务也需要在内核初始化的时候启动,这样等内核初 始化了以后,很多的服务也已经启动了,少了一点东西,命运就要面临重装系统,其实NT架构本身就是一个C/S模型的操作系统,在NT架构包括很多基于微内 核架构的操作系统中,实质上没有标准的内核文件一说的,要说操作系统就是所有的内核文件以及其依赖的库或者别的文件以及需要的服务程序,而只有在大内核系 统上才会出现明确的内核一说,大内核中,内核和用户进程才能分离的这么好。现在位置:
&107&篇文章查看更多精彩文章
查看所有活动
发现身边精彩
PMC张冬:浅谈闪存控制器架构
微信公众账号“大话存储”,作者:张冬
[导读]日中国闪存峰会下午的PCIe分论坛上,来自PMC的首席架构师张冬分享了名为“浅谈”闪存控制器架构的主题演讲,以下内容整理自张冬(冬瓜哥)本人的公众账号“大话存储”:
编者按:日中国闪存峰会下午的PCIe分论坛上,来自PMC的首席架构师张冬分享了名为&浅谈&闪存控制器架构的主题演讲,以下内容整理自张冬(冬瓜哥)本人的公众账号&大话存储&:
SSD基本的组成结构有Flash颗粒和Flash控制器,Flash控制器有芯片,负责Flash的读写、磨损均衡、寿命监控等。前端提供主机,跑ATA协议,私有协议等等,规格很多。
控制器主要做的就是这么几件事情:
第一,后端访问Flash,管理后端Flash颗粒,包括各种参数控制和数据IO。控制器需要把从前端发过来的IO翻译成Flash的指令格式。其实,不同厂商采用的协议不一致,后端要做的是适配不同的厂商提供颗粒的参数,虽然大家遵循的协议一样,但一些机密参数厂商不对外透露,而有了这些参数后可以更快更好地在Flash芯片中进行读写。
第二,前端提供接口和协议。实现对应的SAS/SATA target协议端或者NVMe协议端,获取Host发出的IO指令并解码和生成内部私有数据结果等待执行。跟主机驱动,跟上面的协议栈,利用标准格式输配到系统里面,接收主机端发过来的指令,这两个还不是核心的层次。
第三,最核心的是FTL层。指令接收过来以后,部件里面怎么处理指令。包括影射,元数据、元数据保存,磨损均衡等一堆东西都需要处理,所以这块是各个厂商竞争力的体现。它是最重要的,这块是第二重要的,这块反而最不重要,因为这块是标准化的。
后端都有哪些操作内容:
第一,闪存通道控制器,每个控制器里有多个通道,每个通道下有多片Flash,一个通道挂8片,需要有一个信号选择8片,每次发一个信号下去,要读哪一片,要告诉他,有一个片选。通道数量不同厂商的产品都不一样,高端的有的16通道、32通道,有的8通道、1通道。它跟后端Flash颗粒有托管协议。
数据写到Flash的时候要做两个事情:一个是做ECC校验,Flash靠电压检测来表示。加一个比较电压检测,因为这个过程容易出错,比如说用1.2伏表示零,1.3伏表示1,如果检测出来是1.25伏怎么办?你是0还是1,因为出错率非常高,所以需要ECC。
ECC是通用的称谓,包括好几种算法,纠错率较低的BCH算法,还有LABC低密度校验法,我们用更少的位校验更多的错误。高密度是说,我不在乎校验位的容量,最高的就是RAID1,有一份数据复制一份,那个错了,这个还在,那个成本太高了。4K我有多少ECC。LBAC是业内最低密度的校验,已经达到理论的极限了。这个东西做起来的话,用CPU算的话,这个速度太慢了。数据进来以后,一个数据或者两个数据输出。Flash是拿晶体管(音译),你要往里写相同数据的时候,我都充电,可能就产生干扰,这时候出错率就增加了,把原始数据,可能有多个零,一万个零,写进去的时候,会用一个多项式重新算一遍,最后产生的数据,一个0,一个1,这样就不会导致相邻的cell同时充电,出错率降低,读出来的时候也要经过它,把原始数据重新算过来,写到DARM里面,所以需要两步操作。读的时候扰码,加扰,解扰,看ECC有没有错误,有错纠错,然后把芯片发到内部,供后续的程序处理。算RAID的话,多个颗粒之间做RAID的话用云加速计算器去算。
前端基本上没有什么大家都是一样的,如果你遵从NVMe标准的话,包括提交命令、完成命令这些东西都定好了,这个数量可以达到64K个,同一时刻,系统里面可能存在64K&64K IO排着,但是系统用不到这么多Queue,因为底下的介质达不到64K。设计的时候,永远不可能达到,本身就是错误的,肯定会达到,因为底层的科技的进步是没有办法想象的。
一般来讲,现在的产品,一般做硬件的时候,比如说做64 Queue,但是这些Queue都是主机内部里的,Flash控制器里面需要对每个Queue有一个对应的接受的窗口,这个是硬件计算机,然后会把地址写到控制器里面,这时候控制器知道从主机内存哪个位置把命令拿过来,控制器是从主机里面拿命令,不是主机发送给控制器。NVMe 1.2的标准里面做了改变,主机直接把命令扔到控制器少了一步操作。支撑NVMe的控制器不仅仅是软件的改动,硬件也需要改动,你可以拿纯软件模拟,这样的话就非常慢了,你需要有硬件计算器在里面。至于指令解码这块都是软件,这块没有硬件,这块做硬解码不太划算,基本上拿CPU,把命令接收进来,跑代码算一下。
第三,核心层FTL层:这个是关键竞争力所在,纯软件算法,元数据管理,数据布局影射、磨损均衡、垃圾回收、缓存策略,发了IO下来,Flash写了,你发一笔下来,我等等,后面可能有一万笔,我把4K放到缓存里面,一万笔就不用下来了,我就可以降低写放大。如果一个颗粒坏了,我也可以算出来。掉电元数据一致性保障,这个也是体现竞争力的地方。之前的产了掉电以后再开机,因为卡还没有准备好,一直等卡把元数据恢复出来,重新恢复一致性才了进去。最夸张的可能到八九十都有可能,启动一台机器掉电半小时,现在的新产品,基本上就是10秒,或者几秒钟。
这个算法也不是纯软件的,当然也有硬加速的成分在里面,这个就看你用谁家的芯片。有的芯片支持硬加速的东西,比如说链表的恢复。因为做垃圾回收的时候要用到链表,拿传统的软件算法,插入一个链表或者追加一些项目的话,耗费的周期是非常大的,这个时候用硬加速并行起来,再加上一些硬逻辑的加速的话,这块开销是可以省下来了,省下来以后,IO时延就降下来了。Flash时延很重要,每增加一小步都会影响时延,最好是直接到Flash颗粒,什么都不加,但是这样就没办法用,没有办法管理Flash了。
以上说的是一款Flash控制器要做的事情。做这些事情有各种各样的方法,各种各样的架构设计。稍微总结一下。
Flash控制器的两种策略和方式:
一种是少量的强核心+少量硬件加速。所谓强核心就是一个核心的性能非常高,频率也高,里面的器件也多,分支预判、并行度、数量、执行管道,各种参数都往上标,这就所谓的强核心。核心强了以后,硬加速就不需要这么多了,可以用少量的硬加速。
另一种是大量弱核心+大量硬加速。比如说16个核心,每个核心比较弱,但是能够增加执行的并行度,我有16个并发核心执行,我们跑16套处理程序,这是两种架构。
多核心的两种协作方式:
多核心的协作有同构协作和异构协作两种方式。
同构协作就是每个核心做的事都是完全一样的,处理的步骤完全一样。如果你的控制器阵列里面有16个IO,有16个核心,每个核心都能处理一个IO,这是同构协作,每笔IO处理的时候,都有步骤,先指令、解码,形成对应的操作,下一步算RAID,带入到表里面,查一下我哪些地方是空的可以写,再就是找一下影射表之类的,再就是发送给后端Flash控制器,然后写下去,一步一步执行,每一个核都可以做这个事情,这个是同构协作。
异构协作就是多个核心做不同的事情。处理同一个IO,第一个IO第一步,第一个核心处理,这个核心处理完以后,把这个IO扔到下一个核心,再处理下一步,我这个核心空出来以后,我处理下一个IO的第一步,这就是所谓的流水线了,异构就是这样的。这叫大量重核心,关于它的两种协作,我之前写过文章,在公众号里面,大家可以看一下。
以PMC产品示例介绍控制器的架构:
首先它有一个网络,网络承载16个CPU核心,每个核心里面有一个类似于网卡的控制器,网卡连到网络上,说白了网络就是4口路由器或者交换机连起来的网络,多个CPU之间连起来,此外还有硬加速模块。
这里有以下几部分:
RAM控制器,因为芯片上需要有一定量的RAM放临时数据,写放大,读出来写进去,都要走RAM,
然后是PCIe控制器,这个跟前端PCIe对等的控制器,从这儿接收过来VM1。
后端Flash控制器,连Flash颗粒,通过一定数量的通道。
再就是加速器:
包括缓冲加速器,这个就是分8份,因为每做一个操作,都需要有相应的内存,把数据拷到内存里面,内存的维护很费时费力。比如说之前在X86装Linux,有很多的计算量。对于闪存,精打细算,必须把性能做到极致,这块用硬加速;
链表加速器,刚才已经提到了,哪块空着,哪块被应用,这块用软件维护很费力,(所以需要在这里作加速);
XOR加速器,XOR要用硬加速,当然还有外围辅助,串口等各种其他的控制器,图中没有具体显示。
所有模块通过一个网络互传数据,达到高度并行的目的,所以这个网络速度非常快。
软件的并行度。16个核心,我们提供的参考的部件,SSD厂商把自己优化的东西放进去开发出自己的部件,这几种基本上包含这样一些程序:因为每个IO读的地址可能有重叠,所欲需要有一个锁定协调;有管命令解析的,有管启动的,最核心是:有管日志的,有管磨损均衡的,有管查表的,有关写数据的,还有引擎对应的举动都在这儿,管前端的PCIe 管理员,初始化的配置,需要由它处理,data manager,这是主程序,分析干什么,生成一堆的后续步骤下发下去。其实每一块都可以跑在一个核心上,同一个角色可以复制多份,充分变小。16个核心,达到16份程序并行的运行,16个流水线的Stage,这样就可以屏蔽处理过程中的时延。
我的介绍就到这儿,这是我的公众号,大家如果没有关注的话,可以再关注一下,谢谢。
本文整理自微信公众账号&大话存储&,原文作者系PMC首席架构师张冬,转载请注明出处。
作者的更多文章
微信公众平台:搜索"doitmedia"
或扫描下面的二维码:
Copyright (C) 2013 DOIT Media, All rights Reserved. 北京楚科信息技术有限公司 版权所有.
电信与信息服务业经营许可证:030972号 电信业务审批 [2009]字第572号
京ICP备号-3
京公网安备:如何看待闪存特性与文件系统应用?
 作者: 肖授 编辑:
  【IT168厂商动态】闪存存储的性能与传统磁盘的差异,是众所周知的事情。但是,闪存颗粒在物理层面可靠性和稳定性的问题往往被有意或无意地忽视。那么,针对闪存存储的性能优势和持久性劣势应该采取什么样的解决机制?当前文件系统设计与闪存存储结合存在哪些问题?同时闪存存储在不同的文件系统中具备哪些应用模式和特点 ?这些问题一直困扰着关注闪存与文件系统应用的朋友。  作为DTCC本年度的白金赞助商之一,闪存领域领导性厂商Greenliant亚太营销副总裁李炫辉分析指出,在过去,闪存与文件系统这两个方面是不搭界的事情。因为闪存存储更关注物理介质以及集成电路与底层访问控制,文件系统更关注对上层的应用提供存储的功能和特性。但是,正如多核技术带来和应用采用多线程/进程并发机制提升性能一样,闪存介质的出现也对文件系统应用有所影响和变化。因此,首先需要从了解闪存存储的底层特性、实现机制以及优劣势,扬长避短,利用现有文件系统和闪存优化的文件系统,充分发挥闪存存储的优点,一步一步地解决现在面临的问题。  你所知道的闪存特性和架构是什么样子?  在回答这个问题之前,我们必须搞清楚一个常识问题:现在谈论闪存和固态的概念实际上不太一样,凡是使用Flash Memory的都叫闪存,实际上后者只是一个封装的状态,固态可以封装Flash Memory也可以是非Flash Memory,目前大部分闪存厂商采用的都是Flash Memory的固态盘, 一般都把固态盘叫闪存,闪存也叫固态盘,所以也统称闪存。  除了闪存以外,还有多种快速存储技术,如DRAM ,NVRAM, MRAM and Spin-Torque(自旋力矩磁阻式随机存取), Carbon Nanotube( 碳纳米管 ), Phase Change Memory(相变), Memristor ( 忆阻器 )等等。  决定快速存储大规模应用的主要因素是量产规模、稳定性以及经济性,有量产规模才能提供可能,有了量产规模才能对闪存稳定性和性能进行验证, 再就是经济性如何体现,这些因素决定了快速存储大规模应用。当前,闪存主要用于IO性能加速环境,如数据库加速、虚拟化、延时敏感型应用、Server SAN或SDS、大数据处理等等方面,也是从2010年左右,闪存才开始大规模应用。  那么闪存物理特性的优劣表现在哪些方面呢?  从闪存物理性来看,闪存谈论最多的就是SLC,MLC,它们分别是Single-Level Cell 单层单元和Multi-Level Cell多层单元的缩写,Cell就是一个物理单元,有固定栅和浮动栅,进行计数时候,是电子打到浮动隔离栅产生电位,电位变化形成数据00、01、11、10等,当进行操作,就是要电子进行击穿,在进行改变的时候,将电子通过引槽流出Cell,并产生变化。  闪存为什么有擦写次数限制呢?当进行数据擦写,电子流出时候,物理隔离栅就会变薄,变薄到一定程度就没有绝缘的机制了,电子进入就会漏掉,那么就会坏掉,就出现闪存擦写次数的问题。  当前NAND Flash面临的挑战主要是耐久性、数据保持性、读写干扰、制造工艺缺陷,耐久性受制于闪存颗粒的擦写次数,同时数据保持性是指闪存将数据存在一个Cell中,仍然存在电子泄漏和电子辐射造成数据丢失情况。读写干扰是指对一个Cell进行读写操作时对临近的Cell也会产生干扰。制造工艺也存在不同的品质。另外,SLC比MLC品质要好,Cell都一样,但前者只有两个状态位,后者有4个状态位,那么后者读写数据的擦写次数要增加,寿命自然会缩短。  当前SSD主要使用NAND Flash,属于非易失性存储介质,成本比较低。物理特性不容易改变,那么如何优化显得很重要。  有一个情况需要指出,对于半导体厂商而言,在不断降低制程,密度越来越高,工艺控制难度增加,造成NAND Flash可靠性随制造工艺减小而降低,如擦写次数降低,大容量闪存里面就更容易出现错误。这也就是当前闪存厂商开始更专注 3D NAND 制程工艺的原因。  明白了闪存的物理特性之后,你们清楚闪存与磁盘到底存在哪些区别呢?  闪存的性能与磁盘系统的对比毋庸置疑,前者是电子驱动,后者是机械驱动,闪存的性能是磁盘的几十倍到上百倍,但是在可靠性和稳定性层面,闪存和磁盘却有很大的差异,例如磁盘性能随时间变化不会有变动,15000转硬盘十年以后还是15000转,而闪存存储则随时间和数据擦写量增长存在波动和衰减;闪存在擦写次数方面有限制,但磁盘没有限制;在MTBF方面磁盘可以到200万小时,而闪存则与擦写次数密切相关。当前阻碍闪存大规模应用于企业级应用的主要问题不是性能,而是闪存设备的可靠性,如何在闪存产品的生命周期内保证山村的可靠和性能无衰减是关键。  如何提升闪存可靠性和保障性能无衰减,则需要在闪存设备的架构设计方面下功夫。闪存控制器是闪存设备的核心,是联系主机和NAND Flash的桥梁,闪存控制器的管理功能包括了: Error-correcting code (ECC校验)、RAID保护机制、Wear leveling(磨损平衡)、Bad block mapping(坏块管理)、Read/write disturb management(读写干扰管理)、Garbage collection(垃圾收集)等。  与此同时,闪存控制器也有定制化功能,如加密、安全擦除或自毁、压缩或去重方面。  由于NAND Flash的工艺不能保证NAND的Memory Array在其生命周期中的可靠性,因此在NAND的生产中及使用过程中会产生坏块。为了检测数据的可靠性,在应用NAND Flash的系统中一般都会采用一定的坏区管理策略,而管理坏区的前提是能比较可靠的进行坏区检测。  NAND ECC校验机制比较复杂,由行校验、列校验 组合而成,当出现多位错误时候,可以通过ECC 校验恢复。常用的ECC算法有Hamming、Reed-Solomon码、BCH、LDPC等,和使用颗粒类型相关。SLC一般采用Hamming校验,MLC一般采用Reed-Solomon码或BCH可以实现多位纠错,LDPC一般针对3D NAND校验。  常见的闪存卡ECC模块设计,采用集中式ECC引擎设计,即在板卡的闪存控制器中集成1个或2个ECC引擎处理ECC校验。当数据写入NAND Flash时,会由ECC引擎生成ECC校验码,然后和数据一起写入后端的闪存颗粒。当读取时候,系统从颗粒里面读出数据和ECC校验码,如果验证一致就送出数据,如果发现数据和ECC校验码不一致,则需要通过ECC校验获得正确数据,然后写回后送出数据。这种架构设计比较简单,成本比较低,但是我们知道,当Flash设备随着使用时间和数据量的增长,坏块会逐渐增加,会产生大量的ECC Error,这时候由于ECC引擎成为系统瓶颈,设备性能和可靠性会大幅度下降,对应用性能和数据安全带来影响。  如何消除性能衰减和可靠性下降的问题,这就需要在架构设计方面进行创新。Greenliant在闪存设备架构上实现了分布式ECC 设计架构, 在每一个NAND Package中都封装一个闪存控制器里面。这样就避免了前面所讲的性能衰减和可靠性下降的问题。同时为了防止闪存颗粒故障造成数据丢失,在架构上还实现了板载硬件RAID的功能。  还有一个需要注意的区别:闪存与磁盘系统的物理地址映射有很大不同。  在磁盘里面逻辑块地址LBA和物理块地址PBA是一一对应的,磁盘只要写的是这个LBA那么磁盘就一直会访问这个地址,那么就存在热点;对于闪存盘来说,由于存在擦写次数的限制,则会通过磨损平衡算法,尽可能让每个块擦写次数相同增加闪存设备的寿命,因此同一个LBA在不同的时间会指向不同的物理地址,因此文件系统需要闪存的这种特性做优化。  磨损平衡如何改变逻辑块地址和物理地址对应?磨损平衡分为动态和静态磨损平衡以及全局磨损平衡。动态磨损平衡写一个文件时候,永远写在一个空白块,空白块写完之后再写回到之前的那些数据被删除块上,这样循环地写。但是当一个文件写到闪存上就不很少被访问,而其他块被写了几十上百次,在这种情况下块与块的擦写次数就不再一致,动态磨损平衡算法就失效了,因此我们又采用静态磨损平衡算法,就是当一个块擦写次数和临近块次数超过一定阀值时我们就作一个数据存储交换,这样保证擦写平衡。这样有利于改善闪存耐久性,会优化闪存的性能。另外我们在颗粒级别会有全局磨损平衡算法,这样进一步提升设备的可靠性。  可见,闪存可靠性通过闪存算法、控制器管理可以来优化。那么如何采用闪存存储优化系统性能?  业界目前采用闪存存储优化系统性能的方式主要包括三种:一是所有数据都放闪存存储;二是混合模式一部分热数据放闪存存储;三是缓存架构如缓存热数据在闪存存储,如分层存储将冷热数据进行存储分层。  这三种方式,都需要文件系统支持,由文件系统提供底层设备访问。从几个文件系统特点来展开分析,首先Linux Storage Stack Diagram version 3.17方面。  从这个图中,我们可以看到从文件系统到底层设备,路径很长,可见,文件系统是一个比较复杂的东西。这么长的访问路径会影响到闪存性能和延时优势的发挥。针对这个问题,2012年英特尔提出NVMe标准,可以缩短闪存设备的访问路径,提升访问堆栈性能,更能发挥闪存高IO性能和低延时优势。  而对于高并发的应用而言,基于PCIe的NVMe协议更有明显优势。对于采用AHCI协议的设备来说,每个PCIe卡的ssd访问都需要通过Core 0来管理,Core0成为该设备的控制核,这样的控制机制就会降低性能和访问的可靠性,但NVMe协议支持每个 Core采用独立的链路,可以提高并发性能。  Linux文件系统是基于日志的文件系统,利用闪存提高Linux的文件系统性能可以采用以下几种方式:1. 将Journal日志放置到闪存上,2. 对数据安全不要求的情况下可以禁用Journal,3.由于闪存不存在磁盘存储的巡道和IO合并的需要,也可以禁用系统针对磁盘优化的merge/rotational等参数提高性能,4. Linux最新的Btrfs文件系统基于闪存特性做了访问优化,也可以考虑采用Btrfs文件系统。  ZFS文件系统是也是一个非常有特色的文件系统,当前一些商业化存储系统就是基于ZFS文件系统。ZFS文件系统载在设计时就考虑了通过闪存进行性能加速的方法。ZFS使用日志机制,ZFS intent log (ZIL) 处理同步写,ZIL处理同步写越快,系统性能越好。将闪存作为ZFS日志设备,可以大幅提升同步写性能。ZFS的ARC(Adjustable Replacement Cache)读缓存淘汰算法可以优化系统的读性能,而SSD可以作为二级缓存L2ARC设备提供更大的缓存空间,缓存命中是最大限度能提高性能的。但是  当前比较热门的Ceph文件系统,相对于底层的文件系统而言,Ceph文件系统更像是在底层文件系统之上的文件服务,在这里我们就不做过多介绍,但是Ceph文件系统也大量采用闪存进行性能加速。  针对闪存特性和文件系统应用的分析之后,那么当前闪存存在哪些问题呢?  问题之一在于,大多数和应用的存储设计均是针对磁盘访问特性进行优化的。由于传统磁盘的机械设计,需要通过磁头的旋转进行寻道和数据IO操作,限制了磁盘的性能,因此操作系统和应用的底层算法大部分都是针对如何减少IO操作和寻道时间所设计的。  另外,磁盘存储架构下为了提高IO性能采用了缓存设计,从而又增加了复杂的数据保护的处理机制。  还有就是,应用的并发度也限制了利用了闪存。  当前有些研究机构通过透明地绕过文件系统使用非易失性存储器,在高并发的压力下将闪存设备的性能提升7倍以上。  来自SNIA最新的技术思路, 利用NVMe标准访问协议,针对闪存设备特性来设计存储访问机制。例如利用基于闪存设备的对象存储结构,让应用直接访问底层闪存设备;再有通过闪存优化的文件系统,提供上层的文件访问;对于一些应用提供核心层的闪存优化的块访问机制等等。  另外,出于成本的考虑,有些客户将闪存设备作为磁盘的缓存,通过将SSD作为传统磁盘的读写缓存以加速IO性能,这种使用方式其实会加速设备磨损,因为利用LFU,LRU,MRU等缓存算法,会带来大量的碎片IO操作,造成读也是写的情况,加速了SSD设备的磨损。  李炫辉根据业界趋势包括Greenliant的发展情况,对闪存做了一个很有意思的展望,他指出,未来闪存随着经济性越来越好,可靠性设计的逐步完善,那么面向NVMe闪存设备的访问机制将会成为闪存应用的现实,针对NVMe闪存设备会做成一体化的架构。(阿明)
IT168企业级

我要回帖

更多关于 会员系统架构设计 的文章

 

随机推荐