1.4 安装部署与 Shell 初体验:写入第一行数据 本节摘要:以单机模式(standalone)为目标,从 JDK 准备、HBase 下载解压、两个配置文件改起,到启动、建表、写入、扫描、删除的完整 Shell 操作流。本节的命令输出请逐条对照,出现不一致时正好练习"看 Web UI 与日志定位"的基本功。 单机模式:五分钟能跑的最小集群 生产上的伪分布式、完全分布式先不碰。单机模式下 HBase 自带一个精简版 HDFS(或直接用本地文件系统)和内置 ZooKeeper,一个进程全包,最适合学习。它和生产模式的区别只在存储与协调层,Shell 与数据模型完全一致——学机制用它足够。 环境约定:Linux(或 WSL),JDK 8 或 11(HBase 2.
本节摘要:以单机模式(standalone)为目标,从 JDK 准备、HBase 下载解压、两个配置文件改起,到启动、建表、写入、扫描、删除的完整 Shell 操作流。本节的命令输出请逐条对照,出现不一致时正好练习"看 Web UI 与日志定位"的基本功。
生产上的伪分布式、完全分布式先不碰。单机模式下 HBase 自带一个精简版 HDFS(或直接用本地文件系统)和内置 ZooKeeper,一个进程全包,最适合学习。它和生产模式的区别只在存储与协调层,Shell 与数据模型完全一致——学机制用它足够。
环境约定:Linux(或 WSL),JDK 8 或 11(HBase 2.x 系列对两者都支持),约 2 GB 空闲内存。先确认 Java:
$ java -version openjdk version "11.0.21" 2023-10-17 OpenJDK Runtime Environment (build 11.0.21+9)
下载并解压(以 2.5.x 为例):
$ wget https://archive.apache.org/dist/hbase/2.5.8/hbase-2.5.8-bin.tar.gz $ tar -xzf hbase-2.5.8-bin.tar.gz -C /opt/ $ cd /opt/hbase-2.5.8/
需要改的配置只有两个文件。conf/hbase-env.sh 里指明 Java 家目录并关掉自带的 JVM 管理进程:
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk export HBASE_MANAGES_ZK=true
conf/hbase-site.xml 里指定数据落盘目录与 单机运行模式:
<configuration> <property> <name>hbase.rootdir</name> <value>file:///opt/hbase-data/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>false</value> </property> <property> <name>hbase.unsafe.stream.capability.enforce</name> <value>false</value> </property> </configuration>
hbase.rootdir 用 file:// 前缀即本地文件系统;将来伪分布式改成 hdfs://namenode:8020/hbase 即可。启动并验证:
$ bin/start-hbase.sh running master, logging to /opt/hbase-2.5.8/logs/hbase-root-master-vm1.out $ jps 3036 HMaster
看到 HMaster 进程即成功。浏览器访问 Master 所在机器的 16010 端口(地址形如 主机名:16010)进入 Web UI——这个页面后面要反复用,重点关注 Table Details 页的 Region 列表和 Region Servers 页的负载。
进入 Shell:
$ bin/hbase shell HBase Shell Use "help" to get list of supported commands. hbase:001:0>
建表。列族在建表时就要定义,这里建订单表,两个列族,cf 保留 5 个版本:
hbase:001:0> create 'orders', {NAME => 'cf', VERSIONS => 5}, {NAME => 'detail'} Created table orders Took 1.2345 seconds => Hbase::Table - orders
写入。语法是 put 表名, 行键, 列, 值,注意一次 put 只写一个单元格:
hbase:002:0> put 'orders', 'u1001-1724055123', 'cf:status', 'PAID' hbase:003:0> put 'orders', 'u1001-1724055123', 'cf:amount', '299.00' hbase:004:0> put 'orders', 'u1001-1724055123', 'detail:addr', 'hangzhou' hbase:005:0> put 'orders', 'u2002-1724055121', 'cf:status', 'NEW' Took 0.0123 seconds
点查与扫描:
hbase:006:0> get 'orders', 'u1001-1724055123', 'cf' COLUMN CELL cf:amount timestamp=1724055601, value=299.00 cf:status timestamp=1724055600, value=PAID 1 row(s) hbase:007:0> scan 'orders' ROW COLUMN+CELL u1001-1724055123 column=cf:amount, timestamp=1724055601, value=299.00 u1001-1724055123 column=cf:status, timestamp=1724055600, value=PAID u1001-1724055123 column=detail:addr, timestamp=1724055602, value=hangzhou u2002-1724055121 column=cf:status, timestamp=1724055603, value=NEW 2 row(s)
输出顺序留意:行按行键字典序排,同行内按列族、列限定符排——这就是 1.2 节说的"行键字典序组织"最直观的证据。更新就是再 put 一次;删除单元格用 delete,删整行用 deleteall——但记住 1.2 节的结论,删除只是打墓碑:
hbase:008:0> delete 'orders', 'u2002-1724055121', 'cf:status' hbase:009:0> get 'orders', 'u2002-1724055121' COLUMN CELL 0 row(s)
看 Region。用 Web UI 的 Table Details 页,或者直接查描述信息:
hbase:010:0> describe 'orders' Table orders is ENABLED orders COLUMN FAMILIES DESCRIPTION {NAME => 'cf', VERSIONS => '5', ...} {NAME => 'detail', ...} 2 row(s) hbase:011:0> list_region 'orders' SERVER | REGION_NAME | START_KEY | END_KEY vm1 | orders,,... | | 1 row(s)
只有一台机器、数据量又小,所以整张表就一个 Region(起始键、结束键都为空,代表负无穷到正无穷)。往这张表灌几十万行(后面第 5 章会给灌数据脚本),再到 Web UI 看,Region 会自动分裂成多个——那一刻你能亲眼看到"一行数据的落点"如何随 Region 边界变化而迁移。
⚠️ 常见坑:Shell 里表名、列名都要带单引号;
put一个命令只能写一个列,想一行多列要么多次 put 要么用 Java API 的 batch。另外 Shell 的 JVM 默认吃 1 GB 内存,机器紧张时改hbase-env.sh里的HBASE_SHELL_OPTS。
hbase:012:0> status 1 active master, 0 backup masters, 1 servers, 0 dead, 2.0000 average load hbase:013:0> exists 'orders' Table orders does exist hbase:014:0> disable 'orders' hbase:015:0> drop 'orders'
记住铁律:删表前必须先 disable。disable 会把 Region 全部下线,drop 才能清掉数据与元数据。反过来生产事故里最常见的误操作就是把还在写入的表 disable 了——业务端瞬间全部报错。
单机模式的一切机制(WAL、MemStore、Flush、Compaction、Region 分裂)与生产完全一致,只是它们都发生在同一个进程里。往伪分布式迁移只需三步:装好 HDFS 与 ZooKeeper;hbase.rootdir 改成 HDFS 地址、hbase.cluster.distributed 改 true;再用 local-regionservers.sh 起多个 RegionServer。生产化还要配 hbase.zookeeper.quorum、端口与内存,那是第 7 章运维的话题。
环境就绪,第一行数据已落盘。下一章开始追踪它:从 WAL 到 MemStore 到 HFile,完整走一遍写入路径。