HBase基础01+Phoenix

HBase的介绍


HBase的背景

  • Hadoop仅适合存储大批量的数据,进行顺序化读写,并不支持随机的读取数据操作

HBase的特点

1)他是用java写的Nosql型数据库,基于HDFS,是一个支持高效随机读写能力的Nosql型数据库

2)HBASE支持三种查询方式:
    1- 支持主键查询
    2- 支持主键范围查询
    3- 支持全表查询

3)他的本质是存储数据的容器,数据是存储在HDFS文件上的,不支持join,多行事务,和sql语句的查询,仅支持单行事务,存储格式为字节

4)可以通过横向拓展的,就像Hadoop集群一样

HBase表的特点

1)大:可存储海量的数据,存储十亿行数据,上百万列
2)面向列:数据是面向与列(列族)的形式的存储方案
3)稀疏性:在HBASE中的表存储数据,如如果一个字段为null,并不会     占用磁盘的空间,所以表结构可以非常稀疏 

HBase和其他软件的对比

1)HBase和RDBMS:
    1- HBASE是以表的形式存储数据,不支持join,仅支持单行事务,采用分布式存储,主要存储半结构化数据和结构化数据
    2- RDBMS也是以表的形式存储,支持join和sql语句查询,支持多行事务,采用中心化存储,主要存储结构化数据

2)HBase和HDFS:
    1- HBASE强依赖于HDFS,数据最终存储在HDFS中,支持高效的随机读写操作
    2- HDFS是分布式的存储容器,适合于批量化的数据存储,不支持随机读写的能力


3)HBase和hive
     1- HBase:基于Hadoop的软件, 是NoSQL存储容器, 延迟较低, 接入在线业务.
	 2- Hive:基于Hadoop的软件, 数仓分析工具, 延迟较高, 接入离线业务, 用于OLAP操作.

HBase的应用场景

  • 存储海量的数据
  • 表结构设计比较稀疏
  • 需要高效的随机读写

HBASE的启动步骤

#先启动zookeeper集群
cd /export/server/zookeeper/bin
./zkServer.sh start

#查看进程状态
./zkServer.sh status

#再启动Hadoop集群
start-all.sh

#然后启动HBASE集群
start-hbase.sh

#进入hbase的命令行,查看运行状态
hbase shell
输入status

#web端查看
http://node1:16010/master-status

HBASE的数据模型


HBase数据模型的介绍
HBase基础01+Phoenix

1)HBASE是采用表的方式存储数据的,数据也是通过表的形式组织在一起的,hbase可以组建多张表

2)行键(rowkey):类似于RDBMS中的主键,保证唯一非空

3)列名包括两部分
    1- 列族:在一个表中可以构建多个列族,每个列族下可以有多个列,最多支持上百万个列(建表时列族越少越好)
    2- 列限定符:也称为列名,一个列名必然属于一个列族,列名在建表的时候不需要指定

4)时间戳:每一个数据都有时间戳的概念,默认为添加数据的时间

5)版本号:是否需要保留每个数据的历史变更信息,以及保留多少个,默认是一个

6)一个单元格 = 行键 + 列族 + 列限定符 + 列值

HBase的相关操作


shell操作HBase

#查看hbase的命令使用
help ‘命令名’

#查看集群得状态信息
status

#查看hbase中有哪些表
list

#展示表结构信息
describe

#检查表是否存在, 适用于表量特别多的情况				
exists					

#检查表是否启用或禁用		
is_enabled, is_disabled	

#该命令可以改变表和列族的模式
alter		

使用shell命令建表查询

#创建一张表user
create 'user', 'info', 'data'

#创建一张表user02,并指定版本号
create 'user02', {NAME => 'info01', VERSIONS => '3'}, {NAME => 'data01'}

#如何向表中添加数据
put 'user', 'rk001', 'info:name', 'zhangsna'

#向user表中插入信息, row key为rk001, 列族info中添加gender列标示符, 值为female
put 'user', 'rk001', 'info:gender', 'female'

--------------------------------------------------

#查询数据的操作
get 'user', 'rk001'

#查询info列族中的数据
get 'user', 'rk002', 'info'

#查看列族中的具体那个列名的信息
get 'user', 'rk002', 'info:name', 'info:age'

#查看列族中的具体那个列族的信息
get 'user', 'rk0001', 'info', 'data'

