文章目录
Hbase内部探险
前言
以下内容我将从Hbase的数据存储、region等这些方面入手,进行一个比较全面的总结
在进入Hbase之前,我们先拓展几个api
mutation方法
根据前面提到的方法,如果我们想在一行种添加一列的同时删除一列。可以新建一个Put来添加,新建一个Delete来删除。不过这两行代码分两步执行,并不是一个原子操作。那么我要保证这两个操作同时成功或失败,该怎么做呢?
Table接口提供了一个mutateRow方法来把两个操作作为一个原子操作。为什么不叫方法Mutation呢?顾名思义,两个操作必须是同一rowkey才可以。而我们发现Mutation这个类是Put、Delete、Append、Increment类的父 类。
checkAndMutate方法
put有checkAndPut,delete有checkAndDelete,自然的mutate肯定 也有checkAndMutate方法。只是checkAndMutate不会针对每个操作都去 check一次,所有的操作只会在一开始check一次给出的value跟数据库 中现有的value是否一致(即两个value的关系是否一致,可以是非等关系)
批量操作
当需要一次性操作很多条数据的时候,很多人的第一反应应该是循 环调用put、get、delete方法。不过Hbase给我们提供了一个批量操作的方法batch。因为Put、Get、Delete都实现了Row接口。
当使用batch()功能执行批量put操作时,Put实例不会被写入到客户端缓冲区中,batch()请求是同步的,会把操作直接发往服务器,注意不要将对一行的操作放到一个batch中,因为batch中的操作是无顺序的。
早期的batch方法中可以不传results接收返回结果的集合。不过这种方法在执行的过程中,如果发生异常,则没有返回结果。我们提倡的是batch(actions, results),只传actions的已经被废弃了。
显示调用行锁(Row Lock)的方法已经被废弃,所以我们不提这个。
我们也可以给put、get、delete传入一个list的操作集合来实现批量操作,这个也是基于batch实现的。
BufferedMutator方法
说到BufferedMutator必须得先提一下客户端写缓冲区,是把 多个Put操作攒到一起通过单个RPC请求发送给客户端,目的是节省网络 握手带来的IO消耗。调用 HTable.setAutoFlush(false)来开启。不过0.99版本后,这个特性已经被废弃了。新的模式鼓励大家创建一个新的Table实例,用完即释放(轻量级)。
但是客户端的写缓冲区还是存在,不过转向了BufferedMutator。这个类更多地是被HBase内部调用,大部分情况下我们不需要 直接调用到BufferedMutator。交给客户端自己判断就可以了。
内部探险
Hbase是怎么存储数据的
预写日志
数据到达Region的时候是先写入WAL,然后再被加载到 Memstore的。就算Region的机器宕掉了,由于WAL的数据是存储在HDFS 上的,所以数据并不会丢失。
-
WAL默认打开,可以调用Mutation的setDurability(Durability.SKIP_WAL)来关闭WAL,put、get、delete也有这个方法,但最好不要这样做。
-
延迟、同步写入WAL
除了关闭WAL来提高性能,还可以异步提交。也是使用setDurability这个方法。默认异步提交的时间间隔是1s。如果你的系统对一致性要求不大,且系统瓶颈出现在WAL上时可以使用。
-
WAL滚动
WAL的检查间隔由hbase.regionserver.logroll.period定义,默认 值为1小时。检查的内容是把当前WAL中的操作跟实际持久化到HDFS上的 操作比较,看哪些操作已经被持久化了,被持久化的操作就会被移动到.oldlogs文件夹内(这个文件夹也是在HDFS上的)。WAL文件的最大数量通过hbase.regionserver.maxlogs(默认是32)参数来定义
其他触发滚动条件:
1)当WAL所在的块快要满的时候。
2)当WAL所占的空间大于某个阙值的时候(默认是0.95)
-
WAL文件创建出来存在哪
WAL文件被创建出来后会放在/hbase/.log下(这里说的路径都是基 于HDFS),一旦WAL文件被判定为要归档,则会被移动 到/hbase/.oldlogs文件夹。当.oldlogs没有引用时会删除日志文件.
目前有两种进程会引用WAL,一种是TTL超时(默认10分钟),一种是备份(指不同集群之间的备份)
Memstore
数据在进入HFile之前已经被存储到HDFS一次了,为什么还需要放入Memstore?这是因为HDFS上的文件只能创建、追加、删除,不能修改。对一个数据库来说,按顺序存放数据是非常重要的,这是性能的保证。所以我们需要在内存中进行整理再写入磁盘。所以Memstor是作用不是提高性能,