opennaive

重复数据删除和SSD的互补方法

/*******************************
 * 信息存储专题课程作业
 * 重复数据删除技术和SSD技术的互补方法
 *******************************/

摘要

重复数据删除和SSD是目前存储领域非常热门的话题,近几年来得到了飞速的发展。重复数据删除由于其较高的计算和索引开销,容易成为性能瓶颈,所以一直没有在主存储系统中立足。SSD则受限于寿命和可靠性方面的问题,数据中心接受SSD产品的步伐非常缓慢。研究人员发现这两种技术其实存在互补的可能性,SSD具有重复数据删除需要的随机读写速度,而重复数据删除可以有效降低SSD的IO负载。本文分别从这两个角度介绍了二者互补的解决方案,CAFTL在设备一级拦截重复数据,延长SSD的寿命;ChunkStash使用flash存储指纹来加快索引的速度,提高了重复数据删除的吞吐率。

关键字:重复数据删除,flash,SSD

1 绪论

计算、存储、传输是计算机系统面对的三个基本问题,存储问题作为其中之一,其重要性不言而喻。但是随着计算机和互联网在全球范围的普及,数据量正经历着爆炸式的增长。面对这些海量数据,计算机系统如何能保证充足的存储容量和访问速度,就成了存储技术研究人员主要思考的问题。

目前磁盘仍然是构成存储系统的主流基础设备,其相对低廉的价格、较高的容量、RAID技术带来的可靠性等优点,都是其仍然统治着大规模存储市场的原因。研究人员不断的挖掘磁盘技术的潜力,目前存储密度、转速等性能指标都已接近极限,急需新的技术来提高存储系统的容量和访问速度。在这种背景下,重复数据删除技术和基于flash的固态存储技术得到了研究人员的广泛重视。

重复数据删除是一种无损的压缩技术,它从数据中删除掉重复数据来节省存储空间。重复数据删除技术的基本原理是将数据按照一定的方法进行分块,可以是定长分块,也可以是内容感知的变长分块,然后使用SHA-1等哈希摘要算法计算每一个数据块的指纹,再利用指纹来区分不同内容的数据块,对于相同内容的数据块就只保存一份数据副本。目前重复数据删除技术已经成功应用到了数据备份和归档系统中。

基于flash的固态存储设备现在已经非常普及了,使用flash作为主存的U盘、数码产品随处可见。flash作为半导体存储器,相比磁盘具有很多的优点,比如更高的随机读写性能、抗震性和低能耗。可以说flash就是为了取代磁盘而出现的。

近些年来,得益于大量研究人员的努力,重复数据删除和flash技术都愈发成熟了,理应在更大的舞台上发挥作用,但是由于它们自身的一些限制,使得推广的步伐非常缓慢。

1.1 固态存储技术背景

1.1.1 基于NAND flash芯片的固态存储设备(SSD)


图1 三星公司NAND flash的内部结构

目前市场上的大部分SSD采用的都是NAND flash芯片, NAND flash的体系结构如图1所示[4]。在专业术语中,flash芯片又称为die,若干个die组成一个package;每一个die被划分为多个plane,每一个plane进一步被划分为数以千计的block(注意,这里的block和磁盘的块是不同的概念);每一个block由许多page(64-128个)组成;每一个page都包括一块数据区(通常4KB),和一些备用的存储空间,备用存储空间通常作为元数据区。因为目前磁盘仍然具有统治地位,大多数操作系统支持的是磁盘的驱动程序,所以在flash芯片之上实现了Flash Translation Layer(FTL),向外提供和磁盘一样的接口。

flash存储器支持三种基本操作:读、编程(写)和擦除。编程就是写操作,读和编程都是以page为单位的,而擦除是以block为单位。flash存储器在技术上有三个严格的限制:(1)不能二次编程,也就是对一个page只能编程一次,在下一次编程之前必须对整个block执行擦除操作;(2)不能随机写,一个block内的page必须按顺序写;(3)擦除的次数限制,block擦除一定次数就会磨损,通常是10,000到100,000次。

