列存储
垂直存储方案是基于面向列的存储模型,主要用于读取优化的数据仓库系统中。在垂直存储中,一个关系被垂直划分为若干个子关系,垂直存储的方案基本上有两种:
下图展示了如何在 HDFS 上如何按列组(column-group)存储的示例。在本例中,列 A 和列 B 存储在同一个列组中,而列 C 和列 D 存储在两个独立的列组中。列式存储可以避免在查询执行期间读取不必要的列,并且可以通过压缩同一数据域中的每一列轻松实现高压缩比。但是,由于元组重构的高开销,它不能在基于 hadoop 的系统中提供快速的查询处理。这种列式存储不能保证同一记录中的所有字段都位于同一集群节点中。例如,本列中一条记录的四个字段存储在可以位于不同节点的三个 HDFS 块中。因此,一次记录重构会导致多个集群节点之间通过网络进行大量的数据传输。正如在最初的 MapReduce 论文中所介绍的,MapReduce 集群中过度的网络传输总是会成为瓶颈来源,应该尽可能避免。
PAX 使用了一种混合存储结构,旨在提高 CPU 缓存性能。对于具有来自不同列的多个字段的记录,PAX 不是将这些字段放在不同的磁盘页中,而是将它们放在单个磁盘页中,以保存用于记录重构的额外操作。在每个磁盘页中,PAX 使用一个微型页(mini-page)来存储属于每个列的所有字段,并使用一个页头来存储指向微型页的指针。
类似于行存储,PAX 对多种动态查询有很强的适应能力。然而,它并不能满足大型分布式系统对于高存储空间利用率和快速查询处理的需求,原因在于:
基于上面的总结,Facebook 为基于 MapReduce 的数据仓库系统(如Hive)设计了一种新的数据放置结构:RCFile。RCFile 应用了来自 PAX 的“首先水平划分数据,然后再垂直划分列”的概念。它结合了行式存储和列式存储的优势。首先,RCFile 保证了同一行中的数据位于同一节点中,因此具有较低的元组重构成本。其次,RCFile 可以利用按列的数据压缩并跳过不必要的列读取。
RCFile 是基于 HDFS 之上设计的,具体如下图所示:
RCFile 的存储设计如下:
RCFile 的每个行组中,元数据头部和表格数据段分别进行压缩。
对于元数据头部,RCFile 使用 RLE(Run Length Encoding)算法来压缩数据。由于同一列中所有域的长度值都顺序存储在该部分,RLE 算法能够找到重复值的长序列,尤其对于固定的域长度。
对于数据部分,RCFile 不会对整个数据部分作为整个单元来压缩;相反每个列被独立压缩,RCFile 使用重量级的 Gzip 压缩算法,这是因为可以获得较好的压缩比。此外,由于 Lazy 解压策略,当处理一个行组时,RCFile 不需要解压所有列,可以提高数据的处理效率。
RCFile 对数据部分的所有列使用同样的压缩算法,不过如果使用不同的算法来压缩不同列效果会更好,这也就是 ORCFile 的一项改进。另外,RCFile 还有一些其他缺点,比如区分不同行组时需要扫描同步标记。为了解决这些问题,Facebook 工程师在探索如何更加高效的处理数据,就在同一时刻,HortonWorks 的工程师设计并实现了 ORCFile 文件格式,其就是针对 RCFile 进行了优化,这个我们准备在另外一篇文章进行介绍,敬请关注。
本博客文章除特别声明,全部都是原创!