HBASE专题

1、Hbase基础理论

1.1、Hbase产生背景
顺序访问:Hadoop 只能执行批量处理,并且只以顺序方式访问数据。这意味着必须搜索整个数据集,即使是最简单的搜索工作。当处理结果在另一个庞大的数据集,也是按顺序处理一个巨大的数据集。

随机访问:应用程序,如 HBase,Cassandra,CouchDB,Dynamo 和 MongoDB 都是一些存储大量数据和以随机方式访问数据的数据库。
1.2、Hbase架构
HBase底层的数据存储:HDFS
HBase数据计算:MapReduce
HBase服务协调:ZooKeeper 
1.3、Hbase的存储机制
  • 存储机制
1、Hbase存储数据其底层使用的是HDFS来作为存储介质,
2、Hbase的每一张表对应HDFS上的一个文件夹,文件夹名以Hbase表进行命名
3、在表文件下存放若干个Region命名的文件夹
	:region是表或者表的一部分
4、Region文件夹中的每个列簇也是用文件夹进行存储
	:每个region中有多个store
5、每个列簇中存储的就是实际的数据,以Hfile的形式存在
	:每个store对应一个列簇的数据,store内部有一个Memstore和Hfile
  • 案例
/hbase/data/default/stu/8ca25fe0d49972b2efb4c36537daf1a2/cf1/d89f620da4754e1092402b577f589f8a

data:目录即是Hbase自动生成的用来存储所有表数据的一个目录
default:默认的一个namespace
stu:就是一张表,其实就是一个文件夹
8ca25fe0d49972b2efb4c36537daf1a2:就是stu这张表中的一个region
cf1:就是这个region中第一个列簇所对应的一个store
d89f620da4754e1092402b577f589f8a:这就是用来存储真实数据的hfile
  • Region是 HBase集群分布数据的最小单位
    Region 是部分数据,所以是所有数据的一个自己,但Region包括完整的行,所以Region 是行为单位表的一个子集。

​      每个Region 有三个主要要素:

- - 它所属于哪张表
  - 它所包含的的第一行(第一个Region 没有首行)
  - 他所包含的最后一行(末一个Region 没有末行)

​    当表初写数据时,此时表只有一个Region,当随着数据的增多,Region 开始变大,等到它达到限定的阀值大小时,变化把Region 分裂为两个大小基本相同的Region,而这个阀值就是StoreFile 的设定大小(参数:hbase.hRegion.max.filesize 新版本***\*默认\**\**10G\****) ,在第一次分裂Region之前,所有加载的数据都放在原始区域的那台服务器上,随着表的变大,Region 的个数也会相应的增加,而Region 是HBase集群分布数据的最小单位。

​     (但Region 也是由block组成,Region是属于单一的RegionServer,除非这个RegionServer 宕机,或者其它方式挂掉,再或者执行balance时,才可能会将这部分Region的信息转移到其它机器上。)

​    这也就是为什么 Region比较少的时候,导致Region 分配不均,总是分派到少数的节点上,读写并发效果不显著,这就是HBase 读写效率比较低的原因。

2、Hbase使用场景

一般我们从数仓中离线统计分析海量数据,将得到的结果插入HBase中用于实时查询。
  • 实际业务场景
1、半结构化或非结构化数据
:对于数据结构字段不够确定或杂乱无章很难按一个概念去进行抽取的数据适合用 HBase。而且 HBase 是面向列的,HBase 支持动态增加字段

2、记录非常稀疏
:RDBMS 的行有多少列是固定的,为 null 的列浪费了存储空间。而 HBase 为 null 的 Column是不会被存储的,这样既节省了空间又提高了读性能。

3、多版本数据
:对于需要存储变动历史记录的数据,使用 HBase 就再合适不过了。HBase 根据 Row key 和Column key 定位到的 Value 可以有任意数量的版本值。

4、超大数据量的随机、实时读写
:当数据量越来越大,RDBMS 数据库撑不住了,就出现了读写分离策略,通过一个 Master 专门负责写操作,多个 Slave 负责读操作,服务器成本倍增。随着压力增加,Master 撑不住了,这时就要分库了,把关联不大的数据分开部署,一些 join 查询不能用了,需要借助中间层。随着数据量的进一步增加,一个表的记录越来越大,查询就变得很慢,于是又得搞分表,比如按 ID 取模分成多个表以减少单个表的记录数。经历过这些事的人都知道过程是多么的折腾。采用 HBase 就简单了,只需要加机器即可,HBase 会自动水平切分扩展,跟 Hadoop 的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性(MapReduce)。

