1.HBase概述

HBase 简介

定义

​ HBase 是一种分布式、可扩展、支持海量数据存储的 NoSQL 数据库。

​ HBase采用的是Key/Value的存储方式,这意味着,即使随着数据量增大,也几乎不会导致查询的性能下降

​ HBase又是一个列式数据库(对比于传统的行式数据库而言),当你的表字段很多的时候,你甚至可以把其中几个字段放在集群的一部分机器上,而另外几个字段放到另外一部分机器上,充分分散了负载压力。

​ 然而,如此复杂的存储结构和分布式的存储方式带来的代价就是:哪怕只是存储少量数据,它也不会很快。即:HBase并不快,只是当数据量很大的时候它慢的不明显

使用场景

当你的情况大体上符合以下任意一种的时候:

  • 主要需求是数据分析,比如做报表。
  • 单表数据量不超过千万。

请不要使用HBase,使用MySQL或者Oracle之类的产品可以让你的脑细胞免受折磨。

当你的情况是:

  • 单表数据量超千万,而且并发还挺高。
  • 数据分析需求较弱,或者不需要那么灵活或者实时。

请使用HBase,它不会让你失望的。

特点

1)海量存储

Hbase适合存储PB级别的海量数据,在PB级别的数据以及采用廉价PC存储的情况下,能在几十到百毫秒内返回数据。这与Hbase的极易扩展性息息相关。正式因为Hbase良好的扩展性,才为海量数据的存储提供了便利。

2)列式存储

这里的列式存储其实说的是列族存储,Hbase是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。

在hbase中列是数据,建表时可以不用指定列,只用指定它的列族

3)极易扩展

Hbase的扩展性主要体现在两个方面,一个是基于上层处理能力(RegionServer)的扩展,一个是基于存储的扩展(HDFS)

通过横向添加RegionSever的机器,进行水平扩展,提升Hbase上层的处理能力,提升Hbsae服务更多Region的能力,即提升业务能力

备注:RegionServer的作用是管理region、承接业务的访问。

4)高并发

由于目前大部分使用Hbase的架构,都是采用的廉价PC,因此单个IO的延迟其实并不小,一般在几十到上百ms之间。这里说的高并发,主要是在并发的情况下,Hbase的单个IO延迟下降并不多。能获得高并发、低延迟的服务。

5)稀疏

即hbase中存储的数据可以为空(注:mysql中只允许为null,null不等于空)

数据模型

​ 逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从 HBase 的底层物理存储结构(K-V)来看,HBase 更像是一个 multi-dimensional map

HBase 逻辑结构

1.HBase概述_第1张图片

这一张表划分成了两个列族和三个Region

HBase 物理存储结构

1.HBase概述_第2张图片

数据模型

**1)Name Space **
命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是 hbasedefault,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。

2)列族

​ 在HBase中,若干列可以组成列族(column family)。建表的时候是不需要制定列的,因为列是可变的,它非常灵活,唯一需要确定的就是列族。这就是为什么说一个表有几个列族是一开始就定好的。这一点做法跟以往的数据库有很大的区别。同一个表里的不同列族可以有完全不同的属性配置,但是同一个列族内的所有列都会有相同的属性,因为他们都在一个列族里面,而属性都是定义在列族上的。一个没有列族的表是没有意义的,因为列必须依赖列族而存在。在HBase中一个列的名称前面总是带着它所属的列族。列名称的规范是列族:列名,比如brother:age、brother:name、parent:age、parent:name。

列族存在的意义是:HBase会把相同列族的列尽量放在同一台机器上,所以说,如果想让某几个列被放到一起,你就给他们定义相同的列族。

​ 提示:一个表要设置多少个列族比较合适?

​ 官方的建议是:越少越好,因为HBase并不希望大家指定太多的列族。为什么?因为没有必要,虽然HBase是分布式数据库,但是数据在同一台物理机上依然会加速数据的查询过程。所以请根据实际需要来指定列族,列族太多会极大程度地降低数据库性能;而且根据目前的HBase实现,列族定得太多,容易出BUG。

3)Region

Region就是一段数据的集合。HBase中的表一般拥有一个到多个Region。Region有以下特性:

  • Region不能跨服务器,一个RegionServer上有一个或者多个Region。
  • 数据量小的时候,一个Region足以存储所有数据;但是,当数据量大的时候,HBase会拆分Region。
  • 当HBase在进行负载均衡的时候,也有可能会从一台RegionServer上把Region移动到另一台RegionServer上。
  • Region是基于HDFS的,它的所有数据存取操作都是调用了HDFS的客户端接口来实现的。

