HBASE中,region server挂了之后,如何把这台server上的region转移到另外的region server上呢

无论哪种情况,region server(实指RegionServer进程挂掉,下文同)都无法继续为它的region提供服务了,此时master会删除server目录下代表这台region server的文件,并将这台region server的region分配给其它还活着的同志。
我想问,region server既然挂了,那每个region的详细信息也就丢了,又没多个备份,怎么能重新分配给别的region server呢?
HBase基于Hadoop,Region Server中的数据保存在HDFS上,默认情况下HDFS保存3份,会尽量放在3台机器上。所以当一台机器挂掉的情况下,HDFS层面会检查到这部分数据的复制份数不够,再复制一份出来到其它机器上去的。
你应该先看hbase是如何找到regionserver的。你可以看到hbase找到regionserver是向zookeeper请求-ROOT-表,然后找到-META-表,然后在-META-表里找到regionserver信息。如果regionserver挂了,它把这个元数据,转移到其它活着的regionserver上,然后把wal日志分到其它regionserver上去重新加载。记住这里是元数据,数据本身是在hdfs上的,所以数据本身不会挂。元数据可以理解成对文件的索引,是放在内存中的。
这个分配region -> regionserver的过程叫assign
刚开始也迷惑这个问题,后来想了下,可能是这样的,HBase的HRegion文件和HLog文件都存储在HDFS中的(一般有多份),RegionServer挂了,并不是数据文件就丢失了。RegionServer挂了后,HRegion和HLog都还在,Master重新分配Region,并读取Hlog进行恢复。

HBase的运行时有三个集群

  • Zookeeper集群,负责HBase(当然还有HDFS)集群的协调服务和配置服务。其中的节点是ZooKeeper服务器
  • HDFS集群,是一个分布式文件系统,有单一的名字空间。其中的节点有NameNode和DataNode,前者负责存储文件系统的元数据(包括目录名,文件名,等),后则负责存储实际文件的块。
  • HBase集群,其中的节点有Master和Region Server

    HDFS存储在HBase中,关于数据的元数据也是存储在HBase的表中的,而元数据和数据都通过HDFS文件系统存储。在HDFS中,HBase的文件如下所示:

    • /hbase,hbase的根目录
    • /hbase/weblogs,一个名为weblogs的表的目录
    • /hbase/weblogs/.tableinfo.0000000001,表的元数据信息
    • /hbase/weblogs/e048f132e3c5ac596e4fbcc486c0ef6e,表的一个Region目录
    • /hbase/weblogs/e048f132e3c5ac596e4fbcc486c0ef6e/.regioninfo,Region的元数据信息
    • /hbase/weblogs/e048f132e3c5ac596e4fbcc486c0ef6e/pageviews,Region的一个ColumnFamily目录
    • /hbase/weblogs/e048f132e3c5ac596e4fbcc486c0ef6e/pageviews/837a8a7bbf044ed3849b77881a3089a7,Region的HFile

Zookeeper存储不但在HDFS中存储信息,HBase还在Zookeeper中存储信息,其中的znode如下所示:

  • /hbase/root-region-server ,Root region的位置
  • /hbase/table/-ROOT-,根元数据信息
  • /hbase/table/.META.,元数据信息
  • /hbase/master,当选的Mater
  • /hbase/backup-masters,备选的Master
  • /hbase/rs ,Region Server的信息
  • /hbase/unassigned,未分配的Region也就是说,
    由Zookeeper保持了集群的状态信息

Region Server
在来看Region Server,如图所示:
输入图片说明
Region Server存储了三部分信息:

  • HFile,数据文件,存储在HDFS上
  • Write-Ahead Log(WAL日志就是Hlog,所有的region共享一个hlog,hlog是滚动日志,有很多小文件,会被删除),重做日志,类似于Oracle的Redo Log和MySQL的Binlog,也存在HDFS上。
  • Memstore,内存中的数据缓存(没有flush的部分可能会丢失),类似Oracle的Buffer Cache。

Region Server fail时重新分配Region
其中HFile和WAL都存储在HDFS上,当Region Server fail的时候,数据是不会丢失的,丢失的只是Memstore中尚没有写入HFile的部分
Region Server宕机后,该服务器所负责的Region就会变成不可用,HMaster就会根据集群的负载状况,将这些Region分配给其他Region Server。
接手的Region Server从Zookeeper上,以及ROOT表和META表上可以找到充分的元数据信息,数据又是存在HDFS上,由于HDFS会保持多个副本,数据也不会丢,那么Region Server只需要根据这些信息组织起内存结构,并获取WAL(在hdfs上不会丢失)文件进行重放,就可以最大程度的恢复到原来那台Region Server宕机前的状态。
当然由于RegionServer大多和DataNode在一台服务器上,在写入时,也会调用本地的DFSClient写入,数据块会在本机有一个副本,在另外的机架上有一个副本,还有另外一个随机分配的副本,这样在读写时可以保证Data Locality。如果Region Server接手了一个Region,那么大多数数据块不在本地的Name Node上,读写性能会有下降,但会在后续的Compact过程中逐渐将文件写入本地的Data Node,从而恢复DataLocality
当然由于HDFS少了一个Data Node,改Data Node上的数据块都少了一个副本,HDFS也会在其他的Data Node上重新建立这些副本,以保证可靠性。
http://www.kejik.com/article/270124.html
HBase之WAL机制详细讲解
http://blog.sina.com.cn/s/blog_15e0e0a700102w2v4.html
HLog类

实现了WAL的类叫做HLog,当hregion被实例化时,HLog实例会被当做一个参数传到HRegion的构造器中,当一个Region接收到一个更新操作时,它可以直接把数据保存到一个共享的WAL实例中去
输入图片说明
HLogKey类

1、当前的WAL使用的是hadoop的sequencefile格式,其key是HLogKey实例。HLogKey中记录了写入数据的归属信息,,除了table和region名字外,同时还包括sequence number和timestamp,timestamp是“写入时间“,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number

2、HLog sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue

WALEdit类

1、客户端发送的每个修改都会封装成WALEdit类,一个WALEdit类包含了多个更新操作,可以说一个WALEdit就是一个原子操作,包含若干个操作的集合

LogSyncer类

1、Table在创建的时候,有一个参数可以设置,是否每次写Log日志都需要往集群的其他机器同步一次,默认是每次都同步,同步的开销是比较大的,但不及时同步又可能因为机器宕而丢日志。同步的操作现在是通过pipeline的方式来实现的,pipeline是指datanode接收数据后,再传给另外一台datanode,是一种串行的方式,n-Way writes是指多datanode同时接收数据,最慢的一台结束就是整个结束,差别在于一个延迟大,一个开发高,hdfs现在正在开发中,以便可以选择是按pipeline还是n-way writes来实现写操作

2、Table如果设置每次不同步,则写操作会被RegionServer缓存,并启动一个LogSyncer线程来定时同步日志,定时时间默认是一秒也可由hbase.regionserver.optionallogflushinterval设置

LogRoller类

1、日志写入的大小是有限制的,LogRoller类会作为一个后台线程运行,在特定的时间间隔内滚动日志,通过hbase.regionserver.logroll.period属性控制,默认1小时