5、查询简单
:不涉及到复杂的 Join 查询,基于 RowKey 或者 RowKey 的范围查询

3、Hbase常用操作

3.1、启动hbase
hbase shell

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4BIq6eQS-1627878568390)(C:/Users/%E6%9D%8E%E6%B5%B7%E4%BC%9F/AppData/Roaming/Typora/typora-user-images/image-20210714100631671.png)]

3.2、表的相关操作
3.2.0、Hbase表结构
  • Hbase表:以表的形式存储数据。表有行和列,列划分为若干个列族

img

1、行键 - Row Key:row key是用来检索记录的主键。访问hbase table中的行,只有三种方式
	:Ⅰ、通过单个row key访问
	:Ⅱ、通过row key的range
	:Ⅲ、通过全表扫描
注意:rankey行键可u意识任意字符串,在hbase内部,rowkey保存为字节数组
	:存储时,数据按照row key的字典序排序

2、列簇:列簇是表schema的一部分,而列不是,必须在使用表之前定义
	:列名以列族作为前缀,例如courses:history,courses:math都属于courses这个列族

注意:访问空值、磁盘和内存的使用统计都是在列族层面上进行的
	:物理上,同一列族的数据存储在一起的
	:Hbase的表已经创建之后不能修改
2、列限定符:列族的数据通过列限定符限定

3、时间戳:单元格内不同版本的值按时间倒序排列,最新的数据排在最前面
	
4、cell:单元格由RowKey、列族、列限定符唯一定位,单元格之中存放一个值(Value)和一个版本号。

注意:Hbase是四维定位,通过行键.列族,列限定符,时间戳确定唯一数据
3.2.1、创建表
  • 前置相关
create 'NewsClickFeedback',{NAME=>'Toutiao',VERSIONS=>1,BLOCKCACHE=>true,BLOOMFILTER=>'ROW',COMPRESSION=>'SNAPPY',
TTL => '259200', DATA_BLOCK_ENCODING => 'PREFIX_TREE', BLOCKSIZE => '65536'},
{SPLITS => ['1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']}
  • 相关解释
1.创建表名:NewsClickFeedback
2.列簇:Toutiao
3.数据版本:versions
4.压缩方式:COMPRESSION
	HBase支持的压缩算法主要包括三种::GZip | LZO | Snappy,Snappy的压缩率最低,但是编解码速率最高,对CPU的消耗也最小,目前一般建议使用Snappy
5.预分配策略:SPLITS
	region预分配策略:通过region预分配,数据会被均衡到多台机器上,这样可以一定程度上解决热点应用数据量剧增导致系统自动split引起的性能问题。HBase数据是按照rowkey按升序排列,为避免热点数据产生,一般采用hash + partition的方式预分配region,比如示例中rowkey首先使用md5 hash,然后再按照首字母partition为16份,就可以预分配16个region。
  • 表的相关操作
# 1、创建表
create '<table_name>','<column family>'

# 2、修改表的描述
desc 'table'

# 3、显示所有表
list
  • 案例 - 创建表
create 'emp1', 'personal data', 'professional data'
#表名为emp的样本模式。它有两个列族:“personal data”和“professional data”。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LmwA3zBB-1627878568395)(C:/Users/%E6%9D%8E%E6%B5%B7%E4%BC%9F/AppData/Roaming/Typora/typora-user-images/image-20210714105758510.png)]

  • 案例 - 表结构信息
desc 'emp1'

#查询结果
{NAME => 'personal data', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE
', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true
', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}                                                                 
{NAME => 'professional data', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'F
ALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => '
true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} 

#表结构信息相关解释
3.2.2、修改表
修改表结构前必须disable,修改完后enable
# 1、增加一个列簇
alter 'emp1',name='date'

# 2、删除一个列簇
alter 'emop1','delete'=>'date'
3.2.3、删除表
# 1、使表失效
disable 'table_name'

# 2、删除表结构
drop 'table_name'

# 3、使表有效
enable 'table_name'
  • 案例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lu5TEUoH-1627878568398)(C:/Users/%E6%9D%8E%E6%B5%B7%E4%BC%9F/AppData/Roaming/Typora/typora-user-images/image-20210714103316107.png)]