4)Rowkey

​ 行键(rowkey)完全是由用户指定的一串不重复的字符串,规则随你定!不过,话虽如此,你定的rowkey可是会直接决定这个row的存储位置的。HBase中无法根据某个column来排序,系统永远是根据rowkey来排序的。因此,rowkey就是决定row存储顺序的唯一凭证。而这个排序也很简单:根据字典排序。

比如,以下三个rowkey:

row-1
row-2
row-11

根据字典排序结果:

row-1
row-11
row-2

​ 如果你插入HBase的时候,不小心用了之前已经存在的rowkey,那你就会把之前存在的那个row更新掉。

之前已经存在的值,会被放到这个单元格的历史记录里面,并不会丢掉,只是你需要带上版本参数才可以找到这个值。(这就是列的版本的使用了)

**5)Column **
HBase 中的每个列都由 Column Family(列族) Column Qualifier(列限定符)进行限定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。

6)Cell

​ 由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存贮。一个列上可以存储多个版本的单元格。单元格就是数据存储的最小单元。

7)Time Stamp

​ 用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。

HBase 基本架构

​ 一般一个HBase集群有一个Master服务器和几个RegionServer服务器。Master服务器负责维护表结构信息,实际的数据都存储在RegionServer服务器上。HBase有一点很特殊:客户端获取数据由客户端直连RegionServer的,所以你会发现Master挂掉之后你依然可以查询数据,但就是不能新建表了。

1.HBase概述_第3张图片

​ RegionServer是直接负责存储数据的服务器。RegionServer保存的表数据直接存储在Hadoop的HDFS上

1.HBase概述_第4张图片

​ RegionServer非常依赖ZooKeeper服务,可以说没有ZooKeeper就没有HBase。ZooKeeper在HBase中扮演的角色类似一个管家。ZooKeeper管理了HBase所有RegionServer的信息,包括具体的数据段存放在哪个RegionServer上。

客户端每次与HBase连接,其实都是先与ZooKeeper通信,查询出哪个RegionServer需要连接,然后再连接RegionServer。

1.HBase概述_第5张图片

**架构角色:
1)Region Server **
Region Server 为 Region 的管理者,其实现类为 HRegionServer,直观上说就是服务器上的一个服务。一般来说,一个服务器只会安装一个RegionServer服务,不过你在一个服务器上装多个RegionServer服务也不是不可以。当客户端从ZooKeeper获取RegionServer的地址后,它会直接从RegionServer获取数据。

​ 主要作用如下:

  • ​ 对于数据的操作:get, put, delete;
  • ​ 对于 Region 的操作:splitRegion、compactRegion。

**2)Master **

​ Master 是所有 Region Server 的管理者,其实现类为 HMaster。

​ 在HBase中Master的角色不像领导,更像是打杂的。客户端从 ZooKeeper获取了RegionServer的地址后,会直接从RegionServer获取数据。其实不光是获取数据,包括插入、删除等所有的数据操作都是直接操作RegionServer,而不需要经过Master。

Master只负责各种协调工作,比如建表、删表、移动Region、合并等操作。它们的共性就是需要跨RegionServer,这些操作由哪个RegionServer来执行都不合适,所以HBase就将这些操作放到了Master上了。

​ 这种结构的好处是大大降低了集群对Master的依赖。而Master节点一般只有一个到两个,一旦宕机,如果集群对Master的依赖度很大,那么就会产生单点故障问题。在HBase中,即使Master宕机了,集群依然可以正常地运行,依然可以存储和删除数据。

​ 主要作用如下:

  • 对于表的操作:create, delete, alter
  • 对于 RegionServer的操作:分配 regions到每个RegionServer,监控每个 RegionServer的状态,负载均衡和故障转移。

**3)Zookeeper **
HBase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:

​ 当客户端需要查询数据时,先找到zk,从里面的元数据得知数据的具体位置,然后再去找到这个数据,类似于hdfs里面的namenode

​ 通过Zoopkeeper来保证集群中只有1个master在运行,如果master异常,会通过竞争机制产生新的master提供服务

