HBase 和 Schema 设计

贡献者:Raymondcode

关于各种非 RDBMS 数据存储建模的优缺点,可以在 Ian Varley 的硕士论文 No Relation: The Mixed Blessings of Non-Relational Databases 中找到。虽然有点过时,但是如果你想了解 HBase schema 的建模方式和 RDBMS 的实现方式有什么区别的话,可以当做背景知识阅读一下。另外,阅读 keyvalue 来了解 HBase 内部是如何存储数据的,以及 schema.casestudies 章节。

Cloud Bigtable 网站上的 Designing Your Schema 是很好的相关文档,从里面学到的内容同样适用于 HBase 领域;只要把文档里任何引用的值除 10 左右即可得到对 HBase 适用的值。比如:文档中提到单个值的大小可以到约 10MBs,HBase 也类似,或者最好尽可能的小一些;同时文档中提到,Cloud Bigtable 最多有 100 个列族,在 HBase 建模时考虑改为 约 10 个列族。

另请参阅 Robert Yokota 的 HBase Application Archetypes (其他 HBaser 所完成工作的最新信息),以便对 HBase 模型上的使用案例进行有用的分类。

34. Schema 创建

HBase schemas 可以通过 The Apache HBase Shell 或者 Java API Admin 来创建或者更新。

当进行列族的修改时,必须禁用表,比如:

  1. Configuration config = HBaseConfiguration.create();
  2. Admin admin = new Admin(conf);
  3. TableName table = TableName.valueOf("myTable");
  4. admin.disableTable(table);
  5. HColumnDescriptor cf1 = ...;
  6. admin.addColumn(table, cf1); // adding new ColumnFamily
  7. HColumnDescriptor cf2 = ...;
  8. admin.modifyColumn(table, cf2); // modifying existing ColumnFamily
  9. admin.enableTable(table);

阅读 client dependencies 获取关于配置客户端连接的更多信息。

0.92.x 可以支持在线 scheme 变更, 但是 0.90.x 版本需要禁用表。

34.1. Schema 更新

当表或者列族被修改时(比如 region 大小,block 大小),这些更改会在下一次 major 合并时生效,同时 StoreFiles 会被重写。

阅读 store 获取更多关于 StoreFiles 的信息。

35. 表 Schema 的经验法则

因为存在许多种不同的数据集,不同的访问模式和服务层级的要求。所以,以下经验法则只是概述。阅读完此列表后,请阅读这一章的剩余部分以获得更多详细信息。

  • 目标是把 region 的大小限制在 10 到 50 GB 之间。

  • 目标是限制 cell 的大小在 10 MB 之内,如果使用的是 mob 类型,限制在 50 MB 之内。否则,考虑把 cell 的数据存储在 HDFS 中,并在 HBase 中存储指向该数据的指针。

  • 典型的 scheme 每张表包含 1 到 3 个列族。HBase 表设计不应当和 RDBMS 表设计类似。

  • 对于拥有 1 或 2 个列族的表来说,50-100 个 region 是比较合适的。请记住, region 是列族的连续段。

  • 保持列族名称尽可能短。每个值都会存储列族的名称(忽略前缀编码)。它们不应该像典型 RDBMS 那样,是自文档化,描述性的名称。

  • 如果你正在存储基于时间的机器数据或者日志信息,并且 row key 是基于设备 ID 或者服务 ID + 时间,最终会出现这样一种情况,即更旧的数据 region 永远不会有额外写入。在这种情况下,最终会存在少量的活动 region 和大量不会再有新写入的 region。对于这种情况,可以接受更多的 region 数量,因为资源的消耗只取决于活动 region。

  • 如果只有一个列族会频繁写,那么只让这个列族占用内存。当分配资源的时候注意写入模式。