12

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

  1. 使用 HBase 列限定符作为键的名称。这将使行宽,但非常稀疏。
  2. 将所有数据转储到单个列中并使用 Avro 或 Thrift 对其进行序列化。

这两种方法的设计权衡是什么?一个比另一个更可取吗?他们有什么理由不使用 Avro 或 Thrift 存储数据吗?

4

2 回答 2

12

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

1)显然,您是在强加客户端使用 Avro/Thrift,这是另一个依赖项。这种依赖性意味着您可以消除某些工具的可能性,例如 BI 工具,它们希望在数据中找到值而不进行转换。

2) 在 avro/thrift 方案下,您几乎被迫将整个价值带到线上。根据一行中有多少数据,这可能无关紧要。但是,如果您只对“城市”字段/列限定符感兴趣,您仍然需要获取“付款”、“信用卡信息”等。这也可能会带来安全问题。

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

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

5) 像 HBase 这样的 BigTable 实现非常适合非常宽、稀疏的表,因此不会像您预期的那样对性能造成影响。

于 2013-01-29T17:44:10.477 回答
5

这个问题的正确答案有点复杂,所以我先给你 tl;dr。

使用 Avro/Thrift/Protobuf

您需要在记录与列中包含多少字段之间取得平衡。

您通常希望将经常访问的字段(原始问题中的“键”)一起放入 avro 记录之类的内容中,因为正如 cmonkey 所述,您不希望检索不会使用的额外数据的开销。

通过使行非常宽,由于 HFile 的存储方式,您将在获取列子集时增加查找时间。同样,确定什么是最佳的,取决于您的访问模式。

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

您应该几乎总是在 HBase 中使用压缩(SNAPPY 始终是一个不错的选择)。

于 2014-01-28T07:05:46.850 回答