CAS & deduplication 综述(关注去冗余存储)

本文总结了近十年围绕 CAS(content-addressable store) 和 deduplication 的主要工作,供借鉴。
【转载请注明作者、出处及链接】

该 topic 长期持续活跃,经过下面整理出的几个阶段,我们可以感觉到单纯 block/chunk level deduplication 的“矿”已经挖得差不多了:) 

====基本架构====

Venti [3] 是较早使用“unique hash of block = block identifier”思想(即 content-addressable store, CAS)的实现,可以说为其后的诸多系统提供了基本参照。
  • 只提供 block-level 的存储接口,block size 可根据应用需要改变,最大 52 KB
  • 文件可组织成 a tree of blocks,父 block 存储子 blocks 的 fingerprints [上层应用相关]
  • Hash 函数采用 20-byte SHA-1,60 MB/s (700 MHz Pentium 3)
  • 数据保存在 append-only log,基本单位为 self-contained arena;不提供垃圾回收
  • 用 disk-resident hash table 保存 index(从 fingerprint 到 location in log 的映射)。
      * 两级映射:index 由 bucket 组成,首先用 hash 把 fingerprint 映射到一个 bucket 上,然后在 bucket 内部使用 binary search 查找 entry(fingerprint+type+size+address)
      * stripping index across multiple disks
    [相当于 key-value store 内部实现,仅供参考]
  • Cache: block cache 与 index cache(分离)
  • I/O 测评:与 SCSI RAID 相比,大约 50% 以下。

SIS [2] 是较早基于 file-level 的去冗余文件系统,不属于 CAS,但放在这里作为对比。SIS 由一个用户态服务 groveler 根据 NTFS's updated journal 比较文件并去冗余(与我们最早的设计类似)。
  • variable-size file
  • 128 bit file signature 是很有借鉴意义的设计:前 64 bit 是文件大小,可以据此迅速缩小判断范围;余下 64 bit 是从文件 2 个固定部分各抽取 4KB 进行哈希(类似后来的 super-fingerprint [5] 和 sampling [9])。signature 相同的文件需要再进行 byte-by-byte 的比较才能确定相同。
  • Copy-on-close,只复制没有 overwritten 的部分。
  • Groveler 不是 CPU intensive,而是 I/O intensive(注意,离线去冗余的弊端)。

====比较研究====

[4] 比较了 whole file content, fixed size blocks, variable-length chunks (Rabin fingerprint) 三种方式。
  • 均采用 SHA-1 的前 64 bits 做判断标准,不影响实验结果
  • 对于 300 MB 的文件,在 500MHz Pentium 3 上,依次花费 62s(4.8 MB/s)、71s(4.2 MB/s)、340s(<1 MB/s),其中 Rabin fingerprint 包含了确定边界后计算 SHA-1 的时间(后者占 24% = 82s,< 4 MB/s)
  • Rabin 压缩比率最高,re-computation of SHA-1 较少,但有额外的定界开销
  • 通常情况下,update locality 使得相当部分 fixed size blocks 的 SHA-1 值是一直有效的

除此之外,delta encoding [1] 只保存两个文件之间的差异,也是去冗余的手段之一。常见的有三种实现:
  1. Unix diff:原只用于文本。对于二进制文件,可以先映射为文本,再使用 diff,但压缩比较低。
  2. Bdiff:可用于二进制文件。使用 64KB 的滑动窗口,按 16KB 的步长移动,建立 a suffix tree,而后扫描新文件,使用贪心策略寻找匹配的部分,最终将新文件表示为 copy blocks 和 character insertions 的序列。
  3. Vdelta:可用于二进制文件。使用 hash table 代替 suffix tree,同样基于贪心策略。输出表示为 add 和 copy 组成的序列。
Vdelta 的 encoding/decoding 效率明显高于其他,而压缩比率和 bdiff 不相上下。但是,三种编码方式都需要扫描原始文件。对于我们处理大文件部分更改的需求,这种扫描最好可以避免。与节省空间相比,我们更关心减少额外 I/O 和 en-/decoding 效率。


====技术组合====

