前言
现在hadoop生态发展的这么完善,实际这些书讲的也已经非常好了,还有一些大神的博客,废话不多说。
本书建了一个以hbase为数据库的twitter作为实例用来介绍hbase。
连接管理
创建表
create 'user','info'
其中表名是user
,info
是列族(column family)
HBase中的的列组成列族.
列族
检查表模式
HBase创建表时没提到任何列或者数据类型,除了列族HBase什么也不需要。
HBase:无模式数据库
HBase使用JRuby实现。
HBase连接管理
使用Java连接HBase使用HTablePool比直接使用HTable更为城建,使用连接池更好一些,连接从连接池里分配。
完成工作及时关闭表,连接资源会返回到连接池中。
数据操作
HBase表的行有唯一标识符,叫做行键。
HBase中的所有数据都是作为原始数据使用字节数组形式存储的,行键也还是如此。
HBase使用坐标来定位表中的数据。
- 行键
- 列族
- 列限定符
- 时间
工作机制
HBase写路径 :
HBase中,无论是增加新行还是修改已有的行,其内部流程都是相同的。
MemStore是内存里的写入缓冲区,HBase中数据在永久写入硬盘之前在这里累计,当MemStore填满后,其中的数据会刷鞋到硬盘,生成一个HFile,但是一个HFile不能存多个列族的数据,在集群的每个节点上,没个列族有一个MemStore。
针对分布式系统常见的硬件故障导致的数据丢失问题,,HBase是这么解决:
在写入之前先写入WAL。集群中每台服务器维护一个WAL来记录发生的变化,
WAL是底层文件系统上的一个文件,直到WAL新记录成功写入后,写动作才会被认为成功完成。大多数情况喜爱HBase使用HDFS作为底层文件系统。HBase写入时需要来自WAL和MemStore确认,这两个确认确保每次写入HBase 在尽可能快的同时保证持久性,当MemStore写满时刷
写到一个新HFile,写入时跳过WAL应该会提升写性能,但是不建议禁用WAL。
HBase读路径
读操作可以做到毫秒级,HBase读动作必须重新衔接持久化到硬盘上的HFile和内存中的MemStore中的数据
使用了LRU缓存技术,缓存叫做BlockCache,和MemStore在一个JVM堆里,BlockCache用来保存从HFile里读入内存的频繁访问的数据,避免硬盘读。每个列族都有自己的BlockCache。
BlockCache中的block是HBase从硬盘中完成一次读取的数据单位。Block是建立索引的最小数据单位。Block大小按照列族设定,默认值是64KB。
从HBase中读出一行首先会检查MemStore等待修改的队列,然后检查BlockCache看包含该行的Block是否最近被
访问过,最后才是访问硬盘上对应的HFile。
合并:
Delete命令不会立即删除内容,实际它只是个记录打上删除的标记。标志删除的内容不能在Get和Scan中返回结果,HFile是不能改变的,直到一次大合并,这些记录才会被出里,被删除记录的空间才会释放。
时间版本数据库
每次你在单元上执行操作,HBase都隐式存储一个新时间版本。单元的新建,修改和删除都会同样处理。它们都会留下新时间版本。时间版本是访问特定单元的最后一个坐标,没有设置这个坐标时候HBase就会使用当前时间。
如果一个单元的版本超过了最大数量,多处的记录会在下一次大合并时候扔掉。
数据组织
- 表:
- 行 : 在表里数据按照行存储,行由行健唯一标识。
- 列族 : 行里的数据按照列族分组,列族也影响到HBase数据的物理存放,因此列族必须事前定义且不轻易修改。
- 列限定符: 列族里的数据通过列限定符来定位。
- 单元 : 行健列族和列限定符一起确定一个单元。
- 时间版本: 单元值有时间版本,默认数量是3个
命令操作
get
1
2
3
4
5
6
7
8
9
10
11Get g = new Get(Bytes.toBytes("Name"));
g.addColumn(Bytes.toBytes("info")) //在Get中防止限制条件来减少返回的数据量。
Result r = userTable.get(g);
```
- #### put
与get相似
- #### delete
```Delete d = new Delete (Bytes.toBytes(""Name));
d.deleteColumns(Bytes.toBytes("info"));//指定删除行的一部分
table.delete(d);
deleteColumn
是删除单元的内容deleteColumn
是删除一个单元