6

I recently came across BufferedMutator class of HBase which can be used for batch inserts and deletes. I was previously using a List to put data as hTable.put(putList) to do the same. Benchmarking my code didn't seem to show much difference too, where I was instead doing mutator.mutate(putList);. Is there a significant performance improvement of using BufferedMutator over PutList?

4

1 回答 1

13

简答

BufferedMutator通常提供比仅使用更好的吞吐量,但Table#put(List<Put>)需要适当调整hbase.client.write.buffer、和以获得良好的性能。hbase.client.max.total.taskshbase.client.max.perserver.taskshbase.client.max.perregion.tasks

解释

当您将 put 列表传递给 HBase 客户端时,它会按目标区域对 puts 进行分组,并按目标区域服务器对这些组进行批处理。为每个批次发送一个 rpc 请求。这减少了 rpc 开销,尤其是在 Put 非常小的情况下,从而使每个请求的 rpc 开销很大。

客户端立即将Table所有 Puts 发送到区域服务器并等待响应。这意味着任何可能发生的批处理都仅限于单个 API 调用中的 Put 数量,并且从调用者的角度来看,api 调用是同步的。但是,在BufferedMutator缓冲区中不断缓冲 Puts,并决定根据当前缓冲的大小在后台线程中刷新缓冲的 put,这些线程由一个名为AsyncProcess. 从调用者的角度来看,每个 API 调用仍然是同步的,但整个缓冲策略提供了更好的批处理。后台刷新模型还允许请求的连续流,结合更好的批处理意味着能够支持更多的客户端线程。然而,由于这种缓冲策略,缓冲区越大,调用者看到的每次操作延迟越差,但是通过拥有更多数量的客户端线程可以维持更高的吞吐量。

一些控制 BufferedMutator 吞吐量的配置是:

hbase.client.write.buffer:缓冲区的大小(字节)(越高提供更好的峰值吞吐量,消耗更多内存)

hbase.client.max.total.tasks: 在 AsyncProcess 开始阻塞请求之前,集群中的待处理请求数(越高越好,但可能会使客户端 CPU 饿死,或导致服务器过载)

hbase.client.max.perserver.tasks:在 AsyncProcess 开始阻塞请求之前,一个区域服务器的待处理请求数。

hbase.client.max.perregion.tasks:每个区域的待处理请求数。

此外,为了完整起见,不言而喻,如果瓶颈在服务器端而不是客户端,那么通过在客户端使用BufferedMutatorover将不会看到太多的性能提升Table

于 2017-08-31T04:36:32.080 回答