前言
HBase 是一个构建在 Hadoop HDFS 之上的分布式、面向列的 NoSQL 数据库。它是 Google Bigtable 的开源实现,具有高可靠性、高性能、可伸缩的特点,适合存储海量稀疏数据。本文将详细介绍 HBase 的基本概念、Shell 命令、Java API 以及常用操作。
一、HBase 核心概念
1.1 数据模型
| Table(表) | HBase 中数据的逻辑组织单位 |
| Row Key(行键) | 表中每行数据的唯一标识,按字典序排序 |
| Column Family(列族) | 列的集合,必须在建表时预先定义 |
| Column Qualifier(列限定符) | 列族中的具体列,可以动态添加 |
| Cell(单元格) | 由行键、列族、列限定符、时间戳唯一确定的数据单元 |
| Timestamp(时间戳) | 每个 Cell 的版本标识,默认为写入时间 |
1.2 数据坐标
HBase 中定位一个数据需要四个维度:
[Row Key, Column Family, Column Qualifier, Timestamp] -> Value
1.3 物理存储结构
Table
└── Region (按 Row Key 范围划分)
└── Store (每个 Column Family 对应一个 Store)
├── MemStore (内存缓存)
└── StoreFile/HFile (磁盘文件)
二、HBase Shell 基础命令
2.1 连接与帮助
# 启动 HBase Shell
hbase shell
# 退出 HBase Shell
exit
quit
# 查看帮助
help
# 查看特定命令的帮助
help 'create'
help 'put'
help 'get'
# 查看命令组
help 'general'
help 'ddl'
help 'dml'
help 'namespace'
# 查看 HBase 状态
status
status 'simple'
status 'summary'
status 'detailed'
# 查看版本
version
# 查看当前用户
whoami
# 查看表列表
list
三、命名空间(Namespace)操作
命名空间类似于关系型数据库中的数据库概念,用于对表进行逻辑分组。
# 创建命名空间
create_namespace 'my_namespace'
# 创建命名空间并设置属性
create_namespace 'my_namespace', {'PROPERTY_NAME'=>'PROPERTY_VALUE'}
# 查看所有命名空间
list_namespace
# 查看命名空间详情
describe_namespace 'my_namespace'
# 查看命名空间下的表
list_namespace_tables 'my_namespace'
# 修改命名空间属性
alter_namespace 'my_namespace', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}
# 删除命名空间属性
alter_namespace 'my_namespace', {METHOD => 'unset', NAME => 'PROPERTY_NAME'}
# 删除命名空间(必须为空)
drop_namespace 'my_namespace'
系统默认命名空间
| hbase | 系统内置表所在的命名空间 |
| default | 未指定命名空间时的默认命名空间 |
四、表(Table)DDL 操作
4.1 创建表
# 基本创建(单个列族)
create 'table_name', 'column_family'
# 创建多个列族
create 'table_name', 'cf1', 'cf2', 'cf3'
# 使用完整语法创建
create 'table_name', {NAME => 'cf1'}, {NAME => 'cf2'}
# 在指定命名空间创建表
create 'my_namespace:table_name', 'cf1'
# 创建表并设置列族属性
create 'table_name', {NAME => 'cf1', VERSIONS => 5}
# 设置多个列族属性
create 'table_name', {
NAME => 'cf1',
VERSIONS => 5,
TTL => 86400,
BLOCKCACHE => true,
COMPRESSION => 'SNAPPY'
}
# 创建预分区表
create 'table_name', 'cf1', SPLITS => ['10', '20', '30', '40']
# 使用分区文件创建
create 'table_name', 'cf1', SPLITS_FILE => '/path/to/splits.txt'
# 使用十六进制分区
create 'table_name', 'cf1', {NUMREGIONS => 16, SPLITALGO => 'HexStringSplit'}
# 使用均匀分区
create 'table_name', 'cf1', {NUMREGIONS => 10, SPLITALGO => 'UniformSplit'}
4.2 列族属性详解
| NAME | 列族名称 | 必填 |
| VERSIONS | 保留的版本数 | 1 |
| MIN_VERSIONS | 最小保留版本数 | 0 |
| TTL | 数据生存时间(秒) | FOREVER |
| BLOCKCACHE | 是否启用块缓存 | true |
| BLOCKSIZE | 块大小(字节) | 65536 |
| COMPRESSION | 压缩算法 | NONE |
| BLOOMFILTER | 布隆过滤器类型 | ROW |
| REPLICATION_SCOPE | 复制范围 | 0 |
| IN_MEMORY | 是否优先缓存在内存 | false |
| DATA_BLOCK_ENCODING | 数据块编码 | NONE |
4.3 压缩算法选项
# 可用的压缩算法
COMPRESSION => 'NONE' # 不压缩
COMPRESSION => 'GZ' # Gzip 压缩
COMPRESSION => 'SNAPPY' # Snappy 压缩(推荐)
COMPRESSION => 'LZO' # LZO 压缩
COMPRESSION => 'LZ4' # LZ4 压缩
COMPRESSION => 'ZSTD' # Zstandard 压缩
4.4 布隆过滤器选项
BLOOMFILTER => 'NONE' # 不使用
BLOOMFILTER => 'ROW' # 基于行键(默认)
BLOOMFILTER => 'ROWCOL' # 基于行键+列限定符
4.5 查看表信息
# 查看所有表
list
# 使用正则过滤表
list 'user.*'
list 'ns:.*'
# 查看表是否存在
exists 'table_name'
# 查看表结构
describe 'table_name'
desc 'table_name'
# 查看表的详细信息
describe 'table_name'
# 查看表的 Region 信息
list_regions 'table_name'
# 获取表的 Region 位置
locate_region 'table_name', 'row_key'
4.6 修改表
# 禁用表(修改前必须先禁用)
disable 'table_name'
# 检查表是否禁用
is_disabled 'table_name'
# 启用表
enable 'table_name'
# 检查表是否启用
is_enabled 'table_name'
# 添加列族
alter 'table_name', NAME => 'new_cf'
# 添加列族并设置属性
alter 'table_name', NAME => 'new_cf', VERSIONS => 3, TTL => 86400
# 修改列族属性
alter 'table_name', NAME => 'cf1', VERSIONS => 5
# 删除列族
alter 'table_name', NAME => 'cf1', METHOD => 'delete'
alter 'table_name', 'delete' => 'cf1'
# 修改表级属性
alter 'table_name', MAX_FILESIZE => '134217728'
alter 'table_name', READONLY => true
# 设置表的协处理器
alter 'table_name', 'coprocessor' => 'hdfs:///path/to/coprocessor.jar|com.example.MyCoprocessor|1001|'
# 移除协处理器
alter 'table_name', METHOD => 'table_att_unset', NAME => 'coprocessor$1'
# 同时修改多个列族
alter 'table_name', {NAME => 'cf1', VERSIONS => 5}, {NAME => 'cf2', TTL => 86400}
4.7 删除表
# 禁用表
disable 'table_name'
# 删除表
drop 'table_name'
# 批量禁用表(使用正则)
disable_all 'test.*'
# 批量删除表(使用正则)
drop_all 'test.*'
# 清空表数据(保留表结构)
truncate 'table_name'
# 保留分区的清空
truncate_preserve 'table_name'
五、数据 DML 操作
5.1 插入/更新数据(Put)
# 基本插入
put 'table_name', 'row_key', 'cf:qualifier', 'value'
# 插入并指定时间戳
put 'table_name', 'row_key', 'cf:qualifier', 'value', timestamp
# 插入带属性
put 'table_name', 'row_key', 'cf:qualifier', 'value', {ATTRIBUTES => {'attr1' => 'value1'}}
# 示例
put 'users', 'user001', 'info:name', 'John'
put 'users', 'user001', 'info:age', '25'
put 'users', 'user001', 'info:email', 'john@example.com'
put 'users', 'user001', 'contact:phone', '1234567890'
# 插入二进制数据
put 'table_name', 'row_key', 'cf:qualifier', "\\x00\\x01\\x02\\x03"
5.2 获取数据(Get)
# 获取整行数据
get 'table_name', 'row_key'
# 获取指定列族
get 'table_name', 'row_key', 'cf
get 'table_name', 'row_key', 'cf:qualifier'
# 获取多个列
get 'table_name', 'row_key', 'cf1:q1', 'cf2:q2'
# 获取指定列族的多个列
get 'table_name', 'row_key', {COLUMN => ['cf:q1', 'cf:q2']}
# 获取指定时间戳的数据
get 'table_name', 'row_key', {COLUMN => 'cf:qualifier', TIMESTAMP => 1234567890}
# 获取指定时间范围的数据
get 'table_name', 'row_key', {COLUMN => 'cf:qualifier', TIMERANGE => [1234567890, 1234567900]}
# 获取多个版本
get 'table_name', 'row_key', {COLUMN => 'cf:qualifier', VERSIONS => 5}
# 获取所有版本
get 'table_name用过滤器
get 'table_name', 'row_key', {FILTER => "ValueFilter(=, 'binary:value')"}
# 获取原始数据(包括删除标记)
get 'table_name', 'row_key', {RAW => true, VERSIONS => 10}
5.3 扫描数据(Scan)
# 扫描整表
scan 'table_name'
# 限制返回行数
scan 'table_name', {LIMIT => 10}
# 指定起始和结束行键
scan 'table_name', {STARTROW => 'row001', STOPROW => 'row100'}
# 包含结束行键(HBase 2.0+)
scan 'table_name', {STARTROW => 'row001', STOPROW => 'row100', INCLUSIVE_STOP_ROW => true}
# 扫描指定列族
scan 'table_name', {COLUMNS => 'cf'}
# 扫描指定列
scan 'table_name', {COLUMNS => ['cf:q1', 'cf:q2']}
# 扫描多个版本
scan 'table_name', {VERSIONS => 5}
# 指定时间范围
scan 'table_name', {TIMERANGE => [1234567890, 1234567900]}
# 反向扫描
scan 'table_name', {REVERSED => true}
# 设置缓存行数
scan 'table_name', {CACHE => 1000}
# 原始扫描(包括删除标记)
scan 'table_name', {RAW => true, VERSIONS => 10}
# 只返回行键
scan 'table_name', {FILTER => "KeyOnlyFilter()"}
# 只返回第一列
scan 'table_name', {FILTER => "FirstKeyOnlyFilter()"}
# 行键前缀过滤
scan 'table_name', {ROWPREFIXFILTER => 'user'}
# 使用过滤器
scan 'table_name', {FILTER => "PrefixFilter('row')"}
# 组合多个条件
scan 'table_name', {
STARTROW => 'row001',
STOPROW => 'row100',
COLUMNS => ['cf:q1', 'cf:q2'],
LIMIT => 100,
VERSIONS => 3,
FILTER => "ValueFilter(=, 'binary:value')"
}
5.4 删除数据(Delete)
# 删除指定列的最新版本
delete 'table_name', 'row_key', 'cf:qualifier'
# 删除指定列的指定版本
delete 'table_name', 'row_key', 'cf:qualifier', timestamp
# 删除整个列族
delete 'table_name', 'row_key', 'cf'
# 删除整行
deleteall 'table_name', 'row_key'
# 删除整行的指定列族
deleteall 'table_name', 'row_key', 'cf'
# 删除整行的指定列
deleteall 'table_name', 'row_key', 'cf:qualifier'
# 删除指定时间戳之前的所有版本
deleteall 'table_name', 'row_key', 'cf:qualifier', timestamp
5.5 计数器操作(Incr)
# 增加计数器
incr 'table_name', 'row_key', 'cf:qualifier', increment_value
# 增加 1
incr 'table_name', 'row_key', 'cf:qualifier', 1
# 减少(使用负数)
incr 'table_name', 'row_key', 'cf:qualifier', -1
# 获取计数器值
get_counter 'table_name', 'row_key', 'cf:qualifier'
5.6 追加操作(Append)
# 追加数据到现有值
append 'table_name', 'row_key', 'cf:qualifier', 'value_to_append'
六、过滤器(Filter)详解
6.1 比较过滤器
# 行键过滤器
scan 'table_name', {FILTER => "RowFilter(=, 'binary:row001')"}
scan 'table_name', {FILTER => "RowFilter(>=, 'binary:row001')"}
scan 'table_name', {FILTER => "RowFilter(=, 'substring:user')"}
scan 'table_name', {FILTER => "RowFilter(=, 'regexstring:user.*')"}
# 列族过滤器
scan 'table_name', {FILTER => "FamilyFilter(=, 'binary:cf1')"}
# 列限定符过滤器
scan 'table_name', {FILTER => "QualifierFilter(=, 'binary:name')"}
# 值过滤器
scan 'table_name', {FILTER => "ValueFilter(=, 'binary:value')"}
scan 'table_name', {FILTER => "ValueFilter(>=, 'binary:100')"}
scan 'table_name', {FILTER => "ValueFilter(=, 'substring:test')"}
# 时间戳过滤器
scan 'table_name', {FILTER => "TimestampsFilter(1234567890, 1234567891)"}
6.2 比较运算符
| = | 等于 |
| != | 不等于 |
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
6.3 比较器
| binary | 精确匹配 |
| binaryprefix | 前缀匹配 |
| substring | 子串匹配 |
| regexstring | 正则匹配 |
6.4 专用过滤器
# 前缀过滤器
scan 'table_name', {FILTER => "PrefixFilter('user')"}
# 列前缀过滤器
scan 'table_name', {FILTER => "ColumnPrefixFilter('name')"}
# 多列前缀过滤器
scan 'table_name', {FILTER => "MultipleColumnPrefixFilter('name', 'age')"}
# 列范围过滤器
scan 'table_name', {FILTER => "ColumnRangeFilter('a', true, 'z', true)"}
# 单列值过滤器
scan 'table_name', {FILTER => "SingleColumnValueFilter('cf', 'age', >=, 'binary:18')"}
# 单列值排除过滤器
scan 'table_name', {FILTER => "SingleColumnValueExcludeFilter('cf', 'age', >=, 'binary:18')"}
# 页面过滤器(限制返回行数)
scan 'table_name', {FILTER => "PageFilter(10)"}
# 列分页过滤器
scan 'table_name', {FILTER => "ColumnPaginationFilter(5, 0)"}
# 列计数过滤器
scan 'table_name', {FILTER => "ColumnCountGetFilter(10)"}
# 首个键值过滤器
scan 'table_name', {FILTER => "FirstKeyOnlyFilter()"}
# 只返回键过滤器
scan 'table_name', {FILTER => "KeyOnlyFilter()"}
# 包含结束行过滤器
scan 'table_name', {FILTER => "InclusiveStopFilter('row100')"}
# 随机行过滤器
scan 'table_name', {FILTER => "RandomRowFilter(0.5)"}
# 依赖列过滤器
scan 'table_name', {FILTER => "DependentColumnFilter('cf', 'qualifier')"}
6.5 组合过滤器
# AND 组合
scan 'table_name', {FILTER => "PrefixFilter('user') AND ValueFilter(=, 'binary:active')"}
# OR 组合
scan 'table_name', {FILTER => "PrefixFilter('user') OR PrefixFilter('admin')"}
# SKIP 过滤器(跳过整行)
scan 'table_name', {FILTER => "SKIP ValueFilter(!=, 'binary:valid')"}
# WHILE 过滤器(遇到不匹配时停止)
scan 'table_name', {FILTER => "WHILE RowFilter(<=, 'binary:row100')"}
# 复杂组合
scan 'table_name', {
FILTER => "(PrefixFilter('user') AND SingleColumnValueFilter('cf', 'status', =, 'binary:active')) OR PrefixFilter('admin')"
}
七、Region 管理
7.1 Region 操作
# 查看表的 Region 列表
list_regions 'table_name'
# 手动分裂 Region
split 'table_name'
split 'table_name', 'split_key'
split 'region_name'
split 'region_name', 'split_key'
# 合并 Region
merge_region 'region_name_1', 'region_name_2'
merge_region 'region_name_1', 'region_name_2', true # 强制合并
# 移动 Region 到指定 RegionServer
move 'region_name', 'server_name'
# 关闭 Region
close_region 'region_name'
close_region 'region_name', 'server_name'
# 分配 Region
assign 'region_name'
# 取消分配 Region
unassign 'region_name'
# 平衡 Region
balance_switch true # 开启自动平衡
balance_switch false # 关闭自动平衡
balancer # 手动触发平衡
balancer_enabled # 查看平衡器状态
# 压缩 Region
compact 'table_name'
compact 'region_name'
compact 'table_name', 'cf'
# 主压缩
major_compact 'table_name'
major_compact 'region_name'
major_compact 'table_name', 'cf'
# 刷新 MemStore 到磁盘
flush 'table_name'
flush 'region_name'
7.2 Region 信息查询
# 获取 Region 位置
locate_region 'table_name', 'row_key'
# 查看 Region 状态
status 'detailed'
# 查看 hbase:meta 表
scan 'hbase:meta'
scan 'hbase:meta', {FILTER => "PrefixFilter('table_name')"}
八、快照(Snapshot)管理
# 创建快照
snapshot 'table_name', 'snapshot_name'
# 查看所有快照
list_snapshots
# 查看匹配的快照
list_snapshots 'snap.*'
# 查看快照详情
describe_snapshot 'snapshot_name'
# 从快照恢复表
disable 'table_name'
restore_snapshot 'snapshot_name'
enable 'table_name'
# 从快照克隆新表
clone_snapshot 'snapshot_name', 'new_table_name'
# 删除快照
delete_snapshot 'snapshot_name'
# 批量删除快照
delete_all_snapshot 'snap.*'
# 导出快照到 HDFS
# 在命令行执行
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot snapshot_name -copy-to hdfs://destination/path
# 导入快照
# 在命令行执行
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot snapshot_name -copy-from hdfs://source/path -copy-to hdfs://destination/path
九、安全与权限管理
9.1 用户权限
# 授予权限
grant 'user', 'RWXCA', 'table_name'
grant 'user', 'RW', 'table_name', 'cf'
grant 'user', 'R', 'table_name', 'cf', 'qualifier'
# 权限说明
# R – 读取
# W – 写入
# X – 执行
# C – 创建
# A – 管理
# 撤销权限
revoke 'user', 'table_name'
revoke 'user', 'table_name', 'cf'
# 查看用户权限
user_permission 'table_name'
# 授予命名空间权限
grant 'user', 'RWXCA', '@namespace'
# 授予全局权限
grant 'user', 'RWXCA'
9.2 可见性标签
# 添加标签
add_labels 'label1', 'label2'
# 设置用户标签
set_auths 'user', 'label1', 'label2'
# 获取用户标签
get_auths 'user'
# 清除用户标签
clear_auths 'user', 'label1'
# 插入带标签的数据
put'table_name', 'row_key', 'cf:qualifier', 'value', {VISIBILITY => 'label1'}
# 扫描带标签的数据
scan 'table_name', {AUTHORIZATIONS => ['label1', 'label2']}
十、Java API 使用
10.1 Maven 依赖
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.4.17</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>2.4.17</version>
</dependency>
10.2 建立连接
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
public class HBaseConnection {
private static Connection connection;
public static Connection getConnection() throws IOException {
if (connection == null || connection.isClosed()) {
Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "zk1,zk2,zk3");
config.set("hbase.zookeeper.property.clientPort", "2181");
config.set("zookeeper.znode.parent", "/hbase");
connection = ConnectionFactory.createConnection(config);
}
return connection;
}
public static void closeConnection() throws IOException {
if (connection != null && !connection.isClosed()) {
connection.close();
}
}
}
10.3 DDL 操作
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.io.compress.Compression;
public class HBaseDDL {
// 创建命名空间
public static void createNamespace(String namespace) throws IOException {
try (Admin admin = HBaseConnection.getConnection().getAdmin()) {
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor
.create(namespace)
.addConfiguration("creator", "admin")
.build();
admin.createNamespace(namespaceDescriptor);
}
}
// 创建表
public static void createTable(String tableName, String... columnFamilies) throws IOException {
try (Admin admin = HBaseConnection.getConnection().getAdmin()) {
TableName tn = TableName.valueOf(tableName);
if (admin.tableExists(tn)) {
System.out.println("Table already exists");
return;
}
TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tn);
for (String cf : columnFamilies) {
ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder
.newBuilder(Bytes.toBytes(cf))
.setMaxVersions(3)
.setTimeToLive(86400)
.setCompressionType(Compression.Algorithm.SNAPPY)
.setBlockCacheEnabled(true)
.build();
tableBuilder.setColumnFamily(cfd);
}
admin.createTable(tableBuilder.build());
}
}
// 创建预分区表
public static void createTableWithSplits(String tableName, String cf, byte[][] splitKeys) throws IOException {
try (Admin admin = HBaseConnection.getConnection().getAdmin()) {
TableName tn = TableName.valueOf(tableName);
TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tn);
ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder
.newBuilder(Bytes.toBytes(cf))
.build();
tableBuilder.setColumnFamily(cfd);
admin.createTable(tableBuilder.build(), splitKeys);
}
}
网硕互联帮助中心






评论前必须登录!
注册