前言
本文隶属于专栏《大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和参考文献请见大数据技术体系
几种导致重试的常见异常
在 HBase 客户端到服务端的通信过程中,可能会碰到各种各样的异常。
例如有以下几种导致重试的常见异常:
- 待访问 Region 所在的 RegionServer 发生宕机,此时 Region 已经被移到一个新的 RegionServer 上,但由于客户端存在 meta 缓存,首次 RPC 请求仍然访问到了旧的 RegionServer。后续将重试发起 RPC。
- 服务端负载较大,导致单次RPC响应超时。客户端后续将继续重试,直到 RPC 成功或者超过客户容忍最大延迟。
- 访问meta表或者ZooKeeper异常。
超时参数
下面我们了解一下HBase常见的几个超时参数。
hbase.rpc.timeout
:表示单次 RPC 请求的超时时间,一旦单次 RPC 超过该时间, 上层将收到 TimeoutException。默认为 60 000ms。hbase.client.retries.number
:表示调用 API 时最多容许发生多少次 RPC 重试操作。默认为 35 次。hbase.client.pause
:表示连续两次 RPC 重试之间的休眠时间,默认为 100ms。注意,HBase 的重试休眠时间是按照随机退避算法计算的,若 hbase.client.pause=100,则第一次 RPC 重试前将休眠 1 00ms 左右,第二次 RPC 重试前将休眠 200ms 左右,第三次 RPC 重试前将休眠 300ms 左右,第四次重试前将休眠 500ms 左右,第五次重试前将休眠 1 000ms 左右,第六次重试则将休眠 2 000 ms 左右…… 也就是重试次数越多,则休眠的时间会越长。因此,若按照默认的 hbase.client.retries.number=35,则可能长期卡在休眠和重试两个步骤中。hbase.client.operation.timeout
:表示单次 API 的超时时间,默认值为 1200 000 ms。注意, get/put/delete 等表操作称为一次 API 操作,一次 API 可能会有多次 RPC 重试,这个 operation.timeout 限制的是 API 操作的总超时。
实践
假设某业务要求单次 HBase 的读请求延迟不超过 1 s,那么该如何设置上述 4 个超时参数呢?
首先,hbase.client.operation.timeout
应该设成 1 s。
其次,在 SSD 集群上,如果集群参数设置合适且集群服务正常,则基本可以保证 p99 延迟在 100ms 以内,因此 hbase.rpc.timeout
设成 100ms。这里,hbase.client.pause
用默认的 100ms。
最后,在 1s 之内,第一次 RPC 耗时 100ms,休眠 100ms,第二次 RPC 耗时 100ms, 休眠 200ms,第三次 RPC 耗时 100ms,休眠300ms,第四次 RPC 耗时 100ms,休眠 500ms (不是完全线性递增的)。因此,在hbase.client.operation.timeout
内,至少可执行 4 次 RPC 重试,实际中单次 RPC 耗时可能更短(因为有 hbase.rpc.timeout
保证了单次 RPC 最长耗时),所以 hbase.client.retries.number
可以稍微设大一点(保证在 1s 内有更多的重试,从而提高请求成功的概率),比如设成 6 次。