#查看表中rk001行键中是否有zhangsan的值
get 'user', 'rk001', {FILTER => "ValueFilter(=, 'binary:zhangsan')"}
--------------------------------------------------

#查询user表中的所有信息
scan 'user'

#FORMATTER => 'toString': 表示用于显示中文
scan 'user', {FORMATTER => 'toString'}   

#limit: 表示显示前N条数据.
scan 'user', {LIMIT => 3, FORMATTER => 'toString'}

#列族查询: 查询user表中列族为info的信息.
scan 'user', {COLUMNS => 'info'}

scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 5}

scan 'user', {COLUMNS => 'info', RAW => true, VERSIONS => 3}


----------------------------------------------
#指定多个列族与按照数据值模糊查询, 即: 查询user表中列族为info和data且列标示符中含有a字符的信息.
scan 'user', {COLUMNS => ['info', 'data'], FILTER => "QualifierFilter(=, 'substring:a')"}

#rowkey的范围值查询, 即: 查询user表中列族为info, rk的范围是[rk0001, rk0003)的数据
scan 'user', {COLUMNS => 'info', STARTROW => 'rk0001', ENDROW => 'rk0003'}

#指定rowkey模糊查询, 即: 查询user表中rowkey以rk字符开头的数据.
scan 'user', {FILTER => "PrefixFilter('rk')"}

#指定数据范围值查询, 即: 查询user表中指定范围的数据
scan 'user', {TIMERANGE => [1392368783980, 1392380169185]}

更新数据操作

#更新数据值, 注意: 更新操作同插入操作一模一样, 只不过有数据就更新, 没有数据就添加.
put 'user', 'rk0001', 'info:name', '张三'

#更新版本号, 即: 将user表的f1列族版本号改为5
alter 'user', NAME => 'info', VERSIONS => 5

删除操作

#删除一个列族
alter 'user', 'delete' => 'info'
	
#清空表数据
truncate 'user'
	
#首先需要先让该表为 disable 状态,再删除表
disable 'user'	
drop 'user'			
	
统计一张表有多少行数据
count 'user'

hbase的过滤操作

格式:
scan '表名', {FILTER => "过滤器(比较运算符, '比较器表达式')"}
过滤器的查询地址:
http://hbase.apache.org/2.2/devapidocs/index.html

HBase中常用的过滤器:
rowkey过滤器:
RowFilter			
实现行键字符串的比较和过滤
PrefixFilter		
rowkey前缀过滤器

列族过滤器:
FamilyFilter		
			
列名过滤器:
QualifierFilter 	
列标示符过滤器, 只显示对应列名的数据

列值过滤器:
ValueFilter 		
值过滤器, 找到符合值条件的键值对
SingleColumnValueFilter			
在指定的列族和列中进行比较的值过滤器
SingleColumnValueExcludeFilter	

#在指定的列族和列中进行比较的值过滤器(排除匹配成功的值)
其他过滤器:
PageFilter	
#用于实现分页查询的操作
比较运算符:
>, >=, <, <=, =, !=

比较器:
BinaryComparator		//匹配完整字节数组
BinaryPrefixComparator	//匹配字节数组前缀
NullComparator			//匹配空值
SubstringComparator		//模糊(包含)匹配子字符串

比较器表达式(比较器的使用方式):
BinaryComparator	binary:值
BinaryPrefixComparator	binaryprefix:值
NullComparator	null
SubstringComparator	substring:值

hbase的架构


整体架构
HBase基础01+Phoenix

  • hbase架构说明
1)HMaster的作用:(主节点)
    1- 他是HBase集群的主节点
    2- 管理多有的HRegionServer
    3- 负责分配所有的Region
    4- 负责Region的负载均衡
    5- 负责维护和更新元数据

2)HRegionServer的作用:(从节点)
     1- 负责接收和管理HMaster分配的Region
     2- 负责和HMaster的通信(心跳机制)
     3- 负责数据的读写操作

3)细节:
    1- 1个HRegionServer是由1个HLog文件和多个Region组成
    2- 一个Region是由多个Store组成,一个Region管理一个大的HFile的文件
    3- 1个Store由多个StoreFile和1个MemStore(内存)组成

