配置 HBase 后端
概述
HBase 后端将图数据存储在 Apache HBase 表中。HugeGraph 仅作为 HBase 客户端:它通过 HBase 的 ZooKeeper 集群连接,为每个图创建一个 HBase namespace,并在其中创建该图的 schema 表、数据表和索引表。计数查询由 HBase 的 AggregateImplementation 协处理器完成,HugeGraph 在创建每张表时都会挂载该协处理器。
注意:HBase 后端已废弃,计划在 HugeGraph 2.0 中移除。新部署请使用
hstore(分布式)或rocksdb(内嵌,默认值),已有的 HBase 部署请规划迁移。
自 1.7.0 起,发行包内置的后端只有 hstore、rocksdb、hbase 和 memory。HBase provider 上报的后端驱动版本为 1.12。
支持的 HBase 版本
客户端 jar 固定为 HBase 2.6.5(hbase-endpoint 加 hbase-shaded-client)。服务端要求 HBase 2.x:当检测到的 HBase 版本低于 2.0 时,scan 逻辑会把 inclusive stop row 改写为 exclusive 并追加一个 0 字节,因为该版本之前 inclusive stop row 不生效。CI 任务和本地 Docker 镜像都使用 HBase 2.6.5,后端也是针对这个版本做测试的。
选择该后端
修改需要使用 HBase 的图的 conf/graphs/hugegraph.properties:
注意:
serializer必须设置为hbase,而不是binary。HBase 序列化器是BinarySerializer的子类,它不在 rowkey 中写入 id 前缀,并写入预分区的顶点表和边表所需要的分区前缀。使用serializer=binary时这两点都不生效。
然后初始化后端并启动服务:
默认发行包构建时包含 rocksdb, hbase, hstore 三个后端,无需额外引入 jar。使用 rocksdb-only Maven profile 构建的发行包不包含 HBase 后端,此时 backend=hbase 会以 Not exists BackendStoreProvider: hbase 打开失败。
下面所有配置项都位于图配置文件(conf/graphs/hugegraph.properties)中,而不是 rest-server.properties。只有当发行包包含 hbase 后端时,这些配置项才会被注册。
连接配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| hbase.hosts | localhost | HBase ZooKeeper 的主机名或 IP 地址,多个以逗号分隔,不允许为空。对应 hbase.zookeeper.quorum。 |
| hbase.port | 2181 | HBase ZooKeeper 的端口,取值范围 1 到 65535。对应 hbase.zookeeper.property.clientPort。 |
| hbase.znode_parent | /hbase | HBase ZooKeeper 的 znode 父路径,不允许为空。对应 zookeeper.znode.parent。 |
| hbase.zk_retry | 3 | HBase ZooKeeper 的恢复重试次数,取值范围 0 到 1000。对应 zookeeper.recovery.retry。 |
| hbase.threads_max | 64 | HBase 连接的最大线程数,取值范围 1 到 1000。对应 hbase.hconnection.threads.max,HBase 自身默认值为 256,这里取更小的值以避免内存溢出。 |
超时配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| hbase.truncate_timeout | 30 | 等待后端 truncate 的超时时间,单位秒,必须为正数。该超时按 store 计算,而一个图有三个 store,因此一次 truncate 最多耗时该值的三倍。 |
| hbase.aggregation_timeout | 43200(12 小时) | 等待聚合的超时时间,单位秒,必须为正数。它会设置计数查询所用聚合客户端的 hbase.rpc.timeout。 |
Kerberos 与 HBase 配置文件配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| hbase.kerberos_enable | false | 是否为 HBase 启用 Kerberos 认证。 |
| hbase.krb5_conf | /etc/krb5.conf | Kerberos 配置文件,包含 KDC IP、默认 realm 等。会被设置为 java.security.krb5.conf 系统属性。 |
| hbase.hbase_site | /etc/hbase/conf/hbase-site.xml | HBase 的配置文件。无论是否启用 Kerberos,每次建立连接时都会把它作为配置资源加载。 |
| hbase.kerberos_principal | (空) | Kerberos 认证使用的 HBase principal。 |
| hbase.kerberos_keytab | (空) | Kerberos 认证使用的 HBase keytab 文件。 |
当 hbase.kerberos_enable=true 时,HugeGraph 会在连接上把 hadoop.security.authentication 和 hbase.security.authentication 设置为 kerberos,然后在打开连接之前用配置的 principal 从 keytab 登录。因此 Kerberos 环境下 hbase.krb5_conf、hbase.hbase_site、hbase.kerberos_principal 和 hbase.kerberos_keytab 四项都必须有效:
即使关闭 Kerberos,hbase.hbase_site 也会被读取,路径不存在时相当于加载了一个空资源。当需要上述配置项之外的 HBase 设置时,把它指向集群自身的 hbase-site.xml。
预分区配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| hbase.enable_partition | true | 是否为 HBase 启用预分区。它同时决定后端是否声明支持前缀扫描和范围扫描。 |
| hbase.vertex_partitions | 10 | HBase 顶点表的分区数,不允许为负数。 |
| hbase.edge_partitions | 30 | HBase 边表的分区数,不允许为负数。 |
启用预分区后,顶点表按 hbase.vertex_partitions 个 region 创建,两张边表各按 hbase.edge_partitions 个 region 创建,序列化器会在 rowkey 前面加上 id 哈希得到的分区前缀。
注意:请在初始化后端之前,按实际数据量和 region server 数量调整分区数。它对导入速度影响很大,并且只在建表时生效。
关闭 hbase.enable_partition 会恢复不带前缀的原始 rowkey。作为交换,后端此时会声明支持前缀扫描和范围扫描,这两类扫描在预分区 rowkey 下无法工作。
Namespace 与表结构
每个图对应一个 HBase namespace,名称为 <graphspace>/<store> 转小写,并把 / 替换为 _,因为 HBase namespace 名称只允许字母数字和 _ 字符。在默认配置 graphspace=DEFAULT、store=hugegraph 下,namespace 为 default_hugegraph。
在该 namespace 内,一个图包含三个 store:schema store m、graph store g 和 system store s:
| Store | 表 |
|---|---|
schema (m) | VL、EL、PK、IL、C、m_si |
graph (g) | g_v、g_oe、g_ie、g_si、g_vi、g_ei、g_ii、g_fi、g_li、g_di、g_ai、g_hi、g_ui |
system (s) | s_v、s_oe、s_ie、s_si、s_vi、s_ei、s_ii、s_fi、s_li、s_di、s_ai、s_hi、s_ui、M |
g_v 是顶点表,g_oe 和 g_ie 分别是出边表和入边表,其余 g_* 表依次是二级索引、顶点标签索引、边标签索引、范围索引(int、float、long、double)、全文索引、shard 索引和唯一索引表。所有表都只有一个名为 f 的列族,并且都在建表时挂载了 org.apache.hadoop.hbase.coprocessor.AggregateImplementation 协处理器。只有 g_v、g_oe 和 g_ie 会预分区,system store 中同名的那几张表按单个 region 创建。
system store 中的 M 表保存 init-store.sh 写入的后端版本。truncate 图时会排除该表,因为丢失它会导致下次启动的版本校验失败。清空图会删除这些表;连同存储空间一起清空则会删除整个 namespace。
GET /metrics/backend 会返回 HBase 集群状态:cluster_id、master_name、average_load、hbase_version、region_count、leaving_servers、nodes、region_servers,以及一个 servers map,其中包含每个 region server 的堆内存、磁盘、请求数和 region 明细。PUT /graphspaces/{graphspace}/graphs/{name}/compact 会请求 HBase 对该图的所有表做 compaction。
使用 Docker 做本地测试
Server 仓库中的 docker/hbase 会构建一个 HBase 2.6.5 单机镜像(hugegraph/hbase:2.6.5,容器名 hg-hbase-test),用于本地开发和测试。以下命令都在仓库根目录执行。
为运行在宿主机上的 HugeGraph 启动 HBase:
为运行在同一个 Docker 网络中的容器化 HugeGraph 启动 HBase:
对外公布的主机名很重要:容器启动时会把 HBASE_MASTER_HOSTNAME 和 HBASE_REGIONSERVER_HOSTNAME 写入自己的 hbase-site.xml,未设置时回退到 HBASE_HOSTNAME(默认 hbase)。如果客户端无法解析这个主机名,即使 ZooKeeper 可用,也会报 UnknownHostException: hbase:16000。
映射到宿主机的端口:
| 端口 | 服务 |
|---|---|
| 2181 | ZooKeeper,与 hbase.port 默认值一致 |
| 16000 | HBase Master RPC |
| 16010 | HBase Master Web UI,http://localhost:16010 |
| 16020 | HBase RegionServer RPC |
| 16030 | HBase RegionServer Web UI,http://localhost:16030 |
针对它运行后端测试:
停止并删除数据卷:
该镜像会分别启动 ZooKeeper、master 和 region server 三个守护进程,并等到 master 上报有存活的 server 之后才开始 tail 日志,因此首次启动会比较慢。请给 Docker 分配至少 4 GB 内存。compose 的健康检查也因此设置了 90 秒的 start period。
限制
HBase 后端不支持以下特性:
- 事务。rollback 只会丢弃尚未提交的批次,而 commit 是逐表写入的,因此跨表不是原子的。
- 原地更新单个顶点或边属性,以及合并顶点属性。属性存放在一个 cell 中,因此会重写整个属性列。
- 按名称查询 schema,以及仅按标签查询顶点或边。这两者都需要 HBase 二级索引。
- 按标签删除边。
- 带
in条件、contains条件或contains_key条件的查询。 - 聚合属性和 OLAP 属性。
- 原生数值类型(后端特性
supportsNumberType为关闭状态)。 - scan token。
hbase.enable_partition为true时的前缀扫描和范围扫描。- 除
count以外的聚合函数,其它聚合函数会被拒绝。 - 快照。创建或恢复后端快照会抛出
UnsupportedOperationException。
已支持的特性包括顶点和边的 TTL、分页查询、order by 查询、范围条件,以及按输入 id 排序。