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-statusHbase的数据模型
Hbase数据模型的介绍
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架构说明
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的读取流程
①客户端发起请求,例如:get ‘user’,‘rk001’,‘info’, 通过该zookeeper连接到master
②获取到hbase:meta的存储原数据的regionserver(从节点)信息,返回给客户端
③客户端根据元数据的信息,连接需要存有读取信息的regionserver
④先从mestore中读取数据
⑤如果mestore中没有数据的话,再从blockcache中读取数据
⑥如果还是没有需要的数据就去hfile中读取
注:
读取顺序为: mestore(一级缓存)→blockcache(二级缓存)→hfile
上述的读取数据的方式为 并行的,例如每个RS节点中都有需要的数据 则进行并行读取
hbase的写入流程
①客户端发起请求,例如: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的关系
- 说明
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机制
- 说明
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机制
- 说明
1)目的:将多个storefile文件合并到一个大的hfile文件中 (阈值:storefile文件的个数达到3个或三个以上,又或者hbase集群刚启动的时候) 2)主要分为两个阶段: 1- minor:负责把多个storefile文件合并成一个大的storefile文件 2- major:负责把大的storefile文件和hfile文件做合并(阈值7天或者手动)
split机制
-说明
1)目的:对hfile文件进行切割,将其变成两个hfile文件,对应的region也会一分为二 阈值:最终:10GB 公式:min(region的平方 * 128MB, 10GB) 2)当启动spilt机制后,大的10GB文件hfile文件,会分为两个,这时也就会产生两个region,旧的hfile对应的region会被下线,新的两个region将会被master根据负载均衡被随机分配到指定的RS从节点进行管理HRegionServer的上下线问题
- 说明
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来给刚启动的RegionHMaster的上下线问题
- 说明
1)所有的HMaster都要去ZK中去创建自己的临时节点 2)当hbase集群刚启动的时候,所有的HMaster都会抢占式的去ZK的master节点下,创建自己的临时节点,那个HMaster先创建成功,他就是Active 3)其他的HMaster就去backup-master 节点下创建自己的临时节点,他们的状态就是standby 4)所有的standbymaster的状态都会实时监听ZK的ACtive节点,如果发现宕机,立即抢占Active节点BulkLoad批量装载
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中的压缩
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的图解
endpoint的图解
- 协处理器主要分为两类:
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- 函数索引 这两个都不能单独使用,必须结合全局索引和本地索引一起使用,不能创建索引表,而是在字段上直接存储,不需要手动删除当删除本地索引或者全局索引的时候,他们对应的覆盖索引和函数索引也会同步被删除
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)