hbase的读取流程
HBase基础01+Phoenix
①客户端发起请求,例如:get ‘user’,‘rk001’,‘info’, 通过该zookeeper连接到master

②获取到hbase:meta的存储原数据的regionserver(从节点)信息,返回给客户端

③客户端根据元数据的信息,连接需要存有读取信息的regionserver

④先从mestore中读取数据

⑤如果mestore中没有数据的话,再从blockcache中读取数据

⑥如果还是没有需要的数据就去hfile中读取


读取顺序为: mestore(一级缓存)→blockcache(二级缓存)→hfile
上述的读取数据的方式为 并行的,例如每个RS节点中都有需要的数据 则进行并行读取

hbase的写入流程
HBase基础01+Phoenix
①客户端发起请求,例如:put ‘user’。。。。

②通过连接zookeeper连接到HMaster,读取存储元数据表的RS信息

③通过读取到的元数据信息,连接到存储元数据表的RS,并获取存储,具体要被写入到那个RS中

④客户端把数据写入到HLog的文件中(预写日志文件,可以做故障恢复)

⑤客户端再把数据写入到Memstore文件中,如果这两个地方都写入成功则客户端认为数据写入成功

--------------------以上是客户端的写入操作-------------------------

--------------------以下是服务端的写入操作------------------------

⑥当Memstore中的数据达到一定的阈值(128M或者1小时),就会触发flush机制,将数据刷出到storefile中

⑦在数据被刷出到storefile中之前,可能会遇到 in-memory(内存合并)机制(这个机制是hbase2.0以后的新特性),默认是关闭的需要进行手动设置,他的目的是减少storefile文件的数量,让数据尽可能的晚的刷出到storefile文件中

⑧当storefile文件达到一定的阈值(3个或3个以上),就会触发compact机制,将他们合并到一个大的hfile文件中

⑨当hfile文件达到一定的阈值(最大10GB)后就会触发spilt机制,对一个大的hfile文件进行切割,获取到两个HFile文件,此时就会有两个新的Region了,旧的Region将会下线,产生两个新的Region将会被HMaster根据负载均衡机制,分配到指点的RS从节点中来维护

region和store的关系

HBase基础01+Phoenix

  • 说明
1)Region的解释:
    1- 所谓的Region就是对HBase表的横向切分
    2- 默认一张hbase表只有一个Region,当该表的总容量达到10GB时,将开启split机制,将该表的文件(也就是HFlie文件)一分为二
    3- 后去我们通过创建预分区表的方式,直接指定HFlie的个数

2)Store的解释:
    1- 所谓的store是对hbase的纵向(垂直)切分
    2- 默认情况下,一个列族对应一个store
    3- 列族在数设计得时候越少越好,因为一个列族应对应一个store,当列族过多的时候,可能出现多个列组分布在不同的RS(子节点)中存储,读写时影响效率

hbase的三大机制

flush机制
HBase基础01+Phoenix

  • 说明
1)目的:把Memstore中的数据刷出到storefile文件中
  (阈值:128M-region级别, 1小时- regionserver级别)

2)hbase2.X以前:
   1- 当Memstore达到阈值以后,会触发flush机制,该Memstore会被禁用掉(可读不可写),然后创建一个新的Memstore(可读可写)
   2- 被禁用的Mestore中的数据写出到一个队列中
   3- 队列中的一个Memstore完整的数据将对应一个storefile文件(即,一个Memstore对应一个storefile文件,容易导致storefile文件过多)

3)在hbase2.X以后:
   1- 当Memstore达到一定的阈值后,会触发flush机制,该Memstore将会被禁用(可读不可写),然后创建一个新的Memstore(可读可写)
   2- 旧的Memstore得数据会被放到一个消息队列中(pipeline),该队列采用segment(可以理解为索引)来记录数据,会尽可能晚的将Memstore刷出到storefile中,减少storefile文件的个数
   

1)上述所描述的就是hbase2.X的新特性,叫 in-memory(内存合并)他就是用pipeline对列中的Memstore数据进行合并的,默认该特性是被关闭的,需要手动设置)
 2)合并有3中方式:
     1- Basic(基础型):只对数据进行和并排序,不会删除重复的数据和过期的版本数据
     2- Eager(饥渴型):对数据进行合并排序,也会删除重复的数据和过期的数据
     3- Adaptive(适应型):满足条件下会自动启用,Eager,否则就Basic

