HBase的long GC与 Zookeeper lease expired的权衡

问题和现象:

这是一个连锁反应:
1)RegionServer在遇到"Stop-The-World" GC时,会停止一切工作,这样与Zookeeper保持的心跳,就会停止。
2)Zookeeper在没有收到注册节点的心跳时,就会删除对应rs对应节点。
3)HMaster的ServerManager会发现这个RegionServer出现了问题,然后交由ServerShutdownHandler处理。
4)HMaster的SplitLogManager和RegionServer的SplitLogWorker组成Master-Slave结构,对HMaster
认定Dead的RegionServer的节点进行处理。
 HLOG => {按照Region分割成不同的edits文件},具体内容可以查看:http://www.cloudera.com/blog/2012/07/hbase-log-splitting/
5)HMaster的AssignmentManager把HLog处理完成的Region分配给一个RegionServer,RegionServer在接到Open Region的请求之后,利用分割出来的edits,实现HLog Replay,将其加载到MemStore,并且flush成一个文件。
6)RegionServer上的所有Region在其它RegionServer上提供服务。
7)RegionServer FullGC结束,然后正常与HMaster进行心跳tryRegionServerReport(),后来收到了一个YouAreDeadException,接到命令后,就开始关闭各种线程,然后退出。

以上只是对HBase一个现象的描述,如果正常的情况下,这样的处理是没有问题的。但是,我们在维护的Hbase集群却出现了一个让我们很郁闷的问题。
有应用报出Get、Scan某些数据不见了,查看Region下的RegionServer报出:
DFS Read: java.io.FileNotFoundException: File does not exist: /user/hbase/hbase/OTHER/9cc2c3d381e6891d1798d2cf4fe23859/dat/48bf8d0bbdae4b8b85f66da6f81b66aa
也就是该表格下的dat数据丢失,检查了NameNode查看该文件的情况,发现该数据被原RegionServer的DFSClient删除了,是因为原RegionServer在Long FullGC之后,做了一次minor Compaction,把两个StoreFile文件合并成了一个。而在这个之前,该Region已经被一个新的RegionServer所服务着,这样这个新的RegionServer会认为没有进行Compaction,还是按照接手该Region时的情况进行读取数据,于是,悲剧就产生了。

具体描述:
出问题Region:RegionA
FullGC的RegionServer: RegionServer1
接管RegionA的RegionServer: RegionServer2
RegionServer1 --------------Full---GC------------------->compaction--(delete 原 dat/48bf***)->You Are Dead--->Exit
RegionServer2 -------------------------> 接管RegionA---->请求出错

整体上虽然数据没有丢失,但是仍然给线上系统带来一定的影响。分析了整个过程之后,预防这类问题出现应该
从如下几点入手:
1、相关参数
<property>
  <name>hbase.regionserver.lease.period</name>
  <value>240000</value>
  <description>HRegion server lease period in milliseconds. Default is 60 seconds. Clients must report in within this period else they are considered dead.</description>
</property>
hbase.regionserver.lease.period的设置是Tradeoff,因为在HBase Client操作过程中,如果RegionServer的响应速度过慢或者出现了Long FullGC,超过了设置值,则抛出lease expired。
ps:hbase.regionserver.lease.period的设置要和hbase.rpc.timeout保持一致,最好hbase.rpc.timeout的值略大于hbase.regionserver.lease.period

<property>
  <name>zookeeper.session.timeout</name>
  <value>90000</value>
  <description>Default 3 minutes.ZooKeeper session timeout. HBase passes this to the zk quorum as suggested maximum time for a session (This setting becomes zookeeper's 'maxSessionTimeout'). See http://hadoop.apache.org/zookeeper/docs/current/zookeeperProgrammers.html#ch_zkSessions "The client sends a requested timeout, the server responds with the timeout that it can give the client. " In milliseconds. </description>
</property>
zookeeper.session.timeout指定zk Client与zk Server Quorum之间的会话的最长时间,RegionServerTracker监听rs的znode的变化,超过session time out的值,就认定该RegionServer出错了,然后通过ServerManager的expireServer将其加入Dead RegionServer Lists中。这样等RegionServer发送心跳给HMaster时,发现该RegionServer位于Dead RegionServer Lists中,会抛出YouAreDeadException。然后,RegionServer会开始执行shutdown系统操作。
注意:这里设置的zookeeper.session.timeout与zookeeper设置的ticktime共同影响session的生存周期,一般而言,sessionTimeOut= Min(应用设置的zookeeper.session.timeout,ticktime*20)


2、tryRegionServerReport()的频率设置高一些。默认间隔时间为:
this.msgInterval = conf.getInt("hbase.regionserver.msginterval", 3 * 1000);设置成1*1000ms,可以更快地同步HMaster上RegionServer状态,尽量避免延迟阶段造成的数据不一致。注意,如果是RegionServer的个数超过200,该值不要太小,避免HMaster的压力过大。
3、在compaction删除文件时,tryRegionServerReport一下,保证没有出现已经被认定“Dead”但仍然工作的情况。在任何删除操作之前,首先report一下HMaster,检查是否已经出现YouAreDeadException,然后恢复之前的文件。

转自:http://blog.sina.com.cn/s/blog_4a1f59bf01017vdk.html

你可能感兴趣的:(HBase的long GC与 Zookeeper lease expired的权衡)