为了克服flash存储器的这些限制,设计者在FTL这一层为flash量身定做了很多的技术:(1)间接映射,flash存储器会保存一张逻辑地址和物理地址的映射表,将上层IO请求的逻辑地址转换为物理地址;(2)日志式的写操作,按照物理地址顺序一个接一个地写page,如果要向一个逻辑地址写数据,那么就将原来的物理page置为失效,把数据写到新page,再修改映射表;(3)垃圾回收,定期地回收有很多失效页的block,先将有效的页迁移到新的block上,再擦除block;(4)损耗平衡,由于某些热点数据的修改非常频繁,会导致某些block过早磨损,所以负载均衡机制会将IO负载均衡到每一个block上;(5)过量存储空间,为了帮助垃圾回收和损耗均衡,SSD通常会提供一些额外的存储空间。

1.1.2 SSD的寿命问题

SSD从最开始出现,人们对它的期望就是磁盘的替代者,但是时至今日,这一理想还远远没有实现。首先,flash的位密度越大,它的可靠性和寿命就越短;其次,传统的可靠性解决方案RAID,用于SSD并不成功;再次,SSD的寿命始终没有得到证明。这就解释了为什么SSD仍然只能出现在个人用户的U盘、数码产品这样的应用领域,而商业用户始终对大规模部署SSD心存疑虑,谁也不希望自己的存储设备突然就坏掉了。

一块flash存储器的寿命主要由两个因素决定:(1)写操作负载,显然写地越多flash寿终正寝地越快;(2)垃圾回收和损耗均衡机制,它们的实现策略对flash存储器的寿命会产生巨大的影响。目前大多数的研究工作都将重点放在第二个因素上,很少有人从第一个因素的角度来解决flash的寿命问题。这也是理所当然的,通常认为存储设备对IO负载只能逆来顺受。而本文的一个重点就是讨论如何从设备一级优化写操作负载。

1.2 重复数据删除技术背景

1.2.1 背景和基本方法

重复数据删除技术出现的早期,磁带库是备份和归档系统的主要存储介质,原因是备份和归档系统对存储空间的要求特别大,出于经济的考虑只能选用容量大、价格低廉的磁带库。但是随着磁盘技术的发展,磁盘的容量逐渐赶上了磁带,而且价格也不断下降,于是有人提出使用磁盘来存储备份数据。磁盘相对磁带的优势就是支持随机访问,这为重复数据删除技术的出现奠定了基础,通过结合磁盘技术和重复数据删除技术,可以大大节约成本。

一个典型的重复数据删除技术解决方案的基本步骤是分块、哈希、查重、存储和更新。    分块的功能是按照一定的粒度将数据流切分为数据块,最简单的作法是按照固定的长度进行切分,这样每一个数据块是一样长的,但是这样分块方法会出现数据偏移的问题,即增加或删除一个字节,后面的数据块将会受到影响。于是就出现了内容感知分块法,这种方法根据数据的内容进行分块,通常生成的数据块是不一样长的,最典型的就是采用Rabin指纹的分块算法。

哈希的功能是计算每一个数据块的指纹,指纹将会作为数据块的身份证,伴其终生。最长使用的哈希算法是SHA-1算法,它为每一个数据块生成一个20字节的指纹。指纹将会作为区分数据块的依据,这么做的原因是逐个字节比较数据块的开销太大了。

查重就是在系统里查找重复的指纹。重复数据删除系统会保存一张指纹索引,里面记录了所有已存储数据块的指纹,索引数据结构的实现有多种选择,可以采用哈希表和B树。查重是重复数据删除系统的关键环节,大多数研究人员都将精力放到了这一个环节。

存储就是将数据块写入存储设备,只有当查重没有发现重复数据块才会执行这一步,如果查重发现系统已经存储了该数据块,就会跳过这一步。

更新就是更新指纹索引,只有当查重没有发现重复数据块才会执行这一步,将该指纹插入到索引结构中,如果查重发现系统已经存储了该指纹,就会跳过这一步。

1.2.2 重复数据删除的性能问题

重复数据删除的逻辑虽然简单,但是存在的问题却不少,最引人关注的就是磁盘瓶颈问题。查重的关键是系统保存的指纹索引,如果采用SHA-1算法和8KB的平均块长,那么指纹和数据的比例大约是1:400,那么8TB的数据会产生20GB的指纹。重复数据删除的目的就是节约成本,那么用RAM来存储指纹无疑违背了这一原则,通常的作法就是使用磁盘来存储指纹索引。于是系统每接收一个数据块,都需要去访问磁盘中的指纹索引,而且极有可能导致多次磁盘IO,因为不论是哈希表还是B树,都不可能保证一次找到想要的数据。最坏的情况就是指纹索引根本没有该指纹,而系统不得不访问B树的高度次磁盘,更可悲的是这完全是无用功。

