HDFS对象存储的版本管理设计

前言


前篇文章,笔者已经大致介绍了目前HDFS对象存储服务Ozone内部的基本架构。本篇文章,笔者继续带领大家学习Ozone。今天笔者所主要阐述的主题是:Ozone的对象版本管理。版本管理是一个很实用的需求,用户往往对于一份数据会有历史版本保存的需求,不仅仅说只是为了防止未来的时候会回退到这个版本的数据。本文我们就来看看Ozone是如何支持这个功能的。目前此功能尚未开发,还处于初始设计阶段,但是并不妨碍我们对这套设计做一个预先学习。

数据历史版本管理简单方案


在这里,我们假设脱离于本文内容,做这样一个思考:如果我们要做数据的版本管理,我们可以怎么做?下面是笔者想到的一种比较直接又显得比较low的方法:

每次全量存储写入新的数据,并分配一个唯一标识版本号。

以上这种方式是偏简单暴力的。它有一个很致命的缺点:完全不考虑写入数据是否与现有历史数据是重复的情况。这会带来使用空间浪费的现象。当然,有人可能会说笔者的这种想法完全是杞人忧天,我们这里的一个假设是基于用户每次存入的数据是不同的。但是话说回来,做一个完整的系统设计,我们还是需要考虑很多因素的。

类似数据版本管理方案:HDFS快照


在HDFS内部,有一个类似的数据版本管理功能:HDFS快照。笔者前面提到的可能出现重复数据的问题就是源于快照对这方面的处理。HDFS快照功能在这方面的实现可谓是下了功夫的,它的一个特点是只存入差异的数据,即发生过变更的数据文件。如果数据没有发生过没变,则快照数据返回的则是当前文件数据。这么做是有道理的,如果每次都是一股脑全部拷贝保存,HDFS存储资源多浪费啊。HDFS快照相关的细节大家可以阅读笔者之前写过的一篇文章:HDFS快照管理

Ozone存储对象版本管理


前面铺垫介绍了这么多,现在终于要进入本文主题了。在目前Ozone第一期实现中,数据是单一版本存储的,就是一个key对应一份数据,当再往这个key里,put数据的时候,就是覆盖操作了。当用户要往Ozone中写数据的时候,需要提前向KSM申请一个block,每个block会有大小的限制,所以如果要写入key的数据比较大的时候,这个时候需要申请多个block。所以目前Ozone不带版本支持的架构如下图所示:


这里写图片描述

OK,我们继续来看,如果是增加了版本支持,会是什么样的一个情形呢?为了简单理解,我们暂且考虑一个key,一个版本对应的就是一个单一的block。
首先第一个版本,很简单,就是一对一的关系存储,假设我们写入了6MB的数据,如下图:


这里写图片描述

key与block的关系图


这里写图片描述

对应的元信息关系映射:


这里写图片描述

后面的情况就比较特殊了,会存在2种情况:

  • 对之前的某个偏移位置进行update操作。
  • 在上一版本基础上进行追加写操作。

我们可以理解为后一版本的数据就是对上一版本数据进行往前或向后更新数据。下面我们来看其中的细节操作。

往前修改数据,修改数据需要知道以下信息点:

从哪个偏移量处开始修改数据,也就是从哪个位置处再次写入数据,写入多少长度数据

假设我们在第二个版本中,修改了前面数据在4MB左右的位置,新写入1.25MB的数据。那么此时数据的逻辑结构将变为下图所示:


这里写图片描述

但这里并不是说v2版本数据直接覆盖v1版本对应的数据,二者是共存的关系。只是v2版本的数据在4MB之后的位置应是block2写入的数据。
V2版本中key和block数据映射图


这里写图片描述

元信息映射信息


这里写图片描述

接着我们看另外一种情况,也就是下一个版本v3,进行数据追加写的时候。这种情况比较简单,写入数据到一个新的块,偏移量直接从上一版本的长度位置开始。假设此时,新写入数据2MB,如下图


这里写图片描述

此时元信息关系表变为如下所示:


这里写图片描述

那么问题来了,在这样的逻辑组织情况下,我们如何返回给定版本的数据呢?答案是采用汇聚的形式进行数据的返回。具体来说如下:

  • 1.V1版本数据,直接返回block1的数据,
  • 2.V2版本数据,返回block1[0, 4MB]的数据+block2[0, 1.25MB]+block1[5.25, 6MB]
  • 3.V3版本数据,返回block1[0, 4MB]的数据+block2[0, 1.25MB]+block1[5.25, 6MB]+block3[6, 8MB]

从这里可以看出,此时IO的操作会比单一版本情况下会多很多,最后是用聚合IO的方式来展现各个版本的数据。IO向量信息如下表所示:


这里写图片描述

这种多版本数据的管理方式比较灵活,也可以避免重复数据对于存储空间的浪费。唯一一个缺点是可能看上去不是很好理解。但是总的来说,对于对象存储这样在未来可能会存储数以千万甚至亿级别的对象数据时,这样的设计还是大有裨益的。

OK,以上就是HDFS Ozone对于小对象数据存储的历史版本管理设计,希望能给想要做这方面类似系统的同学带来帮助和启发。

参考资料


[1].https://issues.apache.org/jira/secure/attachment/12877154/OzoneVersion.001.pdf

原文地址:https://www.cnblogs.com/bianqi/p/12183665.html