3.3、数据的相关操作
3.3.1、增加 - put
put命令使用:put 表 行键 列定义 值
	:put 'tablename','row','colfamily:colname','value'
put 'emp1','1','personal data:name','lsj'
put 'emp1','2','personal data:city','zz'
put 'emp1','3','professional data:designation','programmer'
put 'emp1','1','professional data:salary','5000'

在这里插入图片描述

3.3.2、查询 - (get + scan)
# 1、get命令使用 - 查询某行记录
1.1、查看表中的某一行:get  表  行健
get 'emp1','1'

1.2、查看表中的某一cell:get  表  行健  列簇 
get 'emp1','1','personal data'

1.3、查看表中的某一列:get  表  行健  列簇:列 
get 'emp11','1','personal'

1.4、查看表中的某一版本:get  表  行健  列簇:列  时间戳

# 2、scan命令 - 扫描表
scan 'table_name'

# 3、count命令 - 查询表中的数据行数
count 'table_name'

# 4、 -查询表文件所在路径
3.3.3、删除 - delete
# 1、delete:删除表中特定的单元格数据
delete 'emp1','personal data:age',


# 2、deleteall:删除表中的所有单元格
deleteall 'emp1','1'


注意:HBase 的删除操作并不会立即将数据从磁盘上删除,删除操作主要是对要被删除的数据打上标记。当执行删除操作时,HBase 新插入一条相同的 KeyValue 数据,但是使 keytype=Delete,这便意味着数据被删除了,直到发生 Major compaction 操作时,数据才会被真正的从磁盘上删除,删除标记也会从StoreFile删除。
3.3.4、自增长列
incr:incr 'tablename','rowkey','column family:column' step     step是步长,可选,默认为1

4、Hbase的数据写入方式

4.1、hfile文件
  • hfile:在hdfs上生成hfile文件,之后导入hbase,hfile是hbase文件组织形式
实现原理
	:1、使用MapReduce将HDFS文件直接生成Hfile格式数据文件
	:2、然后通过RegionServer将HFile数据文件移动到相应的Regin上去

在这里插入图片描述

4.2、bulk load
  • bulk load:直接将数据批量导入到Hbase上
实现方式
	:1、java代码实现导入 - 使用场景(增量导入)
	:2、Hbase命令进行导入 - 使用场景(初始化导入)
  • 案例:将TSV文件通过ImportTsv命令导入到Hbase上
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv \
-Dimporttsv.separator="," \
-Dimporttsv.bulk.output=/test/hfile_tmp \
-Dimporttsv.columns=HBASE_ROW_KEY,cf test_csv_02 /test/test.csv	
4.3、HDFS上的文件块上传到Hbase
  • 第一步:生成Hfile文件
/*使用MR来实现
 *1、准备好数据源,上传到HDFS进行存储,然后在程序中读取HDFS上的数据源
 *2、进行自定义封装,组装RowKey
 *3、将封装后的数据写会到HDFS上,以Hfile形式存储到HDFS指定目录下
 */
  • 代码实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NteX3Q1r-1627878568427)(C:/Users/%E6%9D%8E%E6%B5%B7%E4%BC%9F/AppData/Roaming/Typora/typora-user-images/image-20210727101236817.png)]

1、docs目录
	commands.sh:将指定hive库数据文件转化为hfile文件,并将生成的hfile文件加载到hbase中的使用文档
2、src目录 - java目录 - 公司域名目录
	mapred -> HFileGenerator:hfile文件生成
	utils -> CommonUtils:
	utils -> HbaseUtils :
	ImportProcedurestarting:
  • 总体代码

  • 第二步:将代码打成jar包,上传到hadoop集群并执行

hadoop jar /v3extdaily2021.jar ${input} ${output} ${type} ${data_day}
  • 第三步:使用BulkLoad将生成的.hfile文件导入到Hbase里
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles -Dhbase.mapreduce.bulkload.max.hfiles.perRegion.perFamily=1024 /user/tianchuang/spark/hfile/daily_min/tc_ptcpT1_variate_'${etl_day}' tc_ptcpT1_variate_'${etl_day}

6、Hbase和Hive的比较

6.1、相同点
HBase 和 Hive 都是架构在 Hadoop 之上,用 HDFS 做底层的数据存储,用 MapReduce 做数据计算
6.2、不同点
1、Hive 是建立在 Hadoop 之上为了降低 MapReduce 编程复杂度的 ETL 工具。
 HBase 是为了弥补 Hadoop 对实时操作的缺陷

