对于 Hbase 来讲,表 schema 设计的好坏,是一个决定 Hbase 读写能力的重要因素。
表的设计
1. 准备
首先要回答一下几个问题:
- 行键结构应该是什么以及它应该包含什么?
- 表中应该有多少列族?
- 哪些数据属于哪个列族?
- 每个列族中有多少列?
- 列名应该是什么? 虽然列名不需要在表创建时定义,您需要在编写或读取数据时了解它们。
- 哪些信息应该进入 Cell?
- 每个单元应存储多少个版本?
2. 注意点
在HBase表中定义的最重要的是行键结构。 为了有效地定义,有必要预先定义访问模式(读取和写入)。 要定义模式,必须考虑有关HBase表的几个属性:
- 索引仅基于 Key 完成。
- 基于行键对表进行排序。表中的每个区域对对行键空间(由开始和结束行键标识)的一部分责任。该区域包含从开始键到结束键的行的排序列表。
- HBase表中的所有内容都存储为 byte[]。 没有类型。
- 仅在行级保证原子性。没有原子性保证跨行,这意味着没有多行事务。
- 必须在创建表时预先定义列族。
- 列限定符是动态的,也可以在写入时定义。 它们被当作 byte[] 存储起来, 所以你甚至也可以将数据放入其中。
3. 总结
- 行键是HBase表设计中最重要的一个方面,它决定了应用程序与HBase表的交互方式。它们还会影响您从HBase中提取的性能。
- HBase表是灵活的,您可以以byte []的形式存储任何内容。
- 将具有类似访问模式的所有内容存储在同一列族中。
- 仅对 key 进行索引。使用它对您有利。
- 高的表可能会让您更快,更简单的操作,但您可以权衡原子性。宽表,每行有很多列,允许行级的原子性。
- 考虑如何在单个API调用中完成访问模式,而不是多个API调用。HBase没有跨行事务,您希望避免在客户端代码中构建该逻辑。
- 散列允许固定长度的键和更好的分布,但是消除了使用字符串作为键所暗示的顺序。
- 列限定符可用于存储数据,就像单元格本身一样。
- 列限定符的长度会影响存储空间,因为您可以将数据放入其中。访问数据时,长度也会影响磁盘和网络I / O成本。要简明扼要。
- 列系列名称的长度会影响通过线路发送到客户端的数据大小(在KeyValue对象中)。要简明扼要。
4. 官方文档总结
- 努力保证每个 region 大小在 10~50 GB。
- 努力保证每个 cell 大小不超过 10 MB, 如果你使用了 MOB, 那么不能超过 50 MB。 否则,就要考虑把数据存储在 HDFS 中,而在 HBase 中存储数据的指针。
- 典型的模式每个表有1到3个列族。 HBase表不应模仿 RDBMS 表设计。
- 对于具有1或2列族的表,大约50-100个区域是一个很好的数字。请记住,区域是列族的连续段。
- 保持列族名称尽可能短。为每个值存储列族名称(忽略前缀编码)。它们不应该像典型的RDBMS那样自我记录和描述。
- 如果要存储基于时间的机器数据或日志记录信息,并且行键基于设备ID或服务ID加上时间,则最终可能会出现一种模式,即较旧的数据区域永远不会有超过特定年龄的额外写入。 在这种情况下,最终会出现少量活动区域和大量没有新写入的旧区域。 对于这些情况,您可以容忍更多区域,因为您的资源消耗仅由活动区域驱动。
- 如果只有一个列族忙于写入,则只有该列族会使用内存。分配资源时,要注意写模式。