HBase简介の备忘

前言

现在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
    11
    Get 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 是删除一个单元