HBase之超时机制

客户端超时设置对整个系统的稳定性以及敏感性至关重要,一旦没有超时设置或超时时间设置过长,服务器端的长时间卡顿必然会引起客户端阻塞等待,进而影响上层应用。好在HBase提供了多个客户端参数设置超时,主要包括 hbase.rpc.timeout / hbase.client.operation.timeout/ hbase.client.scanner.timeout.period

一 hbase.rpc.timeout

表示一次RPC请求的超时时间,如果某一次RPC请求超过该值,客户端就会主动关闭socket,此时服务器端就会捕获到如下的异常:


上述异常经常发生在大量高并发读写业务或者服务器端发生了比较严重的Full GC等场景下,导致某些请求无法得到及时处理,超过了时间间隔。该值默认大小为60000ms,即1min。

 

二 hbase.client.operation.timeout

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

 

三 hbase.client.scanner.timeout.period

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

period

publicList<String> scan(StringtableName,String startRow, StringstopRow,String family, Stringqualifier) throws IOException{

       if (StringUtils.isBlank(tableName)) {

              System.err.println("table isblank!");

             return null;

       }

       if (StringUtils.isBlank(family)) {

              System.err.println("family isblank!");

             return null;

       }

       if (StringUtils.isBlank(qualifier)) {

              System.err.println("qualifieris blank!");

             return null;

       }

       Scanscan = newScan(Bytes.toBytes(startRow), Bytes.toBytes(stopRow));

       TableNametn= TableName.valueOf(tableName);

       Table table = this.conn.getTable(tn);

       ResultScanner scanner = table.getScanner(scan);

       List<String> valList = new ArrayList<String>();

       Stringdata = null;

       for (Result : scanner) {

             byte[] arr =result.getValue(Bytes.toBytes(family), Bytes.toBytes(qualifier));

             data = Bytes.toString(arr);

             valList.add(data);

       }

       table.close();

       return valList;

}

 

很多人都会误认为一次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异常

 

四 scan 请求是怎么拆分的呢?

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

 

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

 

 

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

 

五 在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:



### 回答1: HBase作为一个分布式系统,需要ZooKeeper来进行集群的协调和管理。在HBase中,ZooKeeper Session是指客户端与ZooKeeper服务器之间的逻辑连接,如果客户端与ZooKeeper服务器的Session失效,客户端需要重新连接到ZooKeeper服务器。 HBase的ZooKeeper Session重连机制分为两种情况: 1. 客户端与ZooKeeper服务器的连接断开,但是ZooKeeper服务器仍然存在,这种情况下客户端会尝试重新连接到ZooKeeper服务器,并恢复之前的Session。 2. ZooKeeper服务器不可用,这种情况下客户端会不断地重试连接,直到ZooKeeper服务器可用。当ZooKeeper服务器重新启动并且客户端重新连接成功后,客户端会创建一个新的Session。 ### 回答2: HBase是一个分布式数据库,它使用ZooKeeper来协调和管理其集群中的各个节点。在HBase中,当与ZooKeeper建立连接时,会创建一个会话(session),该会话会定期向ZooKeeper发送心跳以保持连接。 然而,由于各种原因,会话可能会中断,例如网络故障、ZooKeeper集群重新启动或者部分节点宕机等。在这种情况下,HBase会采取重连机制来重新建立与ZooKeeper的连接。 具体而言,HBase的重连机制如下: 1. 首先,HBase会在会话断开之后尝试与ZooKeeper重新建立连接,它会使用预先配置的ZooKeeper集群地址来查找并连接可用的ZooKeeper节点。 2. HBase会等待一段时间,并定期尝试连接ZooKeeper。默认情况下,它会每隔10秒尝试一次,直到连接成功或超过最大尝试次数。 3. 一旦HBase重新建立了与ZooKeeper的连接,它将恢复之前断开的会话。这意味着HBase将能够继续向ZooKeeper发送心跳以保持连接,并且能够接收和处理由ZooKeeper发送的事件通知。 4. 如果HBase尝试连接的次数超过了最大尝试次数,并且仍然无法建立连接,则表示重连失败。这时HBase会进行相应的错误处理,例如记录错误日志、抛出异常或进行其他操作。 综上所述,HBase的重连机制通过周期性地尝试连接ZooKeeper来保证与ZooKeeper的连接稳定性。这确保了HBase能够持续地与ZooKeeper进行通信,从而有效地管理和协调整个HBase集群的操作。 ### 回答3: HBase使用Zookeeper来进行协调和管理分布式集群的配置信息和状态信息。Zookeeper作为一个可靠的分布式协调服务,可以保证数据的一致性和可用性。 在HBase中,当Zookeeper与HBase Master建立连接时会创建一个会话(session),用于维护两者之间的通信。会话通常具有超时时间,一旦超过这个时间,Zookeeper会认为会话已失效并将其关闭。 当HBase Zookeeper会话丢失或超时后,会触发HBase的ZooKeeperWatcher机制进行重连。ZooKeeperWatcher是HBase中一个用于监视Zookeeper状态变化的线程。重连过程包括以下几个步骤: 1. ZooKeeperWatcher会尝试重新建立与Zookeeper的连接。它会检查是否存在已建立的连接,如果存在则会关闭旧连接。 2. 如果与Zookeeper的连接建立成功,则重新初始化HBase集群的状态。这包括重新注册HBase Master和RegionServer节点以及恢复已分配的Region。 3. 如果与Zookeeper的连接建立失败,则会进行重试。重试机制通常是指定一定的时间间隔后再次尝试连接,直到连接成功或超过最大重试次数。 需要注意的是,在HBase中,Zookeeper会话的重连过程是透明的,对HBase用户来说是无感知的。用户只需要确保在配置文件中正确指定Zookeeper集群地址,而不需要关心具体的重连机制。 总之,HBase的Zookeeper会话重连机制确保了与Zookeeper的连接的可靠性和一致性,使得HBase集群在网络异常或Zookeeper故障的情况下能够自动恢复正常的运行状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值