进而出现了上述多种技术的组合——REBL [5],使用了 compression、elimination of content-defined chunks(CDC) 和 delta-compression of similar chunks,组合方式为:
  • 将文件使用 Rabin fingerprints 切割成 CDC,分别计算 SHA hash,保存在 Berkeley DB 中,重复的 chunk 去冗余;
  • 另一个进程分析这些 chunks,每个 chunk 提取若干 fingerprints(基于 chunk 的某些部分)组成 super-fingerprint 作为特征,用于计算相似性;基于这些相似性特征,选择出 reference chunks,然后其他 chunks 相对它们进行 delta-encoding;
  • 对于没有经过如上两种处理的 chunk,压缩存储。
文章偏重于 effectiveness,提供的图表都是压缩比率相关的,具体参数不在此赘述了,实现时可参考;对于 efficiency,只是提到 REBL 比 CDC 会有额外开销。

====优化改进====

Data Domain 在 [7] 中提出了三点改进,如下。注意该系统的基本存储单元不是 block,而是 container,后者也是 fixed-sized,但是包含更多信息(元数据段+数据段),是 self-describing 的(类似 Venti [3] 中组成 log 的 arena)。
  1. Bloom filter,迅速进行 in-memory 的判断 segment descriptor(对应于我们这里所说的 chunk fingerprint)是否存在,确定不存在的可直接插入,从而减少一次 index lookup(可能读磁盘)。
  2. Segment layout 遵照 data stream 的顺序连续存储于同个 container 当中,以保持 spatial locality。即便经过去冗余,一个文件片段所对应的 segments 往往也是连续的。
  3. 利用第 2 条,cache 预取 segment 所在 container 的元数据。

Sparse indexing [9] 与 [7] 解决的是同一个问题:chunk-lookup disk bottleneck problem,即 fingerprint 映射到 chunk location 的 index 无法保存在 RAM 中,使得 lookup 时经常需要 disk seek。
但是它采取了不同的方法:
  • 利用 chunk locality(类似 [7] 的 spacial locality):某次访问 chunk A 时临近访问了 B、C 和 D,下次即使在不同的 backup data 中,很可能访问 chunk A 的前后还会遇到 B、C 和 D。
  • 使用 CDC 把数据流切割成 chunks,然后同理再将 thousands of chunks 组成一个大粒度的 segment(若干 MB 大小)。(类比到 file-level,可视作文件切块)
  • Sampling 指从一个 segment 当中选取小部分 chunk hash 作为 hooks(代表特征),而不是 full index 全部 chunks,这样可以把由 hooks 组成的 sparse index 放入 RAM 中。
  • 当一个新的 segment 到来时,通过 parse index 从已有 segments 中选择 hooks 重合多(即最相似)的若干个作为 chunk deduplication 的比较对象;再将这些选中的 segments 的 manifests(类似元数据,包含每个 chunk 的 hash 和 address)载入内存进行 chunk 的去冗余。
这个工作是面向 inline 的,对 segment 的去冗操作由原先 chunk 数量的 disk seeks,减少为 manifests 的数量(可差 2 个数量级);可见,如果把 segment 类比为我们 file-level 的文件切块,即便 index 仍无法放入内存,每个切块 1 次的 disk seek 也是可以接受的。


Foundation [8] 仿照 Venti [3],但只针对个人用户(实验只在单台 laptop 上做的),声称在低端硬件上实现了高吞吐的 archival,主要改进如下:
  • 使用 bloom filter 判断新数据,与上述 [7] 的做法一致。
  • 设置 index update buffer(数据不另设缓冲,认为直接写入 log 存储),减少 fresh write 更新 index 的开销;定期 pause & flush。
  • 比较了 compare-by-hash 和 compare-by-value 两种实现;后者用 offset 而不是 hash 定位 blocks(严格说不再是 CAS,类似 SIS [2]),并用 MD4 的前 4 bytes 作为初步判重标准取代 SHA-1,之后再进行 byte-by-byte 比较确定相同。
  • By-value 的读性能恒高于 by-hash,但作者测试认为写性能也比较接近。(为 file-level 的读性能提供了有利证据)

