Hbase 分布式数据库

一、Hbase 数据库概述;

概述:Hbase 是一个基于 HDFS 的面向列的分布式数据库,源于 Google 的 BigTable 基于 GFS 进行分布式数据存储一样,前文提到,Hbase 是基于流式数据访问,对于第时间延迟的数据 访问并不适合在 HDFS 上运行,所以需要实时性的随机访问超大规模的数据集,使用 Hbase 则是更好的选择;

 

作用:Hbase 作为典型的非关系型数据库,Nosql 数据库主要分为以下几类:

Ø 基于键值对存储的类型;

Ø 基于文档存储的类型;

Ø 基于列存储的类型;

Ø 基于图形数据存储的类型;

在 Nosql 领域中,Hbase 本身不是最优秀的,但得益于与 hadoop 的整合,为其带来了强大 的扩展空间。Hbase 本质只有插入操作,更新删除等操作都是通过插入操作来完成,这是由 于底层 HDFS 流式访问(一次写入,多次读取)决定的,每次插入数据时,数据会带有“时 间戳”的标记,形成多个版本,Hbase 对于一个数据会保留其固定的版本数量,如果在查询 时,也是显示出距离当前时间最近的一个新版本;

 

二、Hbase 体系结构; 体系结构:

Hbase 分布式数据库

 

 

架构分析:Hbase 体系结构由单个 HMaster 服务器和多个 HRegion Server 服务器组成,而所 有这些服务器是通过 ZooKeeper 来进行协调并处理各个服务器运行期间可能遇见的问题;

 

组件分析:

  • HStore多个 HStore 组成一个 HRegion,本身由两部分组成:Memstore 和 Storefile。首 先用户写入的数据存放到 Memstore 中,当 Memstore 满了后刷入 Storefile;

Ø HRegion由多个 HStore 组成,Hbase 使用表存储数据集,表由行和列组成,但与传统 关系型数据库不同的是,当表的大小超过设定的值时,Hbase 会自动将表划分为不同的 区域 HRegion(此操作也称之为 HRegion 分裂),它是 Hbase 集群上分布式存储和负载 均衡的最小单位,这一点和 HDFS 中文件与文件块存储的概念类似;

 

Hbase 分布式数据库

 

Ø Hlog存储数据日志,到达 HRegion 上的写操作首先被追加到日志中,然后才被加载到 Memstore,主要功能为故障修复,当某台 HRegionServer 发生故障,新的 HRegionServer 在加载 HRegion 的时候可以通过 Hlog 对数据进行恢复;

Ø HRegionServer由多个 HRegion 组成,在整个集群中可能存在多个节点,每个节点只能 运行一个 HRegionServer,负责对 HDFS 中读写数据和管理 HRegion 和 Hlog;

  • HMaster每台 HRegionServer 都会与 HMaster 进行通信,HMaster 的主要任务就是告诉 HRegionServer 它需要维护哪些 HRegion,具体功能如下: 1.管理用户对表的增删改查操作;

2.管理 HRegionServer 的负载均衡,动态调整 HRegion 分布;

3.在 HRegion 分裂后,负责新的 HRegion 的分配;

4.在 HRegionServer 停机后,负责失效 HRegionServer 上的 HRegion 的迁移;

Ø ZooKeeper存储的是 Hbase 中的 ROOT 表(根数据表)和 META 表(元数据表),元数 据表保存普通用户表的 HRegion 标识符信息,标识符格式为:表名+开始主键+唯一 ID。 随着 HRegion 的分裂,标识符信息也会发生变化,分成多个 HRegion 后,需要由一个根 数据表来贯穿多个元数据表;

此外,ZooKeeper 还负责 HRegionServer 故障时,通知 HMaster 进行 HRegion 迁移;若 HMaster 出现故障,ZooKeeper 负责恢复 HMaster,并且保证有且只有一个 HMaster 正 在运行;

Hbase 分布式数据库

 

 

  • Client客户端访问 Hbase 的单位,访问时,首先访问 Zookeeper--ROOT--META--table;

 

三、Hbase 数据库模型;

1.数据模型:

表(table):不存储值为 null 的数据,索引是行关键字、列关键字、时间戳; 行关键字(row key):行的主键,唯一标识一行数据;