​ 通过Zoopkeeper来监控RegionServer的状态,当RegionSevrer有异常的时候,通过回调的形式通知Master RegionServer上下线的信息

​ 通过Zoopkeeper存储元数据的统一入口地址

**4)HDFS **
HDFS 为 HBase 提供最终的底层数据存储服务,同时为 HBase 提供高可用的支持。具体功能概括如下:

​ 提供元数据和表数据的底层分布式存储服务

​ 数据多副本,保证的高可靠和高可用性

HBase 快速入门

HBase 安装部署

Zookeeper 正常部署

首先保证 Zookeeper 集群的正常部署,并启动之:

[root@h1 app]# zkServer.sh start
[root@h2 app]# zkServer.sh start
[root@h3 app]# zkServer.sh start

Hadoop 正常部署

Hadoop 集群的正常部署并启动:

[root@h1 hadoop-2.7.7]# sbin/start-all.sh

HBase 的解压

解压 Hbase 到指定目录:

[root@h1 download]# tar -zxvf hbase-1.3.1-bin.tar.gz -C /root/app

重命名

[root@h1 app]# mv hbase-1.3.1/ hbase

HBase 的配置文件

修改 HBase 对应的配置文件。
1)hbase-env.sh 修改内容:

export JAVA_HOME=/root/app/jdk1.8.0_201
export HBASE_MANAGES_ZK=false

并将以下两行注释掉

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m"

2)hbase-site.xml 修改内容:


	
		hbase.rootdir
		hdfs://h1:9000/HBase
	
	
	
		hbase.cluster.distributed
		true
	
 
	
	
		hbase.master.port
		16000
	
	
	 
		hbase.zookeeper.quorum
		h1,h2,h3
	
	
	 
		hbase.zookeeper.property.dataDir 
		/root/app/zookeeper/data
	

3)regionservers:

h1
h2
h3

4)软连接 hadoop 配置文件到 HBase:

[root@h1 conf]# ln -s /root/app/hadoop-2.7.7/etc/hadoop/core-site.xml /root/app/hbase/conf/core-site.xml
[root@h1 conf]# ln -s /root/app/hadoop-2.7.7/etc/hadoop/hdfs-site.xml /root/app/hbase/conf/hdfs-site.xml

HBase 服务的启动

**1.启动方式 **

[root@h1 hbase]# bin/hbase-daemon.sh start master
[root@h1 hbase]# bin/hbase-daemon.sh start regionserver

注:master只用在h1启动就好了,regionserver需要在三台都启动

提示:如果集群之间的节点时间不同步,会导致 regionserver 无法启动,抛出
ClockOutOfSyncException 异常。

修复提示:
a、同步时间服务

b、属性:hbase.master.maxclockskew 设置更大的值


hbase.master.maxclockskew
180000
Time difference of regionserver from master

**2.启动方式 2 **

[root@h1 hbase]# bin/start-hbase.sh

对应的停止服务:

[root@h1 hbase]# bin/stop-hbase.sh

查看 HBase 页面

启动成功后,可以通过“host:port”的方式来访问 HBase 管理页面,例如:
http://192.168.48.101:16010

1.HBase概述_第6张图片

HBase Shell操作

基本操作

1.进入 HBase 客户端命令行

[root@h1 hbase]# bin/hbase shell

2.查看帮助命令

hbase(main):001:0> help

3.查看当前数据库中有哪些表

hbase(main):002:0> list

表的操作

注:HBase中不能直接用delete,删除数据的话是ctrl+delete(有点反人类哈)

1.创建表

hbase(main):001:0> create 'student','info' 

这句话的意思是建立一个叫student的表,这个表里面有一个列族,这个列族叫info。我们之前说过:

  • HBase的表都是由列族(Column Family)组成的。
  • 没有列族的表是没有意义的。
  • 列并不是依附于表上,而是依附于列族上。

所以HBase的表跟列之间的关系中间还有一层:列族

1.HBase概述_第7张图片

我的表属性要定义在哪里

它们都定义在列族上。HBase的所有数据属性都是定义在列族上的。同一个表的不同列族可以定义完全不同的两套属性,所以从这个意义上来说,列族更像是传统关系数据库中的表,而表本身反倒变成只是存放列族的空壳了。

2.插入数据到表

hbase中没有什么类型之分,只有byte数组

