我们知道 HBase 是基于列族的数据库,数据存在HDFS里。数据横向切分成Region区域,类似sharding。集群中各个slave 叫 区域服务器 Region Server。
所有列家族的元数据信息都必须和表的定义存在一块。
在HBase 内部, 维护两个目录,分别以表的形式存在HDFS里,它们是 -ROOT- 和 .META. . 它们维护当前最新的区域列表,各个区域的状态以及在集群中位置。
-ROOT-目录存放着所有.META.的表区域。而.META.持有用户所有的区域Region信息。
.META.表中的主键由区域名称,表名,起始行,区域创建时间戳,以及所有这些信息的MD5哈希组成。 行键是排序的,便于查找。
当区域状态改变的时候,比如区域数据太多需要切分新区域,或者 RegionServer被Disable/Enable/Deleted/Redeploy等,目录表会被及时的更新。
这样一来,所有区域的状态始终都是最新的。
新连入的客户端首先需要连接到ZooKeeper集群,以得到 -ROOT-的地址并在目录.META.中二分查找到包含当前请求的数据行的区域Region Server及其位置。
之后,客户端就只需要和区域服务器通信了。
每次行的操作会花费三个来回,客户需要缓存遍历-ROOT- 和 .META得到的各个区域第一行和最后一行的信息,这样它们可以自己计算Region的地址,而不需要每次都查.META.目录了。
缓冲对于客户端来说,会一直有效,直到发生故障。这时候,客户会再次查询.META.目录以得到新的位置信息。
下面讲一讲HBase的读写操作。
当写请求到达Region Server的时候,写操作的信息会先被追加到操作日志commit log中去,然后再更新到同存中的memstore数据库。当memstore内存放不下的时候,会被同步到HDFS上面。
操作日志本身存在HDFS上面,所以会保持高可用,甚至在Region Server崩溃的时候也可以访问。
当Region Master注意到某个Region Server不可达时(通常是通过检测ZooKeeper中这个server对应的znode过期失活与否),主服务器会把死去的区域服务器的HBase未完成的操作日志提取分离出来,重新指
定一台区域服务器来重做未完成那一段操作日志,然后才能上线。
当读请求到达Region Server的时候,数据的 memstore缓冲副本会优先被读取,如果请求的行都在内存中,直接返回。否则按照从新到旧的顺序读取 flush文件中的内容。
同时后台会有一个进程定期清理flush 文件,即将多个flush文件重写为一个文件,这样读的文件越少性能越好。在清理的过程中,version个数超过上限将老数据将被删除。过期的单无Cell也会被删除。
后台还一个独立的进程运行在Region Server上面,它负责监控flush文件大小,并在其大小超过配置上限时进行切分,增加新的区域。
阅读(3022) | 评论(0) | 转发(0) |