技术开发 频道

NoSQL:列存储数据库之HBase介绍

  五、关键算法/流程

  region定位

  系统如何找到某个row key (或者某个 row key range)所在的region

  bigtable 使用三层类似B+树的结构来保存region位置。

  第一层是保存zookeeper里面的文件,它持有root region的位置。

  第二层root region是.META.表的第一个region其中保存了.META.z表其它region的位置。通过root region,我们就可以访问.META.表的数据。

  .META.是第三层,它是一个特殊的表,保存了Hbase中所有数据表的region 位置信息。

  说明:

  1 root region永远不会被split,保证了最需要三次跳转,就能定位到任意region 。

  2.META.表每行保存一个region的位置信息,row key 采用表名+表的最后一样编码而成。

  3 为了加快访问,.META.表的全部region都保存在内存中。

  假设,.META.表的一行在内存中大约占用1KB。并且每个region限制为128MB。

  那么上面的三层结构可以保存的region数目为:

  (128MB/1KB) * (128MB/1KB) = = 2(34)个region

  4 client会将查询过的位置信息保存缓存起来,缓存不会主动失效,因此如果client上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的region(其中三次用来发现缓存失效,另外三次用来获取位置信息)。

  读写过程

  上文提到,Hbase使用MemStore和StoreFile存储对表的更新。

  数据在更新时首先写入Log(WAL log)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的MemStore,并且将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。于此同时,系统会在zookeeper中记录一个redo point,表示这个时刻之前的变更已经持久化了。(minor compact)

  当系统出现意外时,可能导致内存(MemStore)中的数据丢失,此时使用Log(WAL log)来恢复checkpoint之后的数据。

  前面提到过StoreFile是只读的,一旦创建后就不可以再修改。因此Hbase的更新其实是不断追加的操作。当一个Store中的StoreFile达到一定的阈值后,就会进行一次合并(major compact),将对同一个key的修改合并到一起,形成一个大的StoreFile,当StoreFile的大小达到一定阈值后,又会对StoreFile进行split,等分为两个StoreFile。

  由于对表的更新是不断追加的,处理读请求时,需要访问Store中全部的StoreFile和MemStore,将他们的按照row key进行合并,由于StoreFile和MemStore都是经过排序的,并且StoreFile带有内存中索引,合并的过程还是比较快。

  写请求处理过程

  1 client向region server提交写请求

  2 region server找到目标region

  3 region检查数据是否与schema一致

  4 如果客户端没有指定版本,则获取当前系统时间作为数据版本

  5 将更新写入WAL log

  6 将更新写入Memstore

  7 判断Memstore的是否需要flush为Store文件。

  region分配

  任何时刻,一个region只能分配给一个region server。master记录了当前有哪些可用的region server。以及当前哪些region分配给了哪些region server,哪些region还没有分配。当存在未分配的region,并且有一个region server上有可用空间时,master就给这个region server发送一个装载请求,把region分配给这个region server。region server得到请求后,就开始对此region提供服务。

  region server上线

  master使用zookeeper来跟踪region server状态。当某个region server启动时,会首先在zookeeper上的server目录下建立代表自己的文件,并获得该文件的独占锁。由于master订阅了server目录上的变更消息,当server目录下的文件出现新增或删除操作时,master可以得到来自zookeeper的实时通知。因此一旦region server上线,master能马上得到消息。

  region server下线

  当region server下线时,它和zookeeper的会话断开,zookeeper而自动释放代表这台server的文件上的独占锁。而master不断轮询server目录下文件的锁状态。如果master发现某个region server丢失了它自己的独占锁,(或者master连续几次和region server通信都无法成功),master就是尝试去获取代表这个region server的读写锁,一旦获取成功,就可以确定:

  1 region server和zookeeper之间的网络断开了。

  2 region server挂了。

  的其中一种情况发生了,无论哪种情况,region server都无法继续为它的region提供服务了,此时master会删除server目录下代表这台region server的文件,并将这台region server的region分配给其它还活着的同志。

  如果网络短暂出现问题导致region server丢失了它的锁,那么region server重新连接到zookeeper之后,只要代表它的文件还在,它就会不断尝试获取这个文件上的锁,一旦获取到了,就可以继续提供服务。

  master上线

  master启动进行以下步骤:

  1 从zookeeper上获取唯一一个代码master的锁,用来阻止其它master成为master。

  2 扫描zookeeper上的server目录,获得当前可用的region server列表。

  3 和2中的每个region server通信,获得当前已分配的region和region server的对应关系。

  4 扫描.META.region的集合,计算得到当前还未分配的region,将他们放入待分配region列表。

  master下线

  由于master只维护表和region的元数据,而不参与表数据IO的过程,master下线仅导致所有元数据的修改被冻结(无法创建删除表,无法修改表的schema,无法进行region的负载均衡,无法处理region上下线,无法进行region的合并,唯一例外的是region的split可以正常进行,因为只有region server参与),表的数据读写还可以正常进行。因此master下线短时间内对整个Hbase集群没有影响。从上线过程可以看到,master保存的信息全是可以冗余信息(都可以从系统其它地方收集到或者计算出来),因此,一般Hbase集群中总是有一个master在提供服务,还有一个以上的’master’在等待时机抢占它的位置。

  六、访问接口

  Hbase Shell

  Java clietn API

  Hbase non-java access

  languages talking to the JVM

  Jython interface to Hbase

  Groovy DSL for Hbase

  Scala interface to Hbase

  languages with a custom protocol

  REST gateway specification for Hbase

  充分利用HTTP协议:GET POST PUT DELET

  text/plain

  text/xml

  application/json

  application/x-protobuf

  Thrift gateway specification for Hbase

  java

  cpp

  rb

  py

  perl

  php

  Hbase Map Reduce

  Hive/Pig

  七、结语:

  全文对Hbase做了简单的介绍,有错误之处,敬请指正。未来将结合Hbase在淘宝数据平台的应用场景,在更多细节上进行深入。

  参考文档

  Bigtable: A Distributed Storage System for Structured Data

  HFile: A Block-Indexed File Format to Store Sorted Key-Value Pairs for a thorough introduction Hbase Architecture 101

  Hbase source code

2
相关文章