hbase(main):002:0> put 'student','1001','info:sex','male' 
hbase(main):003:0> put 'student','1001','info:age','18' 
hbase(main):004:0> put 'student','1002','info:name','Janna' 
hbase(main):005:0> put 'student','1002','info:sex','female' 
hbase(main):006:0> put 'student','1002','info:age','20' 

1.HBase概述_第8张图片

3.用scan来查看表数据

hbase(main):007:0> scan 'student' 
hbase(main):009:0> scan 'student',{STARTROW => '1001', STOPROW  => '1001'} 
hbase(main):010:0> scan 'student',{STARTROW => '1001'} 

1.HBase概述_第9张图片

1.HBase概述_第10张图片

注:STOPROW或者用ENDROW都可以用于表示结束行,随便用哪个都可以

4.查看表属性

hbase(main):011:0> describe 'student' 

1.HBase概述_第11张图片

NAME这个属性表示的是列族的名称,而不是表的名称,而且后面的所有属性都是针对列族的而不是针对表的。

5.增加一个列族

alter 'student','info2' 

1.HBase概述_第12张图片

可以看到现在describe输出的是两个元素,分别对应info和info2两个列族。

6.用put命令来插入数据

hbase(main):012:0> put 'student','1001','info:name','Nick' 
hbase(main):013:0> put 'student','1001','info:age','100' 

第一条语句的意思就是:

  • 往student表插入一个单元格。
  • 这个单元格的rowkey为1001,也就是说它是属于1001这个行中的一个列。
  • 该单元格的列族为info。
  • 该单元格的列名为name。
  • 数据值为Nick。

7.用get来获取单元格数据

hbase(main):012:0> get 'student','1001' 
hbase(main):013:0> get 'student','1002','info:name' 

1.HBase概述_第13张图片

我们可以看到这里的时间戳属性。每一个单元格都可以存储多个版本(version)的值。HBase的单元格并没有version这个属性,它用timestamp来存储该条记录的时间戳,这个时间戳就用来当版本号使用。如果你在写put语句的时候不指定时间戳,系统就会自动用当前时间帮你指定它。指定的方式就是就直接在语句的末尾加上时间戳就行,例

put 'student','1001','info:name','Nick',2222222222222

这个时间戳指定的时间明显比上前时间晚,因此它会覆盖掉我们之前插入的内容,但是之前的内容并没有丢,我们可以通过指定版本号来查看之前的内容

get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3} 

我们发现在get或者scan的输出结果中,HBase并没有专门的一个列族的栏来显示列族这个属性。它总是把列族和列用“列族:列”的组合方式来一起显示,无论是put存储还是scan的查询使用的列定义,都是“列族:列”的格式。比如,info:name表示列族为info,列为name。

8.统计表数据行数

hbase(main):014:0> count 'student' 

9.用delete来删除数据

删除某rowkey的全部数据:

hbase(main):016:0> deleteall 'student','1001' 

删除某rowkey的某一列数据:

hbase(main):017:0> delete 'student','1002','info:sex' 

删除某rowkey的某一列中版本为2的数据:

hbase(main):018:0> delete 'student','1002','info:sex',2 

HBase删除记录并不是真的删除了数据,而是放置了一个墓碑标记(tombstone marker),把这个版本连同之前的版本都标记为不可见了。。这是为了性能着想,这样HBase就可以定期去清理这些已经被删除的记录,而不用每次都进行删除操作。

被打上墓碑标记(tombstone marker)的记录还可以被查询到

在记录被真正删除之前还是可以查询到的,只需要在scan命令后跟上RAW=>true参数和适当的VERSIONS参数就可以看到。

1.HBase概述_第14张图片

被标定为DeleteColumn的列就是被打上墓碑标记的记录。

10.清空表数据

hbase(main):019:0> truncate 'student' 

提示:清空表的操作顺序为先disable,然后再truncate。

11.删除表

首先需要先让该表为disable状态:

hbase(main):020:0> disable 'student' 

然后才能drop这个表:

hbase(main):021:0> drop 'student' 

提示:如果直接drop表,会报错:ERROR: Table student is enabled. Disable it first.

12.变更表信息

将info列族中的数据存放3个版本:

hbase(main):022:0> alter 'student',{NAME=>'info',VERSIONS=>3} 
hbase(main):023:0> get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3} 

你可能感兴趣的:(HBase)