2、Hive 表是纯逻辑表,因为 Hive 的本身并不能做数据存储和计算,而是完全依赖 Hadoop
 HBase 是物理表,提供了一张超大的内存 Hash 表来存储索引,方便查询

3、Hive 是数据仓库工具,需要全表扫描,就用 Hive,因为 Hive 是文件存储
 HBase 是数据库,需要索引访问,则用 HBase,因为 HBase 是面向列的 NoSQL 数据库

4、Hive 表中存入数据(文件)时不做校验,属于读模式存储系统
 HBase 表插入数据时,会和 RDBMS 一样做 Schema 校验,所以属于写模式存储系统

5、Hive 不支持单行记录操作,数据处理依靠 MapReduce,操作延时高
 HBase 支持单行记录的 CRUD,并且是实时处理,效率比 Hive 高得多

7、RowKey相关

7.1、RowKey设计原则
  • 主要目的:并且能让数据分散,从而避免热点问题。
1)rowkey长度原则
	:以byte[]形式保存,一般设定成定长,一般越短越好,不要超过16个字节,与内存8字节对齐。
	
2)rowkey散列原则
	:如果rowkey按照时间戳的方式递增,不要将时间放在二进制码的前面,建议将rowkey的高位字节采用散列字段处理,由程序随即生成。低位放时间字段,这样将提高数据均衡分布,各个regionServer负载均衡的几率。
	:如果不进行散列处理,首字段直接使用时间信息,所有该时段的数据都将集中到一个regionServer当中,这样当检索数据时,负载会集中到个别regionServer上,造成热点问题,会降低查询效率。
	
3)rowkey唯一原则
	:必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块
7.2、RowKey如何设计
1)加盐:而是在rowkey的前面分配随机数,当给rowkey随机前缀后,它就能分布到不同的region中
2)预分区:预先创建hbase表分区。这需要我们明确rowkey的取值范围和构成逻辑
3)哈希:加盐与预分区rowkey设计方法,数据会真正无序随即分布在hbase集群当中,这并没有让我们利用到hbase根据字典顺序排序的这一特点。
4)反转:手机号前几位是固定的,我们可以将手机号反转之后作为rowkey,避免热点问题

8、Phoenix

8.1、Phoenix简介
Phoenix是构建在HBase上的一个SQL层,能让我们用标准的JDBC APIs而不是HBase客户端APIs来创建表,插入数据和对HBase数据进行查询。
8.2、Phoenix二级索引
	对于HBase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询。如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄。对于较大的表,全表扫描的代价是不可接受的。但是,很多情况下,需要从多个角度查询数据。例如,在定位某个人的时候,可以通过姓名、身份证号、学籍号等不同的角度来查询,要想把这么多角度的数据都放到rowkey中几乎不可能(业务的灵活性不允许,对rowkey长度的要求也不允许)

(1)覆盖索引

  • 覆盖索引:将数据打包进索引行中,查询时无需查询原表。
CREATE INDEX my_index ON my_table (v1,v2) INCLUDE(v3)

(2)函数索引

  • 函数索引:使用函数表达式创建二级索引,将函数的结果作为row key写入了HBase中的索引表。
#用函数表达式作为索引列创建索引
CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))

(3)全局索引

  • 全局索引:将所有索引列和原数据row key拼接在一起作为新的row key,写入HBase中的索引表,查询快,写入慢;
-- 默认情况下使用的就是全局索引
CREATE INDEX my_index ON my_table (v2, v3);

(4)本地索引

  • 本地索引将索引数据存放在和表数据相同的主机上,从而防止写入期间的网络开销,写入快,查询慢。
#使用LOCAL关键字创建本地索引
CREATE LOCAL INDEX my_index ON my_table (v1, v2);

9、实战案例

9.1、创建一个Hbase表

(1)通过shell进入Hbase中

hbase shell

在这里插入图片描述
(2)创建表

create 'student','info'    :创建表明和列簇

在这里插入图片描述

(3)表中录入数据

put 'student','1','info:name','xueqian'
put 'student','1','info:gender','F'
put 'student','1','info:age','23'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sDsK3wKV-1627878568432)(C:/Users/%E6%9D%8E%E6%B5%B7%E4%BC%9F/AppData/Roaming/Typora/typora-user-images/image-20210801223146020.png)]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随缘清风殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值