Since all APIs of {@link HBaseClient} are asynchronous and non-blocking,it's possible that the application would produce RPCs at a rate higher than HBase is able to handle. When this happens, {@link HBaseClient}will typically do some buffering up to a certain point beyond which RPCs will fail-fast with this exception, to prevent the application from running itself out of memory.
This exception is expected to be handled by having the application throttle or pause itself for a short period of time before retrying the RPC that failed with this exception as well as before sending other RPCs. The reason this exception inherits from {@link NonRecoverableException}instead of {@link RecoverableException} is that the usual course of actionwhen handling a {@link RecoverableException} is to retry right away, whichwould defeat the whole purpose of this exception. Here, we want the application to retry after a reasonable delay as well as throttle the pace of creation of new RPCs. What constitutes a "reasonable delay" depends on the nature of RPCs and rate at which they're produced. For a write-heavy high-throughput application, this exception will typically be used when HBase is in the process of splitting a region or migrating a region to another server, in which case the application should stop producing new writes for typically at least 1 second (or significantly slow down its pace, to let {@link HBaseClient} buffer the writes).
When {@link HBaseClient} buffers RPCs, it typically uses this exceptionwith a low watermark and a high watermark. When the buffer hits the low watermark, the next (unlucky) RPC that wants to be buffered will be failed with a {@code PleaseThrottleException}, to send an "advisory warning" to the application that it needs to throttle itself. All subsequent RPCs that need to be buffered will be buffered until the buffer hits the high watermark. Once the high watermark has been hit, all subsequent RPCs that need to be buffered will fail-fast with a {@code PleaseThrottleException}.
One effective strategy to handle this exception is to set a flag to true when this exception is first emitted that causes the application to pause or throttle its use of HBase. Then you can retry the RPC that failed (which is accessible through {@link #getFailedRpc}) and add a callback to it in order to unset the flag once the RPC completes successfully. Note that low-throughput applications will typically rarely (if ever) hit the low watermark and should never hit the high watermark, so they don't need complex throttling logic.
|
|
|
|