compact机制
HBase基础01+Phoenix

  • 说明
1)目的:将多个storefile文件合并到一个大的hfile文件中
    (阈值:storefile文件的个数达到3个或三个以上,又或者hbase集群刚启动的时候)

2)主要分为两个阶段:
   1- minor:负责把多个storefile文件合并成一个大的storefile文件
   2- major:负责把大的storefile文件和hfile文件做合并(阈值7天或者手动)
   

split机制
HBase基础01+Phoenix

-说明

1)目的:对hfile文件进行切割,将其变成两个hfile文件,对应的region也会一分为二

    阈值:最终:10GB
         公式:min(region的平方 * 128MB, 10GB)

2)当启动spilt机制后,大的10GB文件hfile文件,会分为两个,这时也就会产生两个region,旧的hfile对应的region会被下线,新的两个region将会被master根据负载均衡被随机分配到指定的RS从节点进行管理

HRegionServer的上下线问题


HBase基础01+Phoenix

  • 说明
HMaster如何管理Regionserver的?

1)一个region只能被一个Regionserver管理
2)HMaster会根据记录的元数据,以及各个RS汇报的region信息,计算出那些Region被谁管理,那些Region还没有别分配
3)那些没有被分配的Region就会被HMaster根据负载均衡机制,找一个相对比较空闲的RS,给他分配一个装载任务,这样Region就会被RS管理了
--------------------------------------------

当Regionserver上线或者下线之后,做了那些事情?

1)其实就是ZK的发布和订阅功能,所有的RS启动后都会去ZK的RS节点下创建自己的临时节点
2)当某一个RS宕机之后,他的临时节点就会消失,从而被HMaster监听到
3)HMaster会将该RS管理得所有的Region,根据负责均衡机制分配给其他的RS进行管理
4)当RS重新启动后,还会去zk的rs节点下创建自己的临时节点,从而被HMaster监听到,此时HMaster还会从其他的RS从节点中转移一些Region来给刚启动的Region

HMaster的上下线问题


HBase基础01+Phoenix

  • 说明
1)所有的HMaster都要去ZK中去创建自己的临时节点
2)当hbase集群刚启动的时候,所有的HMaster都会抢占式的去ZK的master节点下,创建自己的临时节点,那个HMaster先创建成功,他就是Active
3)其他的HMaster就去backup-master 节点下创建自己的临时节点,他们的状态就是standby
4)所有的standbymaster的状态都会实时监听ZK的ACtive节点,如果发现宕机,立即抢占Active节点

BulkLoad批量装载


HBase基础01+Phoenix

hive和hbase集成


  • 说明
1)hive和hbase的数据都是存储在hdfs中的,为了不让数据重复存储而占用大量的磁盘空间,我们将hive和hbase进行集成

hbase表结构的设计


hbase表的名称空间

  • 说明:hbase的名称空间类似于mysql的数据库名称,hbase的默认名称空间是default
#创建命名空间
create_namespace

#查看命名空间
list_namespace

#查看命名空间结构
describe_namespace

#删除命名空间(在没有表的情况下)
drop_namespasce

hbase表的列族的设计

1)列族的数量越少越好,减少中间I/O的开销
2)列族的名设计越小越好,防止占用空间
3)一个表中的列族一般设计不超过5个

hbase中的压缩
HBase基础01+Phoenix

1)压缩比:
见上图
2)解压缩效率(解压速度和压缩速度):
见上图
-------------------------------------------
1)建表时如何指定压缩的格式
create '表名', {NAME => '列族名', COMPRESSION => 'GZ'}
2)修改已有的表压缩的格式
alter '表名', {NAME => '烈族名', COMPRESSION => 'GZ'}

hbase的预分区

  • 说明
    是指在初始化创建表的时候,提前预先设置多个region到hbase中,而多个region可以均匀的落在各个regionserver中,从而分担高并发的读写操作
#如何设计预分区
create '表名', '列族',SPLITS => ['10', '20', '30', '40']

create '表名', '列族', {NUMREGIONS => 10, SPLITALGO => 'HexStringSplit' }

hbase中rowkey的设计原则

