HBase 客户端会查找为所关注的特定行范围提供服务的 RegionServer。它通过查询 hbase:meta 表来完成此操作。详情参见[hbase:meta](#arch.catalog.meta)。在找到所需的 region 之后,客户端联系服务该 region 的 RegionServer 发出读取或写入请求,而不是通过 master。此信息被缓存在客户端中,以便后续请求无需经过查找过程。如果 region 由主负载均衡器重新分配,或者因为 RegionServer 已经死亡,则客户端将重新查询目录表以确定用户 region 的新位置。

有关 Master 对 HBase Client 通信的影响的详细信息,请参阅Runtime Impact

管理功能是通过 Admin 实例完成的

68.1. 集群连接

HBase 1.0 中更改了 API。有关连接配置信息,请参阅连接到 HBase 集群的客户端配置和依赖关系

68.1.1. HBase 1.0.0 的 API

API 已被清理,使用者会通过接口而不是具体类型来工作。在 HBase 1.0 中,从 ConnectionFactory 中获取一个 Connection 对象,然后根据需要从中获取 TableAdminRegionLocator 的实例。完成后,关闭获取的实例。最后,确保在退出之前清理 Connection 实例。Connections 是重量级对象,但是线程安全,因此可以在应用程序中创建并保持一个实例。TableAdminRegionLocator 实例是轻量级的。它们可以随时创建,然后在使用后立即释放掉。有关新 HBase 1.0 API 的使用示例,请参阅Client Package Javadoc 说明

68.1.2. HBase 1.0.0 之前的 API

1.0.0 之前,HTable 实例是与 HBase 集群进行交互的方式。 _[Table](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Table.html)实例不是线程安全的。在任何给定时间,只有一个线程可以使用 Table 的实例。创建 Table 实例时,建议使用相同的 [HBaseConfiguration](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/HBaseConfiguration)实例。确保将 ZooKeeper 和套接字实例共享到 RegionServers,通常也是你想要的。例如,推荐这种方式:

HBaseConfiguration conf = HBaseConfiguration.create();
HTable table1 = new HTable(conf, "myTable");
HTable table2 = new HTable(conf, "myTable");

而不是这种:

HBaseConfiguration conf1 = HBaseConfiguration.create();
HTable table1 = new HTable(conf1, "myTable");
HBaseConfiguration conf2 = HBaseConfiguration.create();
HTable table2 = new HTable(conf2, "myTable");

关于 HBase 客户端如何处理连接的更多信息,请参阅 ConnectionFactory.

连接池

For applications which require high-end multithreaded access (e.g., web-servers or application servers that may serve many application threads in a single JVM), you can pre-create a Connection, as shown in the following example: 对于需要高级多线程访问的应用程序(例如,在单个 JVM 中为许多应用程序线程提供服务的 Web 服务器或应用服务器),你可以预先创建一个Connection,示例如下:

Example 22. 预创建一个 Connection

// Create a connection to the cluster.
Configuration conf = HBaseConfiguration.create();
try (Connection connection = ConnectionFactory.createConnection(conf);
     Table table = connection.getTable(TableName.valueOf(tablename))) {
  // use table as needed, the table returned is lightweight
}

HTablePool 已经废弃

本指南的早期版本讨论了 HTablePool,不过它在 HBase 0.94, 0.95 和 0.96 版本中被废弃,并在 0.98.1 版本中被删除,HBASE-6580,而 HConnection,在 HBase 1.0 中被 Connection 代替。请改用Connection

68.2. WriteBuffer 和批处理方法

在 HBase 1.0 和后续版本中,HTable 被废弃,改用 TableTable 并不使用自动刷新。如果需要缓冲写入,使用 BufferedMutator 类。

在 HBase 2.0 及更高版本中,HTable 不使用 BufferedMutator 来执行 Put 操作。有关更多信息,请参阅HBASE-18500

关于写入持久性的更多信息,请参阅 ACID semantics

对于批量 PutDelete 的细粒度控制,请参阅 Table 方法 batch

68.3. 异步客户端

HBase 2.0 中引入了一种新 API,旨在提供异步访问 HBase 的能力。

你可以从 ConnectionFactory 中获取 AsyncConnection,然后从中获取一个异步表实例来访问 HBase。处理完成后,关闭 AsyncConnection 实例(通常在程序退出时)。

对于异步表,大多数方法与旧的 Table 接口具有相同的含义,返回值通常用 CompletableFuture 包装。 因为这里没有任何缓冲区,所以没有异步表的 close 方法,你不需要关闭它。它是线程安全的。

对于 scan,有几点不同:

  • 仍然有一个 getScanner 方法返回一个 ResultScanner。可以以旧方式使用它,它的工作方式类似于旧的 ClientAsyncPrefetchScanner

  • 有一个 scanAll 方法,它会立即返回所有结果。它的目的是为通常希望立即获得全部结果的小范围扫描提供更简单的方法。

  • 观察者模式。 有一个 scan 方法接受 ScanResultConsumer 作为参数。 它会将结果传递给消费者。

请注意,AsyncTable 接口是模板化的。模板参数指定扫描使用的 ScanResultConsumerBase 的类型,这意味着观察者类型的 scan API 是不同的。scan 的消费者有两种类型 - ScanResultConsumerAdvancedScanResultConsumer

ScanResultConsumer 需要一个单独的线程池,用于执行注册到返回 CompletableFuture 的回调方法。因为使用独立的线程池可以释放 RPC 线程,所以回调可以自由地执行任何操作。如果回调慢或不确定的时候,使用此配置。

AdvancedScanResultConsumer 在框架线程内执行回调。不允许在回调中进行耗时操作,否则它可能会阻塞框架线程并导致非常糟糕的性能问题。正如其名称一样,它专为希望编写高性能代码的高级用户而设计。有关如何使用它编写完全异步代码,请参阅 org.apache.hadoop.hbase.client.example.HttpProxyExample

68.4. 异步管理

你可以从 ConnectionFactory 中获取 AsyncConnection,然后从中获取一个 AsyncAdmin 实例来访问 HBase。请注意,有两个 getAdmin 方法可以获取 AsyncAdmin 实例。一种方法有一个额外的线程池参数,用于执行回调。它专为普通用户设计。另一种方法不需要线程池,所有回调都在框架线程内执行,因此不允许在回调中进行耗时操作。它专为高级用户设计。

默认的 getAdmin 方法将返回一个使用默认配置的 AsyncAdmin 实例。如果要自定义某些配置,可以使用 getAdminBuilder 方法获取用于创建 AsyncAdmin 实例的 AsyncAdminBuilder。用户可以自由设置他们关注的配置来创建一个新的 AsyncAdmin 实例。

对于 AsyncAdmin 接口,大多数方法与旧的 Admin 接口具有相同的含义,返回值通常被 CompletableFuture 包装。

For region name, we only accept byte[] as the parameter type and it may be a full region name or a encoded region name. For server name, we only accept ServerName as the parameter type. For table name, we only accept TableName as the parameter type. For list* operations, we only accept Pattern as the parameter type if you want to do regex matching. 对于大多数管理操作,当返回的 CompletableFuture 完成时,也意味着管理操作已完成。但是对于压缩操作,它只意味着压缩请求被发送到 HBase 并且可能需要一些时间来完成压缩操作。对于 rollWALWriter 方法,它只表示 rollWALWriter 请求被发送到 region server,可能需要一些时间来完成 rollWALWriter 操作。

对于 region 名称,只接受 byte[] 类型的参数,它可以是完整的 region 名称或编码后的 region 名称。对于服务器名称,只接受 ServerName 类型的参数。 对于表名,只接受 TableName 类型的参数。 对于 list* 操作,如果想要进行正则表达式匹配,只接受 Pattern 类型的参数。

68.5. 扩展客户端

有关非 Java 客户端和自定义协议的信息,请参阅Apache HBase External APIs