[12] 作为一篇 best paper,把性能做到了极致,一个 single node 可以达到写 1 GB/s for unique data and 6 GB/s for duplicate data,读 1 GB/s for single stream and 430 MB/s for multiple streams,支持 123 billion objects, 500 TB of data per 25 GB of memory。(不过这也意味着,我们需要大量的 data nodes 才可能支持 thousands of VMs 的需求)

作者坦言“the opportunities for deduplication efficiency optimizations become scarce”,但定位于“combine with careful implementations of known system engineering techniques”。当然,技术上的改进也颇具新意:
  • Progressive sampled indexing:与 [7, 9] 一致,首要解决 index lookup 的瓶颈。这里用了一个小伎俩,把 fingerprint 和 location 都存在 file metadata 中,这样读取文件时可避免 index lookup(严格说已经不是 CAS 了);与 [9] 类似不保存 full index,而是取一部分(sampling),与 [9] 不同的是没有复杂的 segment 选择过程,就直接 chunk deduplication,并将命中 fingerprint 对应 container 的所有 fingerprints 都载入 cache,根据 locality 随后很可能仍会命中。
  • 特别提出了以往系统常常忽略但又很重要的部分 reference management,对垃圾回收有重要作用。它没有采用简单引用计数的方式,而是考虑 reliability and recoverability 选择了 mark-and-sweep 的方法,并为解决其 scalability 问题,提出了 grouped mark-and-sweep。
  • 改进了 client-server interaction,采用基于 fully asynchronous RPC 的 event-driven, pipelined design。(我们设计 C/S 交互流程时要特别参考)

==== Beyond CAS ====

Deep Store [6] 和 EMC Centera 都是基于 object store 的 CAS,所以提供了独特的功能:
  • rich metadata:metadata 和 data 同时存放于 object 当中,archival 的时间长久到产生它们的系统都不复存在时,这些数据依然具备可管理性;
  • diverse search features:对象存储具备基于对象特征的搜索功能;
  • 以及 dynamically scalable、improved reliability 等。

HYDRAstor [10] 和 HydraFS [11] 共同构成了一个存储系统,分别属于后端(block-level store)和前端(file system):
  • HYDRAstor [10] 是一个基于“a grid of storage nodes”+“a distributed hash table”的存储系统,论文的立足点就在于“a concrete commercial implementation”。 因此,它着重完善了 system-wide deduplication、high availability、on-line extensions and upgrades、disk/node/network fault-tolerance、automatic rebuilds on failures 等等,并且提供了一个 low-level API 的编程模型,可供 client 实现新的访问协议。
  • 进而,[11] 研究了如何基于 CAS 搭建一个高效 file system 的问题。主要的设计在于 cache:
    • 应对了三个挑战:updates 代价更高了、cache misses for metadata blocks、需要更大的 write buffer / read cache
    • 相应地,设计策略有:分离 metadata 和 data 的处理过程,将 metadata modifications 集中为 batch(类似 [8] 的 index update buffer);使用 fixed-size caches,限制并行文件系统操作的数量;使用二级 cache。

===============

【结论 / 启示】

Cinquain 的定位是 file-level deduplication,就需要处理 file-level 带来的新问题,利用 block-level 不具备的独特优势。
  1. 我们可以评估 file-level 所需 fingerprints(数量远少于 block-level 的)是否可能常驻内存,如果不行的话再考虑 key-value store 上层添加 bloom filter 等技术。

  2. NFS servers 需要配置缓存/缓冲,特别是写缓存/缓冲(大文件的 hash 计算可并行处理;当频繁更改某个文件时可避免没必要的去冗余存储)。由于文件体积可能较大,meta cache 和 data cache 分离较为合理。

  3. 多种去冗技术的组合,集中体现在大文件处理上。我们的目标是尽量避免大文件部分更改时重新读取整个文件(用于重计算 hash 和 COW),即达到:
        (1) 通过更改的部分计算新的 hash 值
        (2) 通过更改的部分计算 delta-encoding

  4. 与 block-level 相比,文件所具有的特殊而又易于获取的属性(比如大小、类型),应该可以给予利用,以减小碰撞和优化查询。

  5. Inheritance 带来的文件之间的新关系也可被利用增强去冗余效果和效率。
