Hbase| 01安装| shell操作
GFS -->hdfs
mapreduce --->hadoop mr
bigtable-->hbase
HBase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统
海量存储;列式存储;极易扩展;高并发;稀疏(针对HBase列的灵活性,在列族中,你可以指定任意多的列;稀疏性体现了它的非结构化特点)
hbase是一个基于hdfs的列式存储系统,可以用廉价pc组建集群,对10亿行百万列的数据量级提供随机实时读写。
标示 列族
rowkey column family
列族中有若干列,列并不是它的结构;
1. HBase的安装
Hbase和Hadoop版本的对应
1 Zookeeper正常部署
首先保证Zookeeper集群的正常部署,并启动之
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[kris@hadoop101 zookeeper-3.4.10]$ bin/zkServer.sh start [kris@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start [kris@hadoop103 zookeeper-3.4.10]$ bin/zkServer.sh start
2 Hadoop正常部署
Hadoop集群的正常部署并启动
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[kris@hadoop101 hadoop-2.7.2]$ sbin/start-dfs.sh [kris@hadoop102 hadoop-2.7.2]$ sbin/start-yarn.sh
3 HBase解压
解压HBase到指定目录
[kris@hadoop101 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module
4 HBase配置
修改HBase对应的配置文件
1)hbase-env.sh修改内容,声明jdk路径,并且hbase自带的zookeeper设置为false
export JAVA_HOME=/opt/module/jdk1.8.0_144 export HBASE_MANAGES_ZK=false
2)hbase-site.xml修改内容
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<configuration> <!-- Hbase在hadoop的存储路径 ,存储在/hbase的路径下 --> <property> <name>hbase.rootdir</name> <value>hdfs://hadoop101:9000/hbase</value> </property> <!-- 开启完全分布式 --> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <!-- Hbase的master端口号 0.98后的新变动,之前版本没有.port,默认端口为60000(可省略) --> <property> <name>hbase.master.port</name> <value>16000</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>hadoop101,hadoop102,hadoop103</value> </property> <!-- 具体hbase的存储路径, 参照zk的zoo.cfg文件中的dataDir值 --> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/opt/module/zookeeper-3.4.10/zkData</value> </property> <!-- Hbase关闭流的配置,(只适用于本地模式),完全分布式和伪分布式都得关闭 --> <property> <name>hbase.unsafe.stream.capability.enforce</name> <value>false</value> </property> </configuration>
说明:hbase.rootdir:这个目录是region server的共享目录,用来持久化Hbase 。
hbase.cluster.distributed :Hbase的运行模式。false是单机模式,true是分布式模式。若为false,Hbase和Zookeeper会运行在同一个JVM里面。
3)hbase/conf/regionservers
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
hadoop101
hadoop102
hadoop103
在conf创建一个文件名为backup-masters,并且在这文件里添加hadoop102的域名
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@hadoop101 hbase]# vim conf/backup-masters
hadoop102
4)软连接hadoop配置文件到HBase,core-site.xml、hdfs-site.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[kris@hadoop101 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml /opt/module/hbase/conf/core-site.xml [kris@hadoop101 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml /opt/module/hbase/conf/hdfs-site.xml
5 HBase发送到其他集群
[kris@hadoop101 module]$ xsync hbase/
并配置hbase环境变量
[root@hadoop101 module]# vim /etc/profile
#HBASE_HOME
export HBASE_HOME=/opt/module/hbase-2.2.4
export PATH=$PATH:$HBASE_HOME/bin
[root@hadoop101 module]# source /etc/profile
[root@hadoop102 module]# vim /etc/profile
#HBASE_HOME
export HBASE_HOME=/opt/module/hbase-2.2.4
export PATH=$PATH:$HBASE_HOME/bin
[root@hadoop102 module]# source /etc/profile
[root@hadoop103 module]# vim /etc/profile
#HBASE_HOME
export HBASE_HOME=/opt/module/hbase-2.2.4
export PATH=$PATH:$HBASE_HOME/bin
[root@hadoop103 module]# source /etc/profile
6 HBase服务启动
1)启动方式1
启动前确保时间是同步的;因为要hbase有version,所以要保证时间的一致性
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[kris@hadoop101 ~]$ date 2019年 03月 05日 星期二 09:24:52 CST [kris@hadoop102 module]$ date 2019年 03月 05日 星期二 09:24:52 CST [kris@hadoop103 ~]$ date 2019年 03月 05日 星期二 09:24:52 CST
[kris@hadoop101 hbase]$ bin/hbase-daemon.sh start master
[kris@hadoop101 hbase]$ bin/hbase-daemon.sh start regionserver
提示:如果集群之间的节点时间不同步,会导致regionserver无法启动,抛出ClockOutOfSyncException异常。
修复提示:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
a、同步时间服务 b、属性:hbase.master.maxclockskew设置更大的值 <property> <name>hbase.master.maxclockskew</name> <value>180000</value> <description>Time difference of regionserver from master</description> </property>
2)启动方式2
[kris@hadoop101 hbase]$ bin/start-hbase.sh
对应的停止服务:
[kris@hadoop101 hbase]$ bin/stop-hbase.sh
7 查看HBase页面
启动成功后,可以通过“host:port”的方式来访问HBase管理页面,例如:
http://hadoop101:16010
jar包冲突//启动时若出现hadoop和hbase下的jar包冲突,可删掉一个;不删也不影响运行 [kris@hadoop101 lib]$ rm -rf slf4j-log4j12-1.7.5.jar
2. HBase Shell操作
1)进入HBase客户端命令行
[kris@hadoop101 hbase]$ bin/hbase shell
2)查看帮助命令
hbase(main):001:0> help
hbase(main):001:0> help ‘create’
3)查看当前数据库中有哪些表
查看所有的数据库:list_namespace
查看某个数据库下的所有表:list_namespace_tables ‘库名’
查看所有表: list
namespace相关的操作
create_namespace 'my_ns'
drop_namespace 'my_ns'
alter_namespace 'my_ns', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}
建表| 增删改查
create 表名 , 列族中有若干列
create 'student', 'cf1'
desc 'student'
A. 对于不存在的表的添加方式: 创建预分区、SNAPPY压缩
表在刚刚被创建时,只有1个分区(region),当一个region过大(达到hbase.hregion.max.filesize属性中定义的阈值,默认10GB)时,
表将会进行split,分裂为2个分区。表在进行split的时候,会耗费大量的资源,频繁的分区对HBase的性能有巨大的影响。
HBase提供了预分区功能,即用户可以在创建表的时候对表按照一定的规则分区。 预分区:可以减少由于region split带来的资源消耗。从而提高HBase的性能。
create 'hopsonone:app_consume', {NAME => 'info', VERSIONS => 3, COMPRESSION => 'snappy'}, SPLITS => ['0','1','2','3','4','5','6','7','8','9']
查看HDFS可以看到这个表下有10个文件夹(如果没有预分区,则只有一个文件夹):
[easylife@pro-hadoop-1 log]$ hdfs dfs -ls /hbase/data/hopsonone/app_market_consume_come
Found 13 items
drwxr-xr-x - hbase hbase 0 2020-03-27 14:57 /hbase/data/hopsonone/app_consume/.tabledesc
drwxr-xr-x - hbase hbase 0 2020-03-27 14:57 /hbase/data/hopsonone/app_consume/.tmp
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/0230b601f6d7b1cf80eb450ae99841c2
drwxr-xr-x - hbase hbase 0 2020-04-02 01:49 /hbase/data/hopsonone/app_consume/1a6636a461659a1c14e2b6caeecac6a9
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/315bf71819cfaadb98534d0e95130e0c
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/369e86568b58bab19653be46683b5925
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/3d112a84fac43e60c94d810cb1317693
drwxr-xr-x - hbase hbase 0 2020-03-28 23:19 /hbase/data/hopsonone/app__consume/49f0086e1969321aa98c4199507f523f
drwxr-xr-x - hbase hbase 0 2020-04-11 02:10 /hbase/data/hopsonone/app_consume/6d3eb64750b1a8da3dd17bab96956f75
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/a65c10b465677fa2d180b201de75a3ee
drwxr-xr-x - hbase hbase 0 2020-03-31 01:45 /hbase/data/hopsonone/app_consume/b1a2bcabd627b6a3c896e76853309630
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/cec79ab63638a46d52123c0aea1a7a9a
drwxr-xr-x - hbase hbase 0 2020-03-27 14:55 /hbase/data/hopsonone/app_consume/ef28a8d3f5a3707962cfff73a9ac0548
手动分区:(一开始没有分区)
使用切分键 ‘1’ 一分为二:
hbase(main):002:0> split 'hopsonone:app_consume', 'splitKey'
hbase(main):003:0> split 'hopsonone:app_consume_','1'
继续将第二个Region进行切分,以’2’作为切分键:
hbase(main):005:0> split 'hopsonone:app_consume,1,1588043248742','2'
合并分区:
hbase(main):013:0> merge_region '847db2576ef2492b049c806fc46dcb47','7d084c88b65397304a18a7b982998c8d',true
B. 对于一个已经存在的表,修改其压缩方式,并对之前的旧数据生效的方式:
disable '表名'
alter '表名', {NAME => '列族名',VERSION => 3, COMPRESSION => 'snappy'} //注意修改压缩时必须一个列族一个列族的修改;
enable '表名'
这只是能让新数据使用SNAPPY压缩方式,如果旧数据也要采用压缩的话,需要执行
major_compact '表名' //不要在表繁忙期间执行此操作
执行完毕后可以去hdfs上验证压缩是否生效:
hadoop fs -du -s -h /hbase/data/default(namespace名称)/(表名)
如果你要删除压缩方式,步骤和上述步骤一致,唯一不一样的是:
alter '表名', NAME => '列族名', COMPRESSION => 'none'
C. TTL 用的少
create 't1', {NAME =>'f1', TTL => 180}, SPLITS => ['10', '20', '30', '40']
TTL=>的更新超时时间是指:该列最后更新的时间,到超时时间的限制,而不是第一次创建,到超时时间;
TTL的概念只针对CELL
增 put 'table', 'rowkey', 'cfName:filed', 'value' -- 隐式列rowkey
put 'default:student', '1001', 'cf1:name', 'alex'
put 'default:student', '1002', 'cf1:salary', '20000'
put 'default:student', '1002', 'cf1:hoby', 'java'
scan 'default:student'
改
put 'default:student', '1002', 'cf1:hoby', 'math'
查 scan 'table',{STARTROW => '', STOPROW => ''} | get 'table','rowkey' | get 'table', 'rowkey', 'cf:filed'
scan 'default:student', {STARTROW=>'1001', STOPROW=>'1001'}
scan 'default:student', {STARTROW=>'1001'}
scan 'default:student', {LIMIT => 5}
scan 'student', {STOPROW=>'1002'}
get 'student', '1000', 'cf1:name' get 'student', '1001', 'cf1:name'
删
删除数据:
delete 'student', '1001', 'cf1:name' //删除指定列的数据
deleteall 'student', '1001' //删除rowkey的全部数据
清空数据:
truncate 'default:student' //清空数据,包括表的预分区等
truncate_preserve 'default:student' //只清空数据,不清空表预分区;
删除表:
disable 'student'
drop 'student'
hbase(main):041:0> count 'student'
2 row(s) in 0.0230 seconds
=> 2
rowkey是根据自动字典排序的
快照
创建快照
snapshot 'one:tmp_cookie','snapshot_cookie'
hbase(main):010:0> list_snapshots 'snapshot_cookie'
SNAPSHOT TABLE + CREATION TIME
snapshot_cookie one:tmp_cookie (Tue Apr 28 14:25:01 +0800 2020)
1 row(s) in 0.0160 seconds
=> ["snapshot_cookie"]
hadoop fs -ls -R /hbase/.hbase-snapshot
drwxr-xr-x - hbase hbase 0 2020-04-28 14:25 /hbase/.hbase-snapshot/.tmp
drwxr-xr-x - hbase hbase 0 2020-04-28 14:25 /hbase/.hbase-snapshot/snapshot_cookie
-rw-r--r-- 3 hbase hbase 50 2020-04-28 14:25 /hbase/.hbase-snapshot/snapshot_cookie/.snapshotinfo
-rw-r--r-- 3 hbase hbase 737 2020-04-28 14:25 /hbase/.hbase-snapshot/snapshot_cookie/data.manifest
克隆快照:
hbase(main):015:0> clone_snapshot 'snapshot_cookie','one:clone_cookie'
0 row(s) in 0.7270 seconds
put 'hopsonone:tmp_cookie','20200620','info:pv','132'
恢复快照:
hbase(main):021:0> disable 'one:tmp_cookie'
0 row(s) in 2.3620 seconds
hbase(main):022:0> restore_snapshot 'snapshot_cookie'
0 row(s) in 0.7670 seconds
hbase(main):023:0> enable 'one:tmp_cookie'
0 row(s) in 2.2440 seconds
version版本,毫秒数时间戳即默认版本号,scan默认的是加载最新的版本号的数据;
RAW最原始数据;VERSION=>4是本次查询可以看到4个版本的值
它是没有真正的修改,只是在后边追加
flush由内存到hdfs,不是最新的就会丢弃
长整型longint,也可自定义 倒叙排列
hbase(main):013:0> create 'stu1', 'cf1', {NAME=>'cf2', VERSIONS=>3}
0 row(s) in 1.2800 seconds
=> Hbase::Table - stu1
hbase(main):014:0> desc 'stu1'
Table stu1 is ENABLED
stu1
COLUMN FAMILIES DESCRIPTION
{NAME => 'cf1', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENC
ODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536',
REPLICATION_SCOPE => '0'}
{NAME => 'cf2', BLOOMFILTER => 'ROW', VERSIONS => '3', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENC
ODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536',
REPLICATION_SCOPE => '0'}
2 row(s) in 0.0260 seconds
往里put数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
hbase(main):015:0> put 'stu1', '1001', 'cf1:name', 'alex1' 0 row(s) in 0.1060 seconds hbase(main):016:0> put 'stu1', '1001', 'cf1:name', 'alex2' 0 row(s) in 0.0090 seconds hbase(main):017:0> put 'stu1', '1001', 'cf1:name', 'alex3' 0 row(s) in 0.0050 seconds hbase(main):018:0> put 'stu1', '1001', 'cf1:name', 'alex4' 0 row(s) in 0.0060 seconds hbase(main):019:0> put 'stu1', '1001', 'cf1:name', 'alex5' 0 row(s) in 0.0050 seconds hbase(main):020:0> put 'stu1', '1001', 'cf2:name', 'kris1' 0 row(s) in 0.0090 seconds hbase(main):021:0> put 'stu1', '1001', 'cf2:name', 'kris2' 0 row(s) in 0.0110 seconds hbase(main):022:0> put 'stu1', '1001', 'cf2:name', 'kris3' 0 row(s) in 0.0060 seconds hbase(main):023:0> put 'stu1', '1001', 'cf2:name', 'kris4' 0 row(s) in 0.0060 seconds hbase(main):024:0> put 'stu1', '1001', 'cf2:name', 'kris5' 0 row(s) in 0.0060 seconds
hbase(main):025:0> scan 'stu1'
ROW COLUMN+CELL
1001 column=cf1:name, timestamp=1551780927829, value=alex5
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1 row(s) in 0.0140 seconds
hbase(main):027:0> scan 'stu1', {VERSIONS=>6, RAW=>true}
ROW COLUMN+CELL
1001 column=cf1:name, timestamp=1551780927829, value=alex5
1001 column=cf1:name, timestamp=1551780925379, value=alex4
1001 column=cf1:name, timestamp=1551780923004, value=alex3
1001 column=cf1:name, timestamp=1551780920152, value=alex2
1001 column=cf1:name, timestamp=1551780916196, value=alex1
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1001 column=cf2:name, timestamp=1551780982196, value=kris4
1001 column=cf2:name, timestamp=1551780979552, value=kris3
1001 column=cf2:name, timestamp=1551780977159, value=kris2
1001 column=cf2:name, timestamp=1551780972972, value=kris1
1 row(s) in 0.0240 seconds
hbase(main):028:0> flush 'stu1'
0 row(s) in 0.4880 seconds
hbase(main):029:0> scan 'stu1', {VERSIONS=>6, RAW=>true}
ROW COLUMN+CELL
1001 column=cf1:name, timestamp=1551780927829, value=alex5
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1001 column=cf2:name, timestamp=1551780982196, value=kris4
1001 column=cf2:name, timestamp=1551780979552, value=kris3
1 row(s) in 0.0390 seconds
墓碑数据
删除会把删掉的数据让他们成为墓碑
会新增一条最新的墓碑数据
会存到hdfs,但最终会被删除
hbase(main):038:0> put 'stu1', '1001', 'cf1:age', '22'
0 row(s) in 0.0430 seconds
hbase(main):040:0> put 'stu1', '1001', 'cf1:name', 'alex6'
0 row(s) in 0.0060 seconds
hbase(main):041:0> scan 'stu1', {VERSIONS=>6, RAW=>true}
ROW COLUMN+CELL
1001 column=cf1:age, timestamp=1551782031431, value=22
1001 column=cf1:name, timestamp=1551782055498, value=alex6
1001 column=cf1:name, timestamp=1551780927829, value=alex5
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1001 column=cf2:name, timestamp=1551780982196, value=kris4
1001 column=cf2:name, timestamp=1551780979552, value=kris3
1 row(s) in 0.0110 seconds
hbase(main):042:0> delete 'stu1', '1001', 'cf1:name'
0 row(s) in 0.0580 seconds
hbase(main):043:0> scan 'stu1'
ROW COLUMN+CELL
1001 column=cf1:age, timestamp=1551782031431, value=22
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1 row(s) in 0.0160 seconds
hbase(main):044:0> scan 'stu1', {VERSIONS=>6, RAW=>true}
ROW COLUMN+CELL
1001 column=cf1:age, timestamp=1551782031431, value=22
1001 column=cf1:name, timestamp=1551782116703, type=DeleteColumn
1001 column=cf1:name, timestamp=1551782055498, value=alex6
1001 column=cf1:name, timestamp=1551780927829, value=alex5
1001 column=cf2:name, timestamp=1551780984629, value=kris5
1001 column=cf2:name, timestamp=1551780982196, value=kris4
1001 column=cf2:name, timestamp=1551780979552, value=kris3
1 row(s) in 0.0170 seconds