小Q大数据-Hbase数据模型的“旋风之旅”
应用把数据存放在带标签的表中,表由行和列组成。表格的“单元格”(cell)由行和列的坐标交叉决定,是有版本的。默认情况下,版本号是自动分配的,为HBase插入单元格时的时间戳。单元格的内容是未解释的字节数组。例如,下图所示为用于存储照片的HBase表。
表中行的键也是字节数组。所以理论上,任何东西都可以通过表示成字符串或将二进制形式转化为长整型或直接对数据结构进行序列化,来作为键值,表中的行根据行的键值(也就是表的主键)进行排序。排序根据子节序进行。所有对表的访问都要通过表的主键。(HBase不支持表中的其他列建立索引,也称为辅助索引,不过,有几种策略可用于支持辅助索引提供的查询类型,每种策略在存储空间、处理负载和查询执行时间之间存在不同的利弊权衡)。
行中的列被分为“列族”(column family)。同一个列族的所有成员具有相同的前缀。因此,像列info:format和info:geo都是列族info的成员,而contents:image则属于contents族。列族的前缀必须有“可打印的”字符组成。而修饰性的结尾字符,即列族修饰符,可以为任意子节。列族和修饰符之间始终于(:)分割。
一个表的列族必须作为表模式定义的一部分预先给出,但是新的列族成员可以随后按需要加入。例如:只要目标表中已经有了列族info,那么客户端就可在更新时提供新的列info:camera,并存储它的值。
物理上,所有的列族成员都一起存放在文件系统中。所以,我们把HBase描述为一个面向列的存储器,但实际上更准确的说法是:它是一个面向列族的存储器。由于调优和存储都是在列族这个层次上进行的,所以最好使所有列族成员都有相同的访问模式(access pattern)和大小特征。对于存储照片的表,由于图像数据比较大(兆字节)。因而跟较小的元数据(千字节)分别存储在不同的列族中。
简而言之,HBase表和RDBMS中的表类似,只不过它的单元格有版本,行是排序的,而只要列族预先存在,客户端随时可以把列添加到列族中去。
1、区域
HBase自动把表水平划分成区域(region)。每个区域由表中行的子集构成。每个区域由它所属于的表、它所包含的第一行及其最后一行(不包括这行)来表示。一开始,一个表只有一个区域。但是随着区域开始变大,等到它超出设定的大小阈值,便会在某行的边界上把表分成两个大小基本相同的新分区。在第一次划分之前,所有加载的数据都放在原始区域所在的那台服务器上。随着表变大,区域的个数也会增加。区域是在HBase集群上分布数据的最小单位。用这种方式,一个因为太大而无法放在单台服务器上的表会被放到服务器集群上,其中每个节点都负责管理表所有区域的一个子集。表的加载也是使用这种方法把数据分布到各个节点。在线的所有区域按次序排列就构成了表的所有内容。
2、加锁
无论对行进行访问的事务牵涉多少列,对行的更新都是“原子的”(atomic)。这使得“加锁模型”(locking model)能够保持简单。