除此之外,对 key-value store 的性能要求应该是很高的,value 的定位时间应该接近于 CAS 实现。
同时对未来测试环境表示担忧,一个解决办法是将 FS-related 和 VM-related 分开测试,因为前者可以放到 Amazon 上,以达到性能测试规模;后者只能本地测试,主要验证 inheritance 对 VM 的功能性支持。

P.S. 张扬,我觉得 Liquid 或可考虑 ICDE 等偏数据库/数据管理的会(参照 [6])。如果认为 Liquid 在去冗余技术层面创新空间已很有限的话,将其包装成专门优化支持 VM images 数据管理的存储系统,应该可以靠上 ICDE 的宗旨 in designing, building, managing, and evaluating advanced data-intensive systems and applications. 况且,他们领域的人对去冗余存储未必了解那么全面。其实 [6] 就是用了对象存储,强调了可管理特性。

==========

Reference

[1] Hunt, J. J.; Vo, K.-P. and Tichy, W. F. Delta algorithms: an empirical analysis. ACM Trans. Softw. Eng. Methodol., ACM, 1998, 7, 192-214.

[2] Bolosky, W. J.; Corbin, S.; Goebel, D. and Douceur, J. R. Single instance storage in Windows 2000. In Proceedings of the 4th conference on USENIX Windows Systems Symposium, USENIX Association, 2000.

[3] Quinlan, S. and Dorward, S. Venti: a new approach to archival storage. In Proceedings of the 1st USENIX conference on File and storage technologies (FAST '02), USENIX Association, 2002.

[4] Policroniades, C. and Pratt, I. Alternatives for detecting redundancy in storage systems data. In Proceedings of the USENIX Annual Technical Conference (FAST '04), USENIX Association, 2004.

[5] Kulkarni, P.; Douglis, F.; LaVoie, J. and Tracey, J. M. Redundancy elimination within large collections of files. In Proceedings of the USENIX Annual Technical Conference (USENIX '04), USENIX Association,2004.

[6] You, L.L.; Pollack, K.T. and Long, D.D.E. Deep Store: an archival storage system architecture. In Proceedings of the 21st International Conference on Data Engineering (ICDE '05), IEEE, 2005.  

[7] Zhu, B.; Li, K. and Patterson, H. Avoiding the disk bottleneck in the data domain deduplication file system. In Proceedings of the 6th USENIX Conference on File and Storage Technologies (FAST '08), USENIX Association, 2008.

[8] Rhea, S.; Cox, R. and Pesterev, A. Fast, inexpensive content-addressed storage in foundation. In USENIX 2008 Annual Technical Conference (USENIX '08), USENIX Association, 2008, 143-156.

[9] Lillibridge, M.; Eshghi, K.; Bhagwat, D.; Deolalikar, V.; Trezise, G. and Camble, P. Sparse indexing: large scale, inline deduplication using sampling and locality. In Proccedings of the 7th conference on File and storage technologies (FAST '09), USENIX Association, 2009, 111-123.

[10] Dubnicki, C.; Gryz, L.; Heldt, L.; Kaczmarczyk, M.; Kilian, W.; Strzelczak, P.; Szczepkowski, J.; Ungureanu, C. and Welnicki, M. HYDRAstor: a scalable secondary storage. In Proccedings of the 7th USENIX Conference on File and Storage Technologies (FAST '09), USENIX Association, 2009, 197-210.

[11] Ungureanu, C.; Atkin, B.; Aranya, A.; Gokhale, S.; Rago, S.; Grzegorz, C.; Dubnicki, C. and Bohra, A. HydraFS: a high-throughput file system for the HYDRAstor content-addressable storage system. In Proceedings of the 8th USENIX conference on File and storage technologies (FAST '10), USENIX Association, 2010.

[12] Guo, F. and Efstathopoulos, P. Building a high-performance deduplication system. In Proceedings of the 2011 USENIX Annual Technical Conference (USENIX '11), USENIX Association, 2011.

你可能感兴趣的:(cache,File,存储,reference,inheritance,asynchronous)