hadoop—最有效的hdfs数据存储格式

g2ieeal7  于 2021-07-15  发布在  Hadoop
关注(0)|答案(1)|浏览(420)

我必须在hdfs中的专用存储服务器上存储大量数据。这是一种历史数据档案。存储的数据是面向行的,有几十种不同的字段。其中有些是字符串,有些是整数,也有一些浮点数,短数组,数组列表和一个Map。
这个想法是,数据将被扫描不时使用mapreduce或spark作业。
目前我将它们存储为SequenceFile,其中nullwritable作为键,CustomWritableComparable类作为值。这个自定义类定义了所有这些字段。
我想实现两个目标-一个是优化数据的大小,因为它正变得越来越大,我必须每隔几周添加一个新的服务器,而且成本不断增长。另一件事是更容易添加新字段-在当前状态下,如果我想添加一些新字段,我必须重写所有旧数据。
我试图通过在这个类中使用enummap来实现这一点。它给出了相当好的结果,因为它允许很容易地添加新字段,而且数据的大小也减少了20%(原因是记录中的许多字段通常是空的)。但是我写的代码看起来很糟糕,当我尝试添加到这个enummap时,它会变得更难看。对于同一类型的数据是可以的,但是尝试合并所有字段是一场噩梦。
所以我想到了一些其他流行的格式。我尝试过avro和parquet,但在尝试枚举之前,数据的大小几乎和带有自定义类的sequencefiles完全相同。因此,它解决了添加新字段而不需要重写旧数据的问题,但我觉得优化数据大小的潜力更大。
我还要检查的一件事当然是加载数据所需的时间(这也会告诉我是否可以使用bzip2压缩,或者因为性能原因我必须返回gzip),但在继续之前,我想知道是否有人会建议其他解决方案或提示。
提前感谢所有评论。

fkvaft9z

fkvaft9z1#

你大部分的方法都很好。我决定在这个答案中加入我的一些想法。
存储的数据是面向行的,有几十种不同的字段。其中有些是字符串,有些是整数,也有一些浮点数,短数组,数组列表和一个Map。
您在这里提到的所有类型都不比spark支持的数据类型复杂。所以我不会费心去改变数据类型。
实现两个目标—一个是优化数据的大小,因为数据越来越大,我必须每隔几周添加一个新服务器,而且成本不断增长。
通过添加服务器,您是否也在添加计算?存储应该是相对便宜的,我想知道你是不是在服务器上添加了计算机,而你其实并不需要。您应该只为存储和检索数据而付费。考虑一个像s3这样的简单对象存储,它只对存储空间收费,并提供免费的访问请求配额(get/put/post)——我相信大约有1000个请求是免费的,每个月一TB的存储只需要大约10美元。
另一件事是更容易添加新字段-在当前状态下,如果我想添加一些新字段,我必须重写所有旧数据。
如果您有这样一个用例,您将更频繁地写入文件而不是读取文件,我建议不要将文件存储在hdfs上。它更适合于一次写入、多次读取类型的应用程序。也就是说,我建议使用parquet开始,因为我认为您需要一种允许对数据进行切片和切割的文件格式。avro也是一个不错的选择,因为它还支持模式演化。但是如果您有一个复杂的结构,需要指定模式,并且更容易用java对象进行序列化/反序列化,那么最好使用它。
我还要检查的一件事当然是加载数据所需的时间(这也会告诉我是否可以使用bzip2压缩,或者因为性能原因我必须返回gzip)
bzip2的压缩率最高,但也是最慢的。因此,如果数据不经常使用/查询,我建议使用它。gzip具有与bzip2相当的压缩能力,但速度稍快。还要考虑snappy压缩,因为它具有性能和存储的平衡,并且可以支持某些文件类型(parquet或avro)的可拆分文件,这对于map reduce作业非常有用。

相关问题