hbase session超时时间是多少

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hbase session超时时间是多少相关的知识,希望对你有一定的参考价值。

参考技术A 最近处理了一个客户端scan超时问题,记录在此,希望能够帮助到遇到同样问题的同学。

问题的错误堆栈如下面所示:

java.lang.RuntimeException:
org.apache.hadoop.hbase.client.ScannerTimeoutException: 76745ms passed
since the last invocation, timeout is currently set to 60000

at
org.apache.hadoop.hbase.client.AbstractClientScanner$1.hasNext(AbstractClientScanner.java:97)
~[hbase-client-1.1.2.jar:1.1.2]

at
com.mogujie.fulldump.task.HBaseUtil.scanTable(HBaseUtil.java:109)
~[fulldump-indexbuildingcomponent-1.0-SNAPSHOT.jar:na]

at
com.mogujie.fulldump.task.HbaseScanner$Task.run(HbaseScanner.java:114)
[fulldump-indexbuildingcomponent-1.0-SNAPSHOT.jar:na]

at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

业务方报告超时错误后,我们按惯常的思路对服务端进行了排查,包括对更改表配置,对表数据进行major
compact操作等等,但是,经过对集群及表结构的一阵调整之后,超时错误仍然存在。解决问题的最好出发点就是分析源码,看看问题出在哪里,于是决定阅
读源码,找到错误的根节点。

从上面的异常可以看出错误出现在org.apache.hadoop.hbase.client.ScannerTimeoutException中,进入源码看看这个错误在哪里被打印。

在客户端的ClientScanner类的loadcache方法,我们找到了错误输出的地方,代码片段如下所示:

在上面的代码中,lastNext是前一次调用loadcache时的
系统时间,scannerTimeout是用户设置的超时时间。每次进入loadcache函数的时候,都会将当前的时间与前两者之和做对比,如果当前时
间大于了两者之和,则会报出Timeout错误。好啦,错误的原因已经知道了,解决方法就是增大scannerTimeout。scannerTimeout是由hbase.client.scanner.timeout.period控制的,默认值是60s,我们将上述配置增大到120s之后,问题解决,不再发生超时错误。

这个问题深入思考一下,为什么会有这么一个错误。loadcache的
作用是将服务端的数据缓存到本地,客户端中维护一个LinkedList<Result>类型的变量cache用于缓存从服务端region
中拉下的数据。客户端的scanner迭代时调用的next实际上是从这个cache中取的数据,直到cache中的数据被消费空,此时,会重新调用
loadcache开始新一轮从服务端拉取数据。
参考技术B 试试:get'scores','Jim',COLUMN=>'grade',value=>'4'get'scores','Jim',COLUMN=>'grade',value=>'10'或者:get'scores','Jim',COLUMN=>'grade',value=>4get'scores','Jim',COLUMN=>'grade',value=>10我没有用过HBase,最近刚在看,在Shell中,常量是不需要引号的,二进制需要双引号,其他值需要单引号。 参考技术C 不要用filter很慢的,直接scan,设一下start和end就行了。它支持通配的。

HBase客户端访问超时原因及参数优化

默认的HBase客户端的参数配置是没有做过优化的,所以对于低延时响应的HBase集群,需要对客户端的参数进行优化。

1.      hbase.rpc.timeout

以毫秒计算的所有HBase RPC超时,默认为60s。

该参数表示一次RPC请求的超时时间。如果某次RPC时间超过该值,客户端就会主动关闭socket。

 

如果经常出现java.io.IOException: Connection reset by peer异常问题,估计HBase集群出现了大量高并发读写业务或者服务器端发生了比较严重的Full GC等问题,导致某些请求无法得到及时处理,超过了设置的时间间隔。

 

根据实际情况,可以修改为5000,即5s

 

2.      hbase.client.retries.number

客户端重试最大次数。所有操作所使用的最大次数,例如,从根 RegionServer 获取根区域、获取单元格的值和启动行更新。

默认为35,可以设置为3

 

3.     hbase.client.pause 

通用客户端暂停时间值(重试的休眠时间)。重试get失败或区域查找等操作前,经常使用的等待时间段。

HBase1.1版本开始此值默认为100ms,比较合理,如果你的版本不是,建议修改此值为100ms

 

4.      zookeeper.recovery.retry

