前哨站/第8章 HBase实战
第8章 HBase实战

第8章 HBase实战

当需求从"批量分析"变成"随机实时读写"时,HBase 补上了 HDFS 的短板。

列式存储ShellPhoenix

本章学习目标

  • 能说出 HBase 的定位、逻辑视图与 RowKey 设计要点
  • 能安装单机/伪分布式/完全分布式 HBase
  • 能熟练使用 HBase Shell 完成建表与增删改查
  • 能用 Java API 操作 HBase
  • 能用 Phoenix 通过 SQL 查询 HBase

本章导览

核心内容

8.1

HBase概述

HBase 是构建在 HDFS 之上的、面向列的分布式数据库,擅长海量数据的随机实时读写(毫秒~秒级)。

8.1.1

什么是HBase

对比项HDFSHBase
数据访问顺序扫描、批量读按 RowKey 随机读写,毫秒级
数据修改一次写入多次读取支持增删改(追加 + 时间戳)
适用场景离线批处理实时查询、明细查询、消息存储
  • 表结构:Table → Row(行)→ Column Family(列族)→ Column(列)→ Version(版本)
  • RowKey 是唯一主键,按字典序排序,是 HBase 设计的核心
  • 数据按列族存储,列族在物理上是独立的文件
8.1.2

逻辑视图与模式设计

SHELL
# 逻辑视图(类似稀疏的、多维的 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)、完全分布式(多台机器)。

SHELL
# 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:16010
8.3

HBase Shell命令操作

入门最有效的方式就是在 shell 里敲一遍建表与增删改查。

8.3.1

Shell常用命令

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操作

JAVA
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基础操作

SHELL
-- 进入 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 策略回收。