【HBase 设计】
HBase 中的每一张表就是所谓的 BigTable。BigTable 会存储一系列的行记录,行记录有三个基本类型的定义:Row Key、Time Stamp、Column。
Row Key 是行在 BigTable 中的唯一标识。
Time Stamp 是每次数据操作对应关联的时间戳,可以看作 SVN 的版本。
Column 定义为< family>:< label>,通过这两部分可以指定唯一的数据的存储列,family 的定义和修改需要 对 HBase 进行类似于 DB 的 DDL 操作,而 label,不需要定义直接可以使用,这也为动态定制列提供了一种手段。family 另一个作用体现在物理存储优化读写操作上,同 family 的数据物理上保存的会比较临近,因此在业务设计的过程中可以利用这个特性。
【数据模型】
HBase 以表的形式存储数据。表由行和列组成,列划分为若干个列族(row family)。
1. Row Key
与 NoSQL 数据库一样,Row Key 是用来检索记录的主键。访问 HBase table 中的行,只有三种方式:
通过单个 Row Key 访问。
通过 Row Key 的 range 全表扫描。
Row Key 可以使任意字符串(最大长度是64KB,实际应用中长度一
般为 10~ 100bytes),在HBase 内部,Row Key 保存为字节数组。
行键设计RowKey
不要将RowKey设计成有序的形式或集中在固定某个范围内,因为这样容易阻塞并行性,将负载压都在一台机器上。
定位一个单元,需要行,列名和时间戳。
倒序时间戳有助于找到找到最近版本值。
行键是在列族范围内有效,不同列族中可以拥有同样的行键。
行键永远不能变
2. 列族
HBase表中的每个列都归属于某个列族。列族是表的 Schema 的一部分(而列不是),必须在使用表之前定义。列名都以列族作为前缀,例如courses:history、courses:math 都属于 courses 这个列族。
访问控制、磁盘和内存的使用统计都是在列族层面进行的。在实际应用中,列族上的控制权限能帮助我们管理不同类型的应用,例如,允许一些应用可以添加新的基本数据、一些应用可以读取基本数据并创建继承的列族、一些应用则只允许浏览数据(甚至可能因为隐私的原因不能浏览所有数据)。
列族数量:
列族数量越少越好,即使同时有两个列族,查询的时候总是访问其中一个列族,不会同时访问。
当一个表存在多个列族,当基数差距很大时,如A族有100万行,B族10亿行,A族可能会被分散到很多区域region,导致扫描A的效率降低。
多个列族在flush和compaction时,会造成很多I/O负担。
3. 时间戳
HBase 中通过 Row和 Columns 确定的一个存储单元称为 Cell。每个 Cell 都保存着同一份数据的多个版本。 版本通过时间戳来索引,时间戳的类型是 64 位整型。时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也 可以由客户显示赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个 Cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
为了避免数据存在过多版本造成的管理(包括存储和索引)负担,HBase 提供了两种数据版本回收方式。一是保存数据的最后 n 个版本,二是保存最近一段时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。
4. Cell
Cell 是由 {rowkey,column(=< family> + < label>),version} 唯一确定的单元。Cell 中的数据是没有类型的,全部是字节码形式存储。