一、HBase的安装
1. 版本匹配
一定要注意,HBase的版本一定要和已经安装的JDK和Hadoop的版本保持兼容,不能随便选择版本。可以参考官方网站链接http://hbase.apache.org/book.html#java
2. 软件下载
Apache HBase官网下载HBase软件,链接http://hbase.apache.org/downloads.html,点击Download那一列的bin
我的Hadoop是2.10.0版,选择了2.2.4版本的HBase。下载完成后,在本地得到hbase-2.2.4-bin.tar.gz压缩文件。
3. 解压软件
解压下载的文件文件到工作路径/usr/local
$ sudo tar -zxf ~/Downloads/hbase-1.1.2-bin.tar.gz -C /usr/local
查看/usr/local下内容
$ ls /usr/local
输出
bin etc games hadoop hbase-2.2.4 include lib man sbin share src
可以看到hbase-2.2.4文件夹。为方便使用,修改文件夹名为hbase
$ sudo mv /usr/local/hbase-2.2.4 /usr/local/hbase
4. 修改环境变量
为进一步方便调用hbase文件夹下的命令,可以将hbase下的bin目录添加到环境变量中。用vim编辑器打开.bashrc文件
$ vim ~/.bash
进入vim编辑器后,按a或i切换到编辑模式。这里有两种情况:
(1) 如果没有引入过PATH,即没有“export PATH=...”这样一行,则在文件开头添加如下内容
export PATH=$PATH:/usr/local/hbase/bin
(2) 如果已经有“export PATH=...”这样一行,则在这一行末尾添加下面内容——注意不要空格也不要换行
:/usr/local/hbase
其中“:”是分隔符,后面跟的是HBase文件夹路径。效果如下图
修改完成后,Esc退出编辑模式,然后输入“:wq”保存并退出vim编辑器。
在shell中执行source命令使上述配置在当前终端立即生效
$ source ~/.bashrc
值得说明的是,修改~/.bashrc只对单个用户生效。当登录以及每次打开新的 shell 时,该文件被读取。
5. 添加权限
然后添加HBase权限。先进入HBase文件夹所在目录
$ cd /usr/local
再将hbase下的所有文件的所有者改为用户hadoop(即当前Linux登录用户)
$ sudo chown -R hadoop ./hbase
6. 查看版本
最后可以通过查看HBase版本来确定是否安装成功
$ hbase version
——注意可以直接调用hbase命令是因为我们前面添加了PATH,否则应该加上路径,即
$ /usr/local/hbase/bin/hbase version
会输出一大段内容,其中包括HBase版本号
HBase 2.2.4
则说明安装成功。
二、单机模式
HBase有三种运行模式:单机模式、伪分布式模式、分布式模式。作为练习,这里使用单机模式和伪分布模式。首先讲解单机模式配置和运行
1. 配置hbase-env.sh
用vim编辑器打开hbase-env.sh
$ vim /usr/local/hbase/conf/hbase-env.sh
按a或i进入编辑模式,在首行添加如下内容
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HBASE_MANAGES_ZK=true
其中/usr/lib/jvm/java-8-openjdk-amd64是JDK的安装目录,可能不同。另外,配置HBASE_MANAGES_ZK为true,表示由hbase自己管理zookeeper,不需要单独的zookeeper——这条在文件里本来就有,只是被加#注释掉了,所以也可以通过删除#号来解锁。修改完成后,Esc退出编辑模式,然后输入“:wq”保存并退出vim编辑器。
2. 配置hbase-site.xml
用gedit打开hbase-site.xml文件
$ gedit /usr/local/hbase/conf/hbase-site.xml
初始<configuration>和<\configuration>之间是没有内容的。现在添加如下内容
<property>
<name>hbase.rootdir</name>
<value>file:///usr/local/hbase/hbase-tmp</value>
</property>
目的是在启动HBase前需要设置属性hbase.rootdir,以指定HBase数据的存储位置。因为如果不设置的话,hbase.rootdir默认为/tmp/hbase-${user.name},这意味着每次重启系统都会丢失数据。此处将HBase数据存储位置设置在HBase安装目录下的hbase-tmp文件夹,即/usr/local/hbase/hbase-tmp。设置完毕,保存退出。
3. 运行HBase
在shell中输入(如果没配置path则输入完全路径,效果一样)
$ start-hbase.sh #或输入完全路径/usr/local/hbase/bin/start-hbase.sh
会返回
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/hbase/lib/client-facing-thirdparty/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
running master, logging to /usr/local/hbase/bin/../logs/hbase-hadoop-master-xing-ThinkPad-P52s.out
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/usr/local/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/local/hbase/lib/client-facing-thirdparty/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
然后进入shell命令模式,输入
$ hbase shell #或输入完全路径/usr/local/hbase/bin/hbase shell
等待一会儿,最后光标前变为
hbase(main):001:0>
说明启动成功。
想退出shell命令模式则输入exit并回车
hbase(main):001:0> exit
要关闭HBase则输入(注意要先退出shell命令模式)
$ stop-hbase.sh #或输入完全路径/usr/local/hbase/bin/stop-hbase.sh
三、伪分布模式
1. 配置hbase-env.sh
与单机模式配置一样,vim打开hbase-env.sh
$ vim /usr/local/hbase/conf/hbase-env.sh
在开头添加如下内容
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HBASE_MANAGES_ZK=true
export HBASE_CLASSPATH=/usr/local/hadoop/conf
即比单机模式多添加了一行HBASE_CLASSPATH,前面两行和单机模式一样(如果已经有了不要重复添加)。
2. 配置hbase-site.xml
依旧与单机模式配置一样,用gedit打开hbase-site.xml文件
$ gedit /usr/local/hbase/conf/hbase-site.xml
在<configuration>和<\configuration>之间添加如下内容(注意先删除之前添加的单机模式配置内容)
<property>
<name>hbase.rootdir</name>
<value>hdfs://localhost:9000/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
第一个property是修改hbase.rootdir,指定HBase数据在HDFS上的存储路径——假设当前Hadoop集群运行在伪分布式模式下,在本机上运行,且NameNode运行在9000端口。
第二个property是将属性hbase.cluter.distributed设置为true,即设置集群处于分布式模式。
第三个property是关闭stream capabilities(hflush/hsync)功能,因为伪分布式的DataNode只有一个,hbase运行在LocalFileSystem(由rootdir表示)——如果不加第三个property,则使用HBase操作表时会报错
KeeperErrorCode = NoNode for /hbase/master
*对第三个property更详细分析见https://blog.csdn.net/az9996/article/details/88946932
3. 运行HBase
首先登录SHH
$ ssh localhost
这里应该不需要输入密码,因为之前设置了SHH无密码登陆。会返回欢迎内容
Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 5.3.0-42-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
* Canonical Livepatch is available for installation.
- Reduce system reboots and improve kernel security. Activate at:
https://ubuntu.com/livepatch
21 packages can be updated.
0 updates are security updates.
Your Hardware Enablement Stack (HWE) is supported until April 2023.
*** System restart required ***
Last login: Sun Mar 15 17:09:56 2020 from 127.0.0.1
然后启动HDFS。因为之前已经把HDFS的目录添加在.bashr的PATH了,所以可以直接输入
$ start-dfs.sh #或输入完全路径/usr/local/hadoop/sbin/start-dfs.sh
输入jps命令以检查是否成功启动HDFS
jps
输出
19686 Jps
19067 NameNode
19275 DataNode
19532 SecondaryNameNode
能看到NameNode,DataNode和SecondaryNameNode说明成功启动。
然后启动HBase,输入
$ start-hbase.sh #或输入完全路径/usr/local/hbase/bin/start-hbase.sh
启动完成,再次输入命令
jps
应输出
20019 HQuorumPeer
20564 Jps
19067 NameNode
19275 DataNode
19532 SecondaryNameNode
20271 HRegionServer
多了HQuorumPeer和HRegionServer,说明HBase启动成功。
然后可以进入shell命令模式
$ hbase shell #或输入完全路径/usr/local/hbase/bin/hbase shell
等待一会儿,最后光标前变为
hbase(main):001:0>
说明成功进入shell命令模式。
简单总结启动HBase顺序为:SSH -> HDFS -> HBase -> shell命令模式
4. 退出HBase
首先退出shell命令模式,输入exit并回车
hbase(main):001:0> exit
接着关闭HBase,输入
$ stop-hbase.sh #或输入完全路径/usr/local/hbase/bin/stop-hbase.sh
然后可以关闭HDFS
$ stop-dfs.sh #或输入完全路径/usr/local/hadoop/sbin/stop-dfs.sh
最后退出SHH
$ logout
简单总结退出顺序为:shell命令模式 -> HBase -> HDFS -> SHH(进入HBase与之相反)
四、HBase基本操作
1. 创建表
在HBase的shell命令模式下,用create命令创建表一个名为student的表,包含五个属性(即五个列族):Sname、Ssex、Sage、Sdept和course
hbase(main):001:0> create 'student','Sname','Ssex','Sage','Sdept','course'
返回
Created table student
Took 2.7673 seconds
=> Hbase::Table - student
则创建成功。注意HBase的表中会有一个系统默认的属性作为主键,所以无需自行创建主键。
创建完后,可通过describe命令查看表的基本信息
hbase(main):002:0> describe 'student'
Table student is ENABLED
student
COLUMN FAMILIES DESCRIPTION
{NAME => 'Sage', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'F
OREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', C
OMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
{NAME => 'Sdept', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => '
FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false',
COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
{NAME => 'Sname', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => '
FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false',
COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
{NAME => 'Ssex', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'F
OREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', C
OMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
{NAME => 'course', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL =>
'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false',
COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}
5 row(s)
QUOTAS
0 row(s)
Took 0.0457 seconds
2. 添加和修改数据
HBase采用三维有序存储实现数据的有序存储:
行键(rowkey):是数据行的唯一标识,必须通过它进行数据行访问,故在添加数据时,必须制定行键(也称主键)的值。
列键(column key):包含列族(columnFamily)和列限定符(qualifier)上下两级。也有人称HBase是四维存储,即把列族和列限定符(也简称列)视为两个维度。
时间戳(timestamp):在添加数据时,HBase会自动为添加的数据添加一个时间戳。故在需要修改数据时,只需直接添加数据,HBase即会产生新的数据,而旧的数据依然会被保存。在进行查看操作时默认返回最新版本的数据。这就相当于完成了“改”操作。
HBase用put命令添加数据,每次只能给一个表的一行的一列添加一个数据。比如在刚才创建的student表里添加主键(默认,可视为学号)为95001,名字(Sname列族)为YangXing的一行数据
hbase(main):003:0> put 'student','95001','Sname:','YangXing'
Sname后的冒号可要可不要。如果列族下有列,则在列族名后冒号加列限定符即可。比如给95001行下的course列族的math列添加一个数据90
hbase(main):004:0> put 'student','95001','course:math','90'
最后给93020行下的course列族的english列添加一个数据87
hbase(main):005:0> put 'student','93020','course:english','87'
修改数据其实就是在原有位置put数据即可,比如修改93020行下的course列族的english列的数据为82
hbase(main):006:0> put 'student','93020','course:english','82'
它的时间戳会发生变化,可以用下面讲的查看数据命令来验证。
3. 查看数据
HBase中有两个用于查看数据的命令
(1) get命令:用于查看表的某一行数据
(2) scan命令:用于查看表的全部数据
执行get命令查看‘student’表‘95001’行的数据
hbase(main):007:0> get 'student','95001'
返回
COLUMN CELL
Sname: timestamp=1586174484974, value=YangXing
course:math timestamp=1586175378205, value=90
1 row(s)
Took 0.0100 seconds
使用scan命令查看‘student’表的全部数据
hbase(main):008:0> scan 'student'
返回
ROW COLUMN+CELL
93020 column=course:english, timestamp=1586176382246, value=82
95001 column=Sname:, timestamp=1586174484974, value=YangXing
95001 column=course:math, timestamp=1586175378205, value=90
2 row(s)
Took 0.0061 seconds
4. 删除数据
常用的删除命令有两个
(1) delete:用于删除一个数据,即put的反向操作,注意仅删除最新版本的数据
(2) deleteall:用于删除一行里所有列的数据,包括历史版本的数据
例如,删除student表95001行的course:english列
hbase(main):009:0> delete 'student','93020','course:english'
然后查看表
hbase(main):010:0> scan 'student'
会得到
ROW COLUMN+CELL
93020 column=course:english, timestamp=1586175559525, value=87
95001 column=Sname:, timestamp=1586174484974, value=YangXing
95001 column=course:math, timestamp=1586175378205, value=90
2 row(s)
Took 0.0057 seconds
发现93020行的course:english列依然有数据,但不是最新的值为82的数据,而是上个版本value=87的,时间戳也不一样。
另外要注意的是,如果一个列族有列限定符,使用delete时候必须指定列限定符,即不能一次性删除一个列族(除非列族里没有列限定符)。比如以下命令不会生效
hbase(main):011:0> delete 'student','93020','course'
因为93020行的course列族含有english列限定符。但下面的命令可以生效
hbase(main):012:0> delete 'student','95001','Sname'
因为95001行的Sname列族没有列限定符。
(另外提醒一下:不同行的相同列族不一定有相同的列限定符,也允许有的有列限定符而有的没有)
然后试验一下deleteall命令。比如要删除95001行所有列的数据,则输入
hbase(main):013:0> deleteall 'student','95001'
然后查看表
hbase(main):014:0> scan 'student'
会得到
ROW COLUMN+CELL
93020 column=course:english, timestamp=1586175559525, value=87
1 row(s)
Took 0.0126 seconds
95001行的数据都没有了(包括历史版本)。
Reference:
http://dblab.xmu.edu.cn/blog/using_hbase/