第8章 HBase实战
当需求从"批量分析"变成"随机实时读写"时,HBase 补上了 HDFS 的短板。
本章学习目标
- 能说出 HBase 的定位、逻辑视图与 RowKey 设计要点
- 能安装单机/伪分布式/完全分布式 HBase
- 能熟练使用 HBase Shell 完成建表与增删改查
- 能用 Java API 操作 HBase
- 能用 Phoenix 通过 SQL 查询 HBase
本章导览
核心内容
8.1
HBase概述
HBase 是构建在 HDFS 之上的、面向列的分布式数据库,擅长海量数据的随机实时读写(毫秒~秒级)。
8.1.1
什么是HBase
| 对比项 | HDFS | HBase |
|---|---|---|
| 数据访问 | 顺序扫描、批量读 | 按 RowKey 随机读写,毫秒级 |
| 数据修改 | 一次写入多次读取 | 支持增删改(追加 + 时间戳) |
| 适用场景 | 离线批处理 | 实时查询、明细查询、消息存储 |
- 表结构:Table → Row(行)→ Column Family(列族)→ Column(列)→ Version(版本)
- RowKey 是唯一主键,按字典序排序,是 HBase 设计的核心
- 数据按列族存储,列族在物理上是独立的文件
8.1.2
逻辑视图与模式设计
# 逻辑视图(类似稀疏的、多维的 map)
RowKey info:name info:age score:math
1001 张三 20 90
1002 李四 21 — ← 缺列不占空间
# RowKey 设计三原则
# ① 长度短(建议 10~100 字节)② 散列分布(避免热点)③ 有业务含义(便于范围扫描)💡 RowKey 设计不当会造成"热点":所有写请求集中到同一台 RegionServer。常用解法是加盐(hash 前缀)或反转时间戳。
8.2
安装HBase
三种模式:单机(HBase 自带 ZooKeeper + 本地文件)、伪分布式(所有角色在一台机器,数据落 HDFS)、完全分布式(多台机器)。
# hbase-site.xml 关键配置(伪分布式)
<property><name>hbase.rootdir</name>
<value>hdfs://hadoop1:9000/hbase</value></property>
<property><name>hbase.cluster.distributed</name><value>true</value></property>
<property><name>hbase.zookeeper.quorum</name>
<value>hadoop1,hadoop2,hadoop3</value></property>
# 启动
start-hbase.sh
jps # 应看到 HMaster 与 HRegionServer
# Web:http://hadoop1:160108.3
HBase Shell命令操作
入门最有效的方式就是在 shell 里敲一遍建表与增删改查。
8.3.1
Shell常用命令
hbase shell
# 建表(两个列族)
create 'student', 'info', 'score'
# 插入(put 表 行键 列族:列 值)
put 'student', '1001', 'info:name', '张三'
put 'student', '1001', 'info:age', '20'
put 'student', '1001', 'score:math', '90'
# 查询
get 'student', '1001'
scan 'student'
scan 'student', {STARTROW=>'1001', STOPROW=>'1002'}
count 'student'
# 修改与删除
put 'student', '1001', 'info:age', '21' # 覆盖(新版本)
delete 'student', '1001', 'info:age'
deleteall 'student', '1001'
# 维护
list
describe 'student'
disable 'student' && drop 'student'8.4
HBase Java API操作
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "hadoop1,hadoop2,hadoop3");
Connection conn = ConnectionFactory.createConnection(conf);
Table table = conn.getTable(TableName.valueOf("student"));
// 插入
Put put = new Put(Bytes.toBytes("1001"));
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("张三"));
table.put(put);
// 查询
Get get = new Get(Bytes.toBytes("1001"));
Result r = table.get(get);
System.out.println(Bytes.toString(r.getValue(Bytes.toBytes("info"), Bytes.toBytes("name"))));
// 扫描
Scan scan = new Scan();
ResultScanner rs = table.getScanner(scan);
for (Result result : rs) System.out.println(result);
table.close(); conn.close();8.5
Phoenix实战
Phoenix 在 HBase 之上提供 SQL 能力:可以建表、建索引、用 JDBC 查询,把"用 SQL 查 HBase"变成现实。
8.5.2
Phoenix基础操作
-- 进入 sqlline
sqlline.py hadoop1:2181
-- 建表(映射到 HBase 表)
CREATE TABLE IF NOT EXISTS student (
id VARCHAR PRIMARY KEY,
info.name VARCHAR,
info.age INTEGER,
score.math INTEGER
);
-- 插入与查询
UPSERT INTO student VALUES ('1001','张三',20,90);
SELECT * FROM student;
SELECT * FROM student WHERE id = '1001';
-- 建二级索引(提升非 RowKey 条件查询)
CREATE INDEX idx_name ON student (info.name);本章小结
本章从 HBase 的定位讲起(补齐 HDFS 随机读写短板),给出逻辑视图与 RowKey 设计原则,完成三种模式的安装,然后用 Shell 与 Java API 分别演练建表、增删改查、扫描与删除,最后用 Phoenix 在 HBase 上实现 SQL 查询。
思考与练习 先自己做,再点开答案
01
HBase 与关系型数据库的核心差异?
查看参考答案
HBase 是稀疏、分布式的列式存储:只有 RowKey 唯一索引,按 RowKey 排序存储;列可以动态增加,缺列为空不占空间;不支持复杂 join 与事务(仅单行强一致)。关系库有固定模式、丰富索引与完整事务。
02
RowKey 设计不好会带来什么问题?
查看参考答案
热点问题:RowKey 单调递增会让写请求集中到同一 RegionServer。缓解办法是加盐前缀(hash)、反转字段、或预分区。
03
put 同一个 cell 两次,会覆盖还是保留?
查看参考答案
会写入新版本(时间戳),读取默认返回最新版本;旧版本由 compaction 按 TTL/versions 策略回收。