zookeeper的重试次数,可调整为3次,zookeeper不轻易挂,且如果HBase集群出问题了,每次重试均会对zookeeper进行重试操作。

 

zookeeper的重试总次数是:

hbase.client.retries.number * zookeeper.recovery.retry。

 

并且每次重试的休眠时间均会呈2的指数级增长,每次访问HBase均会重试,在一次HBase操作中如果涉及多次zookeeper访问,则如果zookeeper不可用,则会出现很多次的zookeeper重试,非常浪费时间。

 

 

5.      zookeeper.recovery.retry.intervalmill

zookeeper重试的休眠时间,默认为1s,可以减少,比如:200ms。

 

 

6.      hbase.client.operation.timeout

该参数表示HBase客户端发起一次数据操作直至得到响应之间总的超时时间,数据操作类型包括get、append、increment、delete、put等。很显然,hbase.rpc.timeout表示一次RPC的超时时间,而hbase.client.operation.timeout则表示一次操作的超时时间,有可能包含多个RPC请求。

 

举个例子说明,比如一次Put请求,客户端首先会将请求封装为一个caller对象,该对象发送RPC请求到服务器,假如此时因为服务器端正好发生了严重的Full GC,导致这次RPC时间超时引起SocketTimeoutException,对应的就是hbase.rpc.timeout。那假如caller对象发送RPC请求之后刚好发生网络抖动,进而抛出网络异常,HBase客户端就会进行重试,重试多次之后如果总操作时间超时引起SocketTimeoutException,对应的就是hbase.client.operation.timeout。

 

默认为1200000,可以设置为30000,即30s。

 

7.      hbase.regionserver.lease.period

hbase.client.operation.timeout参数规定的超时基本涉及到了HBase所有的数据操作,唯独没有scan操作。然而scan操作却是最有可能发生超时的,也是用户最为关心的。HBase特别考虑到了这点,并提供了一个单独的超时参数进行设置:hbase.client.scanner.timeout.period。

 

此参数指scan查询时每次与RegionServer交互的超时时间。

默认为60s,可不调整。

HBase 1.1版本开始,此参数更名为hbase.client.scanner.timeout.period。

 

为了对这个参数更好地理解,我们演示一个scan的例子:

package com.zy.hbase;

 

import java.io.IOException;

 

importorg.apache.hadoop.conf.Configuration;

import org.apache.hadoop.hbase.HBaseConfiguration;

import org.apache.hadoop.hbase.KeyValue;

import org.apache.hadoop.hbase.TableName;

importorg.apache.hadoop.hbase.client.Connection;

importorg.apache.hadoop.hbase.client.ConnectionFactory;

importorg.apache.hadoop.hbase.client.HTable;

import org.apache.hadoop.hbase.client.Result;

importorg.apache.hadoop.hbase.client.ResultScanner;

import org.apache.hadoop.hbase.client.Scan;

import org.apache.hadoop.hbase.util.Bytes;

 

public class KylinScan

 

         /**

          * @param args

          * @throws IOException

          */

         publicstatic void main(String[] args) throws IOException

                   scan("kylin");

        

 

         @SuppressWarnings("deprecation")

         publicstatic void scan(String tbl) throws IOException

                   Configurationconf = HBaseConfiguration.create();

                   conf.set("HADOOP_HOME","D:\\\\iangshouzhuang\\\\hadoop-2.6.0");

                   conf.set("hbase.zookeeper.quorum","10.20.18.24,10.20.18.25,10.20.18.28");

                   conf.set("hbase.zookeeper.property.clientPort","2181");

                   conf.set("zookeeper.znode.parent","/hbase114");

                  

                   conf.setInt("hbase.rpc.timeout",20000);

                   conf.setInt("hbase.client.operation.timeout",30000);

                   conf.setInt("hbase.client.scanner.timeout.period",20000);

                  

                   StringtableName = tbl;

 

                   TableNametableNameObj = TableName.valueOf(tableName);

                  

                   Connectionconnection = ConnectionFactory.createConnection(conf);

                   HTabletable = (HTable) connection.getTable(tableNameObj);

                  

                   Scanscan = new Scan();

                   scan.setMaxResultSize(10000);

                   scan.setCaching(500);

                   ResultScannerrs = table.getScanner(scan);

                   for(Result r : rs)

                            for(KeyValue kv : r.raw())

                                     System.out.println(String.format("row:%s,family:%s, qualifier:%s, qualifiervalue:%s, timestamp:%s.",

                                     Bytes.toString(kv.getRow()),Bytes.toString(kv.getFamily()),

                                     Bytes.toString(kv.getQualifier()),

                                     Bytes.toString(kv.getValue()),kv.getTimestamp()));

                           

                  

        

 

