HBase中的一张表
- schema-less 每一列没有类型。只需要告知column family,不关心每一列的名字和类型
- 每一个cell能存储多个版本,默认只保留最近的3个版本,每次创建,修改,删除都会变更版本号
- rowkey 每一行都不一样,真个table的所有row都是唯一的
- 在HBase中的原生数据都是以byte的形式存储的
- cell :通过[ rowkey, column family,column qualifier]定位,例如:
Put p =new Put(Bytes.toByte("TheRealMT"));
p.add(Bytes.toByte("info"))
p.add(Bytes.toByte("name"))
p.add(Bytes.toByte("Mark Twain"))
复制代码
在这里 rowdy是 TheRealMT,column family是 info,column qualifier是name,cell中真正存值是 Mark Twain
- table创建好之后,每次修改column family必须先下线当前的额表
- column qualifier能被当做数据,HBase本身相当于是一个多维的map
- hbase总没有多对多和一对多这种映射,更多的是非结构化数据
- hbase单行操作是原子的
schema设计一般需要考虑以下几个问题:
- table该有几个column family?
- 数据应该去哪个column family?
- 每个column family该有几个column?
- 每个column该叫什么名字?
- 什么样的信息该放入cells?
- 每个cells里面改存储几个版本?
- rowkey的结构是什么,它本身该包含什么信息?
如何理解HBase中的key-value结构?
宽表和高表的概念
wide table: 包含多个列的table; tall table: 包含多行的table;
tall table 相对来说性能会好一点
rowkey设计需要考虑的一些因素
在内存中,数据存在的时候就已经是排好序的,当存储到HFile的时候也是排好序的,HBase中获取数据的唯一方式就是rowkey
- 基于IO的考虑,比如时间作为rowkey,如果要获取前几秒的数据,那么扫描一小块数据就能得到想要的结果,但是要写入数据的时候,很有可能一直是写在了table的最后面,负载不均匀
- 写优化。比如时间来说,读是很快,但是以写来消耗的。要优化写,即均匀分布,首先可以通过 hash,这样每次查找的时候,必须知道rowkey生成的元素,同时确保生成的rowkey能通过确定的方式计算得到;其次可以通过添加随机元素(salt)的方式生成rowkey,比如根据机器的多少,生成随机数,并与之取模再得出rowkey的前缀,然后拼上时间
- 读优化。比如时间放在前面的情况
- 拼接顺序和决定放什么元素在里头都很重要
代码语言:javascript复制比如 名字 时间戳 的组合
Olivia1
Olivia2
Olivia5
Olivia7
Olivia9
TheFakeMT2
TheFakeMT3
TheFakeMT4
TheFakeMT5
TheFakeMT6
TheRealMT1
TheRealMT2
TheRealMT5
TheRealMT8
复制代码
代码语言:javascript复制时间戳 名字 的组合
1Olivia
1TheRealMT
2Olivia
2TheFakeMT
2TheRealMT
3TheFakeMT
4TheFakeMT
5Olivia
5TheFakeMT
5TheRealMT
6TheFakeMT
7Olivia
8TheRealMT
9Olivia
复制代码
如果要知道一段时间之内某个名字的行,(时间戳 名字)的方式需要遍历整个表,而(名字 时间戳)则不需要
使用MD5加密rowkey的好处:长度是一致的,不再需要单独的分隔符。但是时无法获取原来的rowkey元素 把信息放在rowkey的好处:可以以常量的时间获取数据
java访问的一般方式
java api连接HBase,一般使用HTablePool,然后根据pool再拿到具体的表。单个的创建表的方式花销太大
附录
本文来自<HBase In Action>一书。推荐。可以基本了解HBase的概念