列族(Colume Family):行中的列被分为“列族”,同一个列族的所有成员具有相同的列族 前缀,一个表的列族必须在创建表时预先定义,格式(列名:修饰符); 列关键字(Colume key):列键,格式为:<family>:<qualifer>,family 是列族名;qualifer 是 列族修饰符,表示列族中的一个成员;

存储单元格(Cell):在 Hbase 中,值作为一个单元保存在单元格中,要定位一个单元,需 要满足“行键+列键+时间戳”三个要素;

时间戳(Timestamp):插入单元格时的时间戳,默认作为单元格的版本号;

 

2.存储方式: 关系型数据库:

 

Hbase 分布式数据库

主键设置为 name 列,查找时根据学生名字可以很容易的实现查找,那么请思考以下问题;

Ø 如果现在新增加一门课程,如何在不改变表结构的情况下进行保存新课程的成绩呢?

Ø 如果 tom 同学数学成绩参加了补考,如何记录其同学的两次数学成绩?

Ø 如若 tom 同学数学没有成绩,那么表中值为 null,即使为空,也会占用存储空间;

 

HBase 数据库:

 

Hbase 分布式数据库

 

在不同时间插入不同数据时,会生成时间戳,并且在列族内生成数据记录; 在 HBase 数据库实际存储时,其表内空值不计入存储空间内;

 

四、总结 Hbase 整体特点:

HBase 就是这样一个基于列模式的映射数据库,它只能表示简单的键值的映射关系。与关系 型数据库相比,它有如下特点:

Ø 数据类型: HBase  只有简单的字符串类型,它只保存字符串。而关系型数据库有丰富 的类型选择和存储方式;

Ø 数据操作:HBase  只有简单的插入、查询、删除、清空等操作,表和表之间是分离的, 没有复杂的表和表之间的关系,所以不能、也没有必要实现表和表之间的关联操作。而 关系型数据库有多种连接操作;

Ø 存储模式:HBase   是基于列存储的,每个列族都由几个文件保存,不同列族的文件是分 离的。关系型数据库是基于表格结构和行模式存储的;

Ø 数据维护:HBase   的更新操作实际上是插入了新的数据,它的旧版本依然会保留,而不 是关系型数据库的替换修改;

Ø 可伸缩性:HBase 这类分布式数据库就是为了这个目的而开发出来的,所以它能够轻松 地增加或减少硬件数量,并且对错误的兼容性比较高。而关系型数据库通常需要增加中 间层才能实现类似的功能;

 

五、案例:搭建 Hbase 完全分布式数据库系统; 案例环境:

 

系统类型

IP 地址

主机名、角色

所需软件

Centos 7.4 1708 64bit

192.168.100.101

master hadoop:namenode hbase:HMaster

hadoop-2.7.6.tar.gz

jdk-8u171-linux-x64.tar.gz hbase-2.0.1-bin.tar.gz

Centos 7.4 1708 64bit

192.168.100.102

slave1 hadoop:datanode hbase:HRegionServer

hadoop-2.7.6.tar.gz

jdk-8u171-linux-x64.tar.gz hbase-2.0.1-bin.tar.gz

Centos 7.4 1708 64bit

192.168.100.103

slave2 hadoop:datanode hbase:HRegionServer

hadoop-2.7.6.tar.gz

jdk-8u171-linux-x64.tar.gz hbase-2.0.1-bin.tar.gz

 

版本对应:

Hbase 分布式数据库

 

 

 

下载位置:http://www.apache.org/index.html#projects-list

 

Hbase 部署环境: 单机模式:在单台主机运行 Hbase;

伪分布式模式:HBase 只在 hadoop 的 namenode 节点运行,与单机模式类似,只是其数据 文件可以存储在 datanode 节点上;

完全分布式模式:HBase 运行在 hadoop 集群的多个节点上,通常将 HMaster 运行在 namenode

节点上,将 HRegionServer 运行在 datanode 节点上;

 

案例步骤:

  • 搭建 Hadoop 分布式存储集群(namenode 和 datanode);
  • 在 master 节点安装部署 Hbase 程序;
  • 在 master 节点配置 HBase 程序;
  • 将 master 节点的 habse 程序复制到 slave 节点;

Ø 在 master 节点上开启 HBase 进程并查看进程;

Ø 验证 slave 节点上的进程状态;

