使用HBro列或使用Avro序列化数据是否更好?

时间:2013-01-29 17:21:00

标签: java hbase

我正在开发一个项目,该项目使用HBase存储用户的键/值信息。我们正在重新设计我们正在使用的HBase架构。正在讨论的两个选项是:

  1. 使用HBase列限定符作为键的名称。这会使行宽,但非常稀疏。
  2. 将所有数据转储到单个列中,并使用Avro或Thrift对其进行序列化。
  3. 这两种方法的设计权衡是什么?一个比另一个好吗?它们是否有任何理由不使用Avro或Thrift存储数据?

2 个答案:

答案 0 :(得分:9)

总之,我倾向于为每个键使用不同的列。

1)显然,你强调客户端使用Avro / Thrift,这是另一种依赖。这种依赖性意味着您可以消除某些工具的可能性,例如期望在没有转换的情况下在数据中查找值的BI工具。

2)在avro / thrift计划下,你几乎被迫将整个价值带到了线上。根据连续的数据量,这可能无关紧要。但是,如果您只对“城市”字段/列限定符感兴趣,则仍需要“付款”,“信用卡信息”等。这也可能会带来安全问题。

3)如果需要,Avro / Thrift的更新将更具挑战性。示例:您决定添加'hasIphone6'键。 Avro / Thrift:您将被迫删除该行并使用添加的字段创建一个新行。在列方案下,附加一个新条目,仅包含新列。对于单行而言,并不大,但如果这样做到十亿行,则需要进行大规模的压缩操作。

4)如果已配置,您可以在HBase中使用压缩,这可能会超过avro / thrift序列化,因为它可以压缩列族,而不仅仅是单个记录。

5)像HBase这样的BigTable实现非常适用于非常宽的稀疏表,因此不会像预期的那样出现性能损失。

答案 1 :(得分:3)

对此的正确答案有点复杂,所以我先给你tl; dr先生。

使用Avro / Thrift / Protobuf

您需要在记录与列中打包的字段数之间取得平衡。

您通常希望将经常一起访问的字段(原始问题中的“键”)放入类似avro记录的内容中,因为正如cmonkey所提到的,您不希望获得额外数据的开销,这是您赢得的额外数据使用。

通过使您的行非常宽,由于HFiles的存储方式,您在获取列的子集时会增加搜索时间。再次,确定什么是最佳,归结为您的访问模式。

我还想指出,通过使用像avro这样的东西,你也可以为自己提供进化。您不需要删除该行并使用包含新字段的记录重新添加该行。 Avro具有向后兼容性和向前兼容性的规则。这实际上使您的生活变得更加轻松,因为您可以读取新旧记录,而无需重写数据或强制更新旧客户端代码。

你应该几乎总是在HB​​ase中使用压缩(SNAPPY总是一个不错的选择)。