HBase BufferedMutator 与 PutList 性能对比

HBase BufferedMutator vs PutList performance

最近接触到HBase的BufferedMutatorclass,可以用于批量插入和删除。 我以前使用 List 将数据作为 hTable.put(putList) 来做同样的事情。 对我的代码进行基准测试似乎也没有显示出太大差异,而我却在做 mutator.mutate(putList);。 使用 BufferedMutator 比 PutList 有显着的性能改进吗?

简答

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

说明

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

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

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

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

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

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

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

此外,为了完整起见,不言而喻,如果瓶颈在服务器端而不是客户端,那么使用 BufferedMutator 不会比 Table 在客户端上。