hadoop - 最高效的 HDFS 数据存储格式
问题描述
我必须在 HDFS 的专用存储服务器上存储大量数据。这是某种历史数据的存档。存储的数据是面向行的,并且有数十种不同类型的字段。其中一些是字符串,一些是整数,还有一些浮点数、短裤、数组列表和地图。
这个想法是使用 MapReduce 或 Spark 作业不时扫描数据。
目前我将它们存储为 SequenceFiles,其中 NullWritable 作为键,自定义 WritableComparable 类作为值。这个自定义类定义了所有这些字段。
我想实现两个目标 - 一个是优化数据大小,因为它变得非常大,我必须每隔几周添加新服务器,成本不断增长。另一件事是更容易添加新字段 - 在当前状态下,如果我想添加一些新字段,我将不得不重写所有旧数据。
我试图通过在这个类中使用 EnumMap 来实现这一点。它给出了相当不错的结果,因为它可以轻松添加新字段,并且数据大小减少了 20%(原因是记录中的很多字段通常是空的)。但是我写的代码看起来很糟糕,当我尝试将列表和地图添加到这个 EnumMap 时,它变得更加丑陋。相同类型的数据没问题,但尝试组合所有字段是一场噩梦。
所以我想到了一些其他流行的格式。我尝试过 Avro 和 Parquet,但在尝试使用 Enums 之前,数据的大小几乎与使用自定义类的 SequenceFiles 完全相同。所以它解决了添加新字段而不需要重写旧数据的问题,但我觉得优化数据大小的潜力更大。
我还要检查的另一件事当然是加载数据所需的时间(这也会告诉我是否可以使用 bzip2 压缩,或者由于性能原因我必须回到 gzip),但在我之前继续这个我想知道是否有人会提出其他解决方案或提示。
提前感谢所有评论。
解决方案
您的大多数方法似乎都不错。我只是决定在这个答案中添加一些我的想法。
存储的数据是面向行的,并且有数十种不同类型的字段。其中一些是字符串,一些是整数,还有一些浮点数、短裤、数组列表和地图。
您在这里提到的所有类型都没有比spark 支持的数据类型更复杂。所以我不会以任何方式更改数据类型。
实现两个目标 - 一个是优化数据大小,因为它变得非常大,我必须每隔几周添加新服务器,并且成本不断增长。
通过添加服务器,您是否也在添加计算?存储应该相对便宜,我想知道您是否正在为您的服务器添加计算,而您并不真正需要。您应该只为存储和检索数据付费。考虑一个像 S3 这样的简单对象存储,它只向您收取存储空间的费用,并提供免费的访问请求配额(GET/PUT/POST)——我相信大约有 1000 个请求是免费的,每月 1 TB 的存储成本仅为 10 美元.
另一件事是更容易添加新字段 - 在当前状态下,如果我想添加一些新字段,我将不得不重写所有旧数据。
如果您有一个用例,您将更频繁地写入文件而不是读取,我建议不要将文件存储在 HDFS 上。它更适合一次写入,多次读取类型的应用程序。也就是说,我建议使用 parquet 开始,因为我认为您将需要一种允许对数据进行切片和切块的文件格式。Avro 也是一个不错的选择,因为它还支持模式演化。但是,如果您有一个复杂的结构,您需要指定架构并使其更容易使用 java 对象进行序列化/反序列化,则最好使用它。
我还要检查的另一件事当然是加载数据所需的时间(这也会告诉我是否可以使用 bzip2 压缩,或者由于性能原因我必须回到 gzip)
Bzip2 的压缩率最高,但也是最慢的。因此,如果数据没有真正经常使用/查询,我会推荐它。Gzip 具有与 Bzip2 相当的压缩率,但速度稍快。还要考虑 snappy 压缩,因为它具有性能和存储的平衡,并且可以支持某些文件类型(parquet 或 avro)的可拆分文件,这对于 map-reduce 作业很有用。
推荐阅读
- ios - 如何在 Swift 中分隔字符串中的两个 URL?
- python - 如何设置 python-mode 以便 linter 检查 python 3 和 python 2 错误
- vue.js - 作为道具传递的对象数组不更新子组件
- checkbox - 在 Google 表格中启用/禁用复选框
- python - TypeError:“Mul”Op 的输入“y”的类型为 float32,与参数“x”的类型 float64 不匹配
- jekyll - 如何在 GitHub Pages 上生成指向帖子原始降价文件的链接?
- azure-powershell - 获取 AzureStorageBlobContent 超时
- android - Android - 无法运行 aapt dump badging:'android:icon' 属性:属性值引用不存在
- machine-learning - Seeker 识别(机器学习)
- spring-boot - 如何使用 Spring Boot 每秒支持几千个请求