输出结果为:

row:100001, family:info, qualifier:id,qualifiervalue:1, timestamp:1469930920802.

row:100001, family:info, qualifier:name,qualifiervalue:Hadoop, timestamp:1469930934184.

 

很多人都会误认为一次scan操作就是一次RPC请求,实际上,一次请求大量数据的scan操作可能会导致多个很严重的后果:服务器端可能因为大量io操作导致io利用率很高,影响其他正常业务请求;大量数据传输会导致网络带宽等系统资源被大量占用;客户端也可能因为内存无法缓存这些数据导致OOM。为了避免这些问题,HBase会将一次大的scan操作根据设置条件拆分为多个RPC请求,每次只返回规定数量的结果。上述代码中foreach(Result r :rs)语句实际上等价于Result r = rs.next(),每执行一次next()操作就会调用客户端发送一次RPC请求,参数hbase.client.scanner.timeout.period就用来表示这么一次RPC请求的超时时间,默认为60000ms,一旦请求超时,就会抛出SocketTimeoutException异常。

 

根据上面的描述,我们引入两个问题来进行说明。

1.      一个Scan操作可能会被拆分为几个RPC

一次scan请求的RPC次数主要和两个因素相关,一个是本次scan的待检索条数,另一个是单次RPC请求的数据条数,很显然,两者的比值就是RPC请求次数。

一次scan的待检索条数由用户设置的条件决定,比如用户想一次获取某个用户最近一个月的所有操作信息,这些信息总和为10w条,那一次scan总扫瞄条数就是10w条。为了防止一次scan操作请求的数据量太大,额外提供了参数maxResultSize对总检索结果条数进行限制,该参数表示一次scan最多可以获取到的数据条数,默认为-1,表示无限制,如果用户设置了该参数,最后的返回结果条数就是该值与实际检索条数的更小者。

单次RPC请求的数据条数由参数caching设定,默认为100条。因为每次RPC请求获取到数据都会缓存到客户端,因此该值如果设置过大,可能会因为一次获取到的数据量太大导致客户端内存oom;而如果设置太小会导致一次大scan进行太多次RPC,网络成本高。

 

 

2.      在scan过程中RegionServer端偶尔抛出leaseException

看到leaseException就会想到租约机制,的确,HBase内部在一次完整的scan操作中引入了租约机制。为什么需要租约机制?这和整个scan操作流程有莫大的关系,上文讲到,一次完整的scan通常会被拆分为多个RPC请求,实际实现中,RegionServer接收到第一次RPC请求之后,会为该scan操作生成一个全局唯一的id,称为scanId。除此之外,RegionServer还会进行大量的准备工作,构建整个scan体系,构造需要用到的所有对象,后续的RPC请求只需要携带相同的scanId作为标示就可以直接利用这些已经构建好的资源进行检索。也就是说,在整个scan过程中,客户端其实都占用着服务器端的资源,此时如果此客户端意外宕机,是否就意味着这些资源永远都不能得到释放呢?租约机制就是为了解决这个问题。RegionServer接收到第一次RPC之后,除了生成全局唯一的scanId之外还会生成一个携带有超时时间的lease,超时时间可以通过参数hbase.regionserver.lease.period配置,一旦在超时时间内后续RPC请求没有到来(比如客户端处理太慢),RegionServer就认为客户端出现异常,此时会将该lease销毁并将整个scan所持有的资源全部释放,客户端在处理完成之后再发后续的RPC过来,检查到对应的lease已经不存在,就会抛出leaseExcption异常。

以上是关于hbase session超时时间是多少的主要内容,如果未能解决你的问题,请参考以下文章

Java EE 网站的默认会话超时是多少?

如何往session对象保存和取出数据?

黑猴子的家:HBase 之HRegionserver挂死,日志出现Session Expired异常排查

HBase性能调优

hbase参数配置优化

Hbase性能调优