Ø 访问网页,查看 HBase 运行状态;

 

Ø 在 master 节点登录 HBase 数据库,查看数据库状态;

Ø HBase 数据库中基本管理操作;

 

 

  • 搭建 Hadoop 分布式存储集群(namenode  datanode);

此处省略存储搭建

  •  master 节点安装部署 Hbase 程序; [[email protected] ~]# ls hbase-2.0.1-bin.tar.gz hbase-2.0.1-bin.tar.gz

[[email protected] ~]# tar zxvf hbase-2.0.1-bin.tar.gz [[email protected] ~]# mv hbase-2.0.1 /usr/local/hbase [[email protected] ~]# ls /usr/local/hbase

bin conf hbase-webapps lib NOTICE.txt RELEASENOTES.md CHANGES.md docs LEGAL LICENSE.txt README.txt

[[email protected] ~]# chown hadoop:hadoop /usr/local/hbase/ -R

 

  •  master 节点配置 HBase 程序;

[[email protected] ~]# su - hadoop

[[email protected] ~]$ vi /usr/local/hbase/conf/hbase-site.xml ##HBase  站点相关配 置文件

<configuration>

<property>

<name>hbase.rootdir</name>

<value>hdfs://master:9000/hbase</value>

<description>配置 HRegionServer 的数据库文件存放目录</description>

</property>

<property>

<name>hbase.cluster.distributed</name>

<value>true</value>

<description>配置 HBase 为完全分布式方式</description>

</property>

<property>

<name>hbase.master</name>

<value>master:60000</value>

<description>配置 HMaster 的地址和端口</description>

</property>

<property>

<name>hbase.zookeeper.quorum</name>

<value>master,slave1,slave2</value>

<description>配置 zookeeper 集群服务器的位置</description>

</property>

</configuration>

 

[[email protected] ~]$ vi /usr/local/hbase/conf/hbase-env.sh ##HBase   变 量 配

 

置文件

export JAVA_HOME=/usr/local/java

export HADOOP_HOME=/usr/local/hadoop export HBASE_HOME=/usr/local/hbase export HBASE_MANAGES_ZK=true

注解:export HBASE_MANAGES_ZK=true 此配置项意为开启 habse 内置的 zookeeper 进程,使

其随 HBase 进程一同启动;

 

[[email protected] ~]$ vi /usr/local/hbase/conf/regionservers ##HBase 的节点

slave1 slave2

 

  •  master 节点的 habse 程序复制到 slave 节点;

[[email protected] ~]# mkdir /usr/local/hbase

[[email protected] ~]# chown hadoop:hadoop /usr/local/hbase/

 

[[email protected] ~]# mkdir /usr/local/hbase

[[email protected] ~]# chown hadoop:hadoop /usr/local/hbase/

 

[[email protected] ~]$ scp -r /usr/local/hbase/* [email protected]:/usr/local/hbase [[email protected] ~]$ scp -r /usr/local/hbase/* [email protected]:/usr/local/hbase

 

Ø  master 节点上开启 HBase 进程并查看进程;

Hbase 分布式数据库

 

 

注解:如若启动 hbase 时,出现:错误:找不到或无法加载主类;

 由于 habse 版本与 hadoop 版本导致,或者环境变量导致;

 

Hbase 分布式数据库

 

Hbase 分布式数据库

 

Ø 验证 slave 节点上的进程状态;

 

Hbase 分布式数据库

Hbase 分布式数据库

 

 

Hbase 分布式数据库

 

 

Ø 访问网页,查看 HBase 运行状态;

http://192.168.100.101:16010

 

Hbase 分布式数据库

 

Hbase 分布式数据库

 

Ø  master 节点登录 HBase 数据库,查看数据库状态;

 

Hbase 分布式数据库

 

Ø  master 节点访问 hadoop 存储中数据,验证数据文件状态;

 

Hbase 分布式数据库

 

Ø HBase 数据库中基本管理操作;

[[email protected] ~]# /usr/local/hbase/bin/hbase shell hbase(main):001:0> status ##查看状态

1 active master, 0 backup masters, 2 servers, 0 dead, 1.0000 average load

Took 0.8818 seconds

hbase(main):002:0> create 'class','age','chengji' ##创建表,语法:create  表名 列族 列键

Created table class Took 1.5186 seconds

=> Hbase::Table - class

hbase(main):003:0> list ##查看所有表 TABLE

class

  1. row(s)

Took 0.0940 seconds

=> ["class"]

hbase(main):004:0> describe 'class' ##查看表的详细信息 Table class is ENABLED

class

COLUMN FAMILIES DESCRIPTION

{NAME => 'age', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR

=> 'f

alse', 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', PR

EFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '

65536'}

{NAME => 'chengji', 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'}

  1. row(s)

Took 0.1701 seconds

 

hbase(main):012:0> put 'class','tom','age','18' ##添加数据,语法:put    名 行键 列键 

Took 0.1784 seconds

hbase(main):013:0> put 'class','marry','age','20'

Took 0.0262 seconds

hbase(main):014:0> scan 'class' ##扫描 class 表中数据

ROW COLUMN+CELL

marry column=age:, timestamp=1535528846020, value=20

tom column=age:,  timestamp=1535528825217, value=18 2 row(s)

Took 0.0628 seconds

 

hbase(main):017:0> put 'class','tom','chengji:math','95' ##插入数据 Took 0.0217 seconds

hbase(main):018:0> put 'class','tom','chengji:english','90'

Took 0.0100 seconds

hbase(main):019:0> put 'class','marry','chengji:math','85'

Took 0.0130 seconds

hbase(main):020:0> put 'class','marry','chengji:english','90'

Took 0.0085 seconds hbase(main):021:0> scan 'class'

ROW COLUMN+CELL

marry column=age:, timestamp=1535528846020, value=20

marry column=chengji:english, timestamp=1535529132585, value=90

marry column=chengji:math,  timestamp=1535529119078, value=85

tom column=age:,  timestamp=1535528825217, value=18

tom column=chengji:english,  timestamp=1535529101465, value=90

tom column=chengji:math,  timestamp=1535529089638, value=95 2 row(s)

Took 0.0120 seconds

hbase(main):033:0>  scan 'class',{COLUMN=>'chengji:math',LIMIT=>1} ##根据条件查找,

 

显示一行

ROW COLUMN+CELL

marry column=age:, timestamp=1535528846020, value=20

marry column=chengji:english, timestamp=1535529132585, value=90

marry column=chengji:math,  timestamp=1535529119078, value=85 1 row(s)

Took 0.0456 seconds

 

hbase(main):038:0> get 'class','tom' ##获取表中数据,语法:get

表名 行键

COLUMN CELL

age: timestamp=1535528825217, value=18 chengji:english timestamp=1535529101465, value=90 chengji:math timestamp=1535529089638, value=95

1 row(s)

Took 0.0125 seconds

hbase(main):042:0> get 'class','tom',{COLUMN=>'age:'} ##根据条件获取表中数据, 语法:get  表名 行键 {COLUMN=>列族}

COLUMN CELL

age: timestamp=1535528825217, value=18 1 row(s)

Took 0.0188 seconds

hbase(main):043:0> get 'class','tom','age:' ##根据条件获取表中数据, 同上

COLUMN CELL

age: timestamp=1535528825217, value=18 1 row(s)

Took 0.0171 seconds

hbase(main):044:0> get 'class','tom','chengji:english' COLUMN CELL

chengji:english timestamp=1535529101465, value=90 1 row(s)

Took 0.0162 seconds

 

hbase(main):045:0> delete 'class','tom','chengji:english' ##删除表中数据记录,语法: delete  表名 行键 列键

Took 0.0367 seconds

hbase(main):046:0> get 'class','tom','chengji:english' ##获取表中数据记录,无法 获取

COLUMN CELL

0 row(s)

Took 0.0226 seconds

hbase(main):047:0> get 'class','tom' ##获取表中 tom 此行键的 所有内容

 

COLUMN CELL

age: timestamp=1535528825217, value=18

chengji:math timestamp=1535529089638, value=95 1 row(s)

Took 0.0106 seconds

 

hbase(main):048:0> disable 'class' ##删除表之前,需要先将表 关闭 disable

Took 0.8495 seconds

hbase(main):049:0> drop 'class' ##删除表 Took 0.4907 seconds

hbase(main):050:0> list ##查看所有表

TABLE

0 row(s)

Took 0.0086 seconds

=> []

hbase(main):051:0> exit