1)尽量不要使用递增的时序数据
2)避免rowkey和列的长度过大,否则会占用较大的空间
3)使用了Long等类型比String类型更加节省空间
4)保证rowkey的唯一性
5)避免出现热点数据,也就是数据集中在一个region中(可采用对行键进行反转和加盐的策略和哈希策略)

hbase的协处理器


observer的图解
HBase基础01+Phoenix
endpoint的图解
HBase基础01+Phoenix

  • 协处理器主要分为两类:
1)observer
   1-类似于监听者的作用,当put到Memstore中数据时,observer协处理器会有hook(钩子)钩取操作命令,到HLog中。

2)endpoint
   1-endpoint类似于函数的这类协处理器,他会将每个storefile中的数据在服务端先进行处理合并,减少客户端拉取数据的量,从而提高效率

Phoenix的介绍


  • Phoenix的快速入门
    Phoenix可以通过SQL的方式来操作hbase的工具,只不过Phoenix针对hbase做了更深的优化操作,底层大量利用了hbase的协处理器
#启动Phoenix的命令
cd /export/server/Phoenix/bin
sqlline.py node1:2181

#表的创建
create table  "order_dtl_01" (
		   "id"  varchar primary key,
		   "c1"."status" varchar ,
		   "c1".money  integer ,
		   c1."pay_way" integer ,
		   c1.user_id varchar,
		   c1.operation varchar,
		   c1.category varchar 
		);

#表的删除
delete 表名

#表的查看
!table

#表结构的信息
!desc 表名

#表数据的的添加和更新
upsert into 表名(列族.列名1, 列族.列名2。。。。)values (值1, 值2,值3, 。。。)

#数据的删除
delete 

#分页查询
select * from 表  limit 每页显示多少条 offset 从第几条开始查询
  • 手动分区及指定压缩格式(默认情况下只有一个分区)
create table [if not exists] 表名 (
rowkey名称 数据类型 primary key,
列族名.列名1 数据类型,
列族名.列名2 数据类型,
列族名.列名3 数据类型,
列族名.列名4 数据类型,
) compression=‘GZ’ //压缩方式
   split on ('10', '20', '30', '40') //手动指定分区方案
  • 哈希加盐(自动分区)
create table [if not exists] 表名 (
 rowkey名称  数据类型 primary key,
   列族名.列名1 数据类型 ,
   列族名.列名2 数据类型 ,
   列族名.列名3 数据类型 ,
   列族名.列名4 数据类型 
   .....
)
compression='GZ', 	//压缩方式
salt_buckets=10  	//加盐预分区 (hash + rowkey自动加盐)
;

Phoenix的视图操作


  • 默认情况下Phoenix中只展示自己创建的表,如果hbase的表是通过hbase自己构建的,那么在Phoenix中是无法看到的如果想看到需要通过Phoenix创建视图进行对hbase中的表进行映射
create view "名称空间"."Hbase对应的表的表名"(
key varchar primary key,
"列族"."列名" 类型,
......
)[default_column_family='列族名'];
	注意事项:
		1. 视图的名称一定要与 需要建立视图的Hbase的 表名一致.
		2. key的名称可以是任意的, 但是必须添加 primary key
		3. 普通的列, 需要和 hbase的对应表的列保持一致.

Phoenix的二级索引


  • 通过Phoenix可以非常方便的创建二级索引,这些二级索引可以加快查询速度
1)索引的分类
   1- 全局索引:会创建索引表,原表有几个region,索引表就有几个region
               如果查询列有索引列的出现,则全局索引无效,上述情况可以通过Hint让全局索引有效
   create index 索引名 on 表名(列1, 列2.。。)
   drop index 索引名 on 表名
   
   2- 本地索引:不会创建索引表,而是在原表的字段上直接存储,如果有查询列有非索引字段,则本地索也有效, 如果使用的是哈希加盐分区表,则本地索引部分功能无效
   create local index 索引名 on 表名(列1,列2 。。。)
   
   3- 覆盖索引
   4- 函数索引
      这两个都不能单独使用,必须结合全局索引和本地索引一起使用,不能创建索引表,而是在字段上直接存储,不需要手动删除当删除本地索引或者全局索引的时候,他们对应的覆盖索引和函数索引也会同步被删除
上一篇:【优化求解】基于matlab遗传算法求解电动汽车有序充电优化问题【含Matlab源码 792期】


下一篇:难搞的偏向锁终于被 Java 移除了