当存储成为性能瓶颈,最常用的作法有二:(1)使用速度更快的存储设备替代原有的存储设备;(2)使用体系结构的办法,用容量较小但速度更快的存储设备构建缓存。现在大多数的研究者采用的是第二种办法,考虑到SHA-1是随机性非常高的算法,指纹将会随机地分布在索引的各个位置,局部性很差导致了缓存的低命中率,所以设计一个优秀的缓存并不是一件容易的事情,好在现在已经有了非常成熟的解决方案。本文的一个重点是讨论如何使用第一种方法来解决性能问题。

目前重复数据删除技术已经被广泛应用到备份和归档领域,但是在主存储系统,如文件系统、虚拟机等应用场景,仍然举步维艰。据我所知,只有ZFS和opendedup文件系统采用了重复数据删除技术,而且更多的是实验性质。原因就是重复数据删除对系统的性能影响太大,不仅仅是前文提到的写性能,而且读性能也受到了影响,原因是经过重复数据删除之后的数据是离散分布在磁盘上的,使得文件系统的缓存不能发挥作用。

2 利用重复数据删除技术提高SSD的寿命

SSD的寿命问题是其还不能取代磁盘的重要原因,写密集型应用会加速SSD的损毁,IO负载是由上层应用决定,除了尽量避免SSD用于写密集型应用以外,还可以考虑如何从设备一级来减少IO负载。正如前文介绍的,重复数据删除技术可以发现IO负载中的重复数据,如果要写的数据已经存储在SSD了,那么就可以避免这一次写操作。但是重复数据删除技术会带来大量的计算开销,如果将其放在SSD读写的关键路径上,无疑对性能会产生严重的影响,下面介绍的CAFTL针对这些问题进行了研究。

2.1 CAFTL的重复数据删除

CAFTL[1]的全称是Content-Aware Flash Translation Layer,顾名思义就是要在FTL这一层拦截写入重复数据的IO请求。CAFTL在设计时面临的最大的挑战就是SSD本身的计算、内存资源十分有限以及非常高的性能要求。因此CAFTL从一开始就不准备追求完美的重删率,采用了in-line和out-of-line相结合的方式,在IO负载很重的情况下,将重复数据删除排除在关键路径之外,从而保证系统的性能。

因为文件系统的IO负载存在很多小写请求,备份系统常用的变长分块并不适合CAFTL的应用场景,所以CAFTL采用的是定长的分块方法,将数据块定为page大小,这种设定非常自然,因为flash的读写都是以page为单位的。

图2展示了CAFTL处理写请求的流程,(1)写请求的数据会被放到缓存中,(2)计算数据的指纹,(3)查找fingerprint store对指纹进行查重,(4)如果发现匹配的指纹,就更新映射表,将写请求的逻辑地址映射到匹配数据块的物理地址,(5)如果没有发现匹配的指纹,照常写入数据。

fingerprint store就是CAFTL的指纹索引,由于flash内存有限,再考虑到大部分指纹其实都没有机会发生匹配,CAFTL并不保存完整的指纹索引,而是保存发生匹配最多的热门指纹。如图所示,指纹索引被分为多个segment,segment又由bucket链表组成,bucket的每一个条目保存的信息是{?ngerprint, (location, hotness)},其中hotness表示这个指纹的热度(也就是引用数)。通过摸运算,指纹被映射到某个segment中,然后依次查找每一个bucket。

 

图2 CAFTL处理写请求的流程

考虑一下CAFTL的修改问题,IO请求修改一个page的数据,传统SSD只需要让旧page失效,将新数据写到新page再修改映射表。但是CAFTL需要查看是否有其它逻辑地址(LBA)被映射到这个旧page的物理地址(PBA),这就需要遍历整个映射表。因此CAFTL设计了二重映射机制,引入了虚拟地址(VBA)的概念,增加了二级映射表,表的每一个条目的信息是{PBA, reference},这里的reference指的是指纹的引用数,注意reference是4字节的,而hotness是1字节的,大于255的引用数都是一样的热度。指向同一个PBA的LBA将会改为指向一个VBA,再由VBA映射到PBA。考虑到31位地址可以寻址2G个page,相当于8TB数据,这对于目前的SSD已经足够了,CAFTL将32位地址的第一位用于区分PBA和VBA。如果要修改一个LBA的数据,先判断映射到的目标地址是PBA还是VBA,如果是VBA就不将旧page置为失效,而是将其引用次数减1。

2.2 in-line重复数据删除的性能优化

flash自身的资源是非常有限的,而重复数据删除对计算资源和内存资源的需求很大。图3是缓存大小对CAFTL读写性能影响,横坐标是11种不同的IO负载,纵坐标是相对于普通FTL的性能影响,当flash的内存很少时,重复数据删除对性能的影响比较严重,因为大量的写请求会因为不能得到缓存而被阻塞。图4是处理器对CAFTL读性能的影响,因为SSD的写是异步的,写入缓存就是写入成功,精确测量什么时候真正写入flash比较困难,所以通过测试读性能从侧面反映读被写阻塞了。可以说两个测试反映的都是缓冲区被填满后导致IO请求阻塞。针对这个问题,CAFTL采取了几个优化方法。

 
图3 缓存对CAFTL的影响

 

图4 哈希计算速度对性能的影响

CAFTL通过取样法减少指纹的计算。在文件系统的应用场景下,重复数据量并不是很多,这意味着大多数的指纹计算都是在“浪费”时间。因此CAFTL将若干个page组成一个抽样元组,从中取一个page计算指纹,如果这个指纹能在指纹索引中查到,说明这个元组中很有可能存在大量重复数据,反之则认为其中重复数据很少。CAFTL的抽样方法是对元组中每一个page读取前四个字节并转换为数字,选择值最大的page为样本。这种做法的理论依据是Broder定律[5],即两个集合最大或最小的元素相同的概率等于两个集合相似度。抽样法会丢失部分重删率,但对性能的改进比较显著。

预哈希技术,CAFTL为每一个page额外计算和存储一个4字节的CRC32校验码。因为CRC32的计算速度比SHA-1要快得多,所以在计算page的指纹之前先计算CRC32校验码,如果不能在指纹索引中查找到此校验码,就可以肯定其指纹也不在指纹索引里,从而避免SHA-1计算。

动态切换,当IO负载很高的时候,就关闭in-line重复数据删除。CAFTL通过观察缓存的使用情况来判断当前的IO负载,如果缓存所剩无几就关闭in-line重复数据删除,反之则开启in-line重复数据删除。

2.3 CAFTL的out-of-line重复数据删除

由于CAFTL对性能的要求很苛刻, out-of-line的重复数据删除几乎成为必然的选择,在系统空闲的时候进行重复数据删除可以避开IO请求的关键路径。

上文介绍的in-line重复数据删除会遗漏一些重复的数据,并且存在一些page没有计算指纹,out-of-line重复数据删除的工作就是找出“漏网之鱼”。out-of-line重复数据删除的工作原理比较简单,CAFTL扫描flash的元数据,找出未计算指纹的page,给它们补上SHA-1指纹并判断是否重复。

3 利用flash技术解决重复数据删除的磁盘瓶颈问题

flash的随机读性能和顺序读性能一样出色,从这点看无疑非常适合存储重复数据删除技术的指纹索引,因为指纹索引是一个读密集型的数据结构。但是flash也有缺点,其随机写性能比顺序写要低很多,而且flash的写以page为单位而且不能二次编程,这就导致小写成为flash的问题,而索引更新恰恰都是随机写和小写。下面就介绍一种扬长避短的解决方案:Chunk Metadata Store on Flash(ChunkStash)。

3.1 ChunkStash的体系结构

图5所示为ChunkStash[2]的体系结构,一共由三部分组成:RAM存储区,flash存储区和磁盘存储区。ChunkStash的磁盘存储区是一个container容器,如图6所示,这部分的设计采用的是Data Domain的设计方案[3],为了保护数据和指纹的局部性,所有的数据块都用container进行封装存储在磁盘上,container包括数据区(1024个数据块)和元数据区(64KB),数据区存储着数据块,元数据区存储了数据块的指纹、偏移、长度等元数据信息,container都是不可修改,内存中会有一个container缓冲区,当写满时就给container贴上“封条”写到磁盘去,如此既保护了数据的局部性也避免了磁盘小写。flash存储区存放container元数据区的副本,取代了磁盘中的指纹索引,为了避免随机写和小写,flash都是按顺序写的,而且和磁盘的container容器同步更新,一个container的元数据区是64KB,所以flash每次都是顺序写16个page(如果page是4KB的话)。RAM中的数据结构是最复杂的,也是ChunkStash的关键,Chunk Metadata Write Buffer是container缓冲区的元数据部分,Metadata Cache是指纹缓存,每次访问flash中的指纹就将其所属container的所有指纹都读入指纹缓存中,有效减少访问flash的次数,由于flash中的指纹是根据数据块的逻辑顺序存储的,必须在内存中对它建立索引方便查找,Hash Table Index就是为此设计的,它的结构比较复杂,可以将其看成是指纹索引的摘要。

 

图5 ChunkStash体系结构


图6 Container容器

图7是ChunkStash重复数据删除的流程图。当一个数据块到达系统,首先会在指纹缓存中查找,如果未命中就继续在container缓冲区中找,仍未找到则再查找哈希表定位其在flash中可能的位置,最后如果是新数据块就加入container缓冲区。
 

图7 流程图

3.2 为ChunkStash设计的哈希表

由于flash中的指纹按照数据块的逻辑顺序存储,必须为其建立索引,不然查重就得顺序遍历指纹库了。ChunkStash在内存中保存了一张哈希表来索引flash中的指纹库,这张哈希表的设计目标是每当指纹缓存未命中,最多只需要访问一次flash就可以判断指纹是否存在。哈希表的结构如图7所示,哈希表的每个条目需要6个字节。

 

图8 哈希表结构

哈希表使用的关键技术是cuckoo hashing。传统的解决哈希冲突的方法有线性探测和拉链法,线性探测会增加查询哈希表的时间,而拉链法占用较多内存。cuckoo hashing为每个键(在ChunkStash中就是指纹)分配n个候选位置,如果新来的键x的n个位置都被占了,那么就强迫其中一个位置的键y让出位置,y再在自己的剩余n-1个位置中找位置,依次类推直到所有键都找到位置。但是为y重新分配位置可能又会导致一系列重新分配,甚至产生死锁,所以系统只会尝试固定次数的重新分配,实在不行就把键放入辅助链表。这样查找哈希表的最坏情况是搜索n个位置加上辅助链表,研究表明,辅助链表的长度非常小。

ChunkStash的哈希表使用n个哈希函数h1,……,hn计算n个候选位置。要获得指纹的候选位置,就分别计算h1(x),……,hn(x),候选位置就是计算结果低位取模。图8中,compact key signature是指纹的摘要,取自哈希函数计算结果的高位,pointer是指向flash的指针。查找哈希表的过程是这样的:计算指纹x的第k个候选位置,即hk(x)的低位取模,再将哈希表中这个位置存储的签名和hk(x)的高位比较,如果不匹配就查找下一个候选位置,如果匹配就根据pointer找到flash中完整的指纹,如果完整的指纹也匹配就查找成功了,如果未匹配就表示查找失败,将指纹插入这个位置,并为这个位置的原指纹寻找其他的候选位置。

另外,在最坏的情况下,查询一次哈希表需要计算n个哈希函数,这是可以优化的。有研究表明两个哈希函数可以模拟多个哈希函数:

hi (x)=g1 (x)+i*g2 (x)

因此,在cuckoo hashing中使用较多的哈希函数并不会造成额外的开销。

3.3 ChunkStash性能评价

通过flash和RAM相结合的方式存储指纹索引,ChunkStash避免flash的随机写操作的同时,充分利用了flash的随机读性能。图9是ChunkStash和Data Domain设计方案Zhu08-BDB的比较,Zhu08-BDB在内存中用Bloom Filter过滤指纹索引中不存在的指纹,磁盘中用数据库保存完整指纹索引。纵坐标是备份吞吐率,横坐标表示两次完全备份,第一次重复数据较少,第二次重复数据很多。比较Zhu08-BDB-HDD和ChunkStash-SSD可以看出SSD对于性能的提高是非常明显的。实验还测试了ChunkStash的哈希表的效率,Zhu08-BDB-SSD表示将数据库存储在SSD中,比较Zhu08-BDB-SSD和ChunkStash-SSD可以看出哈希表的效率要比Bloom Filter高得多。

但是应该看到ChunkStash的高效是必然,因为不仅flash的成本要比磁盘高得多,而且其哈希表使用的RAM也比Bloom Filter多得多。每一个指纹需在哈希表占6字节,而平均块长为8KB、总数据量为8TB的数据集有1G个指纹,再考虑到哈希表的装载因子不可能是1,其实际消耗的内存空间还会更大。
 

图9 ChunkStash和DDFS的性能比较

4 总结

重复数据删除技术和flash存储器都是在存储学界讨论非常热门的技术,但由于各自存在的局限性,都未能在更多的场景中扮演更重要的角色。

重复数据删除技术能够节省大量的存储和带宽资源,但是同时带来大量的计算和索引开销,不能胜任对性能要求比较苛刻的场景。虚拟机是一个应用重复数据删除的理想领域,因为多个虚拟机之间经常安装相同的系统软件和应用,虚拟机磁盘镜像之间会存在大量重复数据,目前虽然已有研究人员进行了实验,但为了降低性能影响,大多采用了定长分块和out-of-line重复数据删除,使得重复数据删除不能发挥最大的作用。在文件系统中也存在可观的重复数据,文件系统的负载中读请求占据了很大的比例,而重复数据删除技术会将文件的数据分散在磁盘,使得缓存失效,导致大量磁盘随机读,所以鲜有文件系统提供对重复数据删除技术的支持,opendedup是其中的佼佼者。

SSD是以磁盘取代者的姿态出现在公众视野的,但目前来看,由于寿命和可靠性等方面的原因,要想彻底颠覆磁盘的地位仍然任重道远。flash芯片属于半导体存储器,具有容量较大、没有机械运动、能耗低、高效的随机访问等特点,但是其有限的擦除次数导致SSD的寿命较短。尽管SSD生产商宣称SSD能够支持数年的日常使用,关于SSD寿命的问题仍然讨论地非常激烈,SSD仍然有待证明自己。

研究人员发现二者之间其实存在互补的关系,SSD可以提供重复数据删除需要的随机访问速度,而重复数据删除可以通过降低SSD的IO负载来延长其寿命,于是近年来关于二者相互作用的研究越来越多。重复数据删除技术要想在文件系统等领域获得一席之地,一定需要像flash这样的新型存储期间的支持;而flash要想进军数据中心,而不仅仅是存在于玩具之中,也需要重复数据删除这样的技术来帮忙。

CAFTL和ChunkStash在这方面做了很好的尝试。通过in-line和out-of-line相结合的方式,以及一些优化策略,CAFTL把性能影响降低了很多,但是它的重删率也受到了很大的影响。为了避免flash不擅长的随机写和小写,ChunkStash在flash中存储了指纹库,内存中用压缩的指纹索引检索指纹库,这样可以达到很高的性能,但是消耗较多内存,导致成本很高。

参考文献

[1] Feng Chen, Tian Luo, Xiaodong Zhang. CAFTL: A Content-Aware Flash Translation Layer Enhancing the Lifespan of Flash Memory based Solid State Drives. In Proceedings of FAST’11.
[2] DEBNATH, B. , SENGUPTA, S. , AND LI, J. ChunkStash Speeding up Inline Storage Deduplication using Flash Memory. In Proceedings of USENIX’10.
[3] ZHU, B. , LI, K. , AND PATTERSON, H. Avoiding the Disk Bottleneck in the Data Domain Deduplication File System. In Proceedings of FAST’08.
[4] AGRAWAL, N. , PRABHAKARAN, V. , WOBBER, T. , DAVIS, J. D. , MANASSE, M. , AND PANIGRAHY, R. Design tradeoffs for SSD performance. In Proceedings of USENIX’08.
[5] A. Z. Broder. On the resemblance and containment of documents. In Proceedings of SEQUENCES ’97.


分类:

技术点:

相关文章: