|
文章目录
- 分布式NoSQL列存储数据库Hbase(四)
- 知识点01:课程回顾
- 知识点02:课程目标
- 知识点03:存储设计:存储架构
- 知识点04:存储设计:Table、Region、RegionServer的关系
- 知识点05:存储设计:Region的划分规则
- 知识点06:存储设计:Region内部存储结构
- 知识点07:存储设计:HDFS中的存储结构
- 知识点08:热点问题:现象及原因
- 知识点09:分布式设计:预分区
- 知识点10:Hbase表设计:Rowkey设计
分布式NoSQL列存储数据库Hbase(四)
知识点01:课程回顾
- Hbase Java API DML
- DML实现规则
- put
put表名rowkey列族:列值
- delete
delete表名rowkey列族:列
- get:最快
get表名rowkey[列族:列]
- 根据rowkey进行查询,Rowkey是索引,所有的查询都是走索引
- step1:先构建Get对象,指定rowkey
- step2:根据需求指定列族或者列
- step3:返回整个Rowkey的所有数据
- 返回值:Result:一个Result代表一个Rowkey的所有数据
20210101_001 column=basic:age, timestamp=1616034013623, value=18
20210101_001 column=basic:name, timestamp=1616034013623, value=laoda
20210101_001 column=other:addr, timestamp=1616034013623, value=shanghai
20210101_001 column=other:phone, timestamp=1616034013623, value=110
- 迭代取出每一列:Cell:一个Cell代表一列的数据
20210101_001 column=basic:age, timestamp=1616034013623, value=18
- 一个Result包含一个Cell数组:rs.rawCells
- 工具类
- Bytes:用于实现类型转换
- 将其他类型转换为字节类型:写
- 将字节类型转换为其他类型:读
- CellUtil:用于从Cell对象中取数据
- scan:全表扫描,不常用
scan 表名
- step1:构建Scan对象
- step2:表执行Scan对象:getScanner
- step3:获取返回值,多个Rowkey的数据
- ResultScanner = Iter【Result】
- Filter:条件查询,最常用的
scan 表名 Filter
- step1:构建Scan对象
- step2:根据查询条件构建过滤器
- 范围过滤
- STARTROW:指定从某个Rowkey开始,包含
- STOPROW:指定到某个Rowkey结束,不包含
- 过滤器:Filter
- Rowkey过滤:PrefixFilter
- 列值过滤:SingleColumnValueFilter
- 列的过滤:MultipleColumnPrefixFilter
- 组合过滤:FilterList
- step3:表执行Scan对象:getScanner
- step4:获取返回值,多个Rowkey的数据
- ResultScanner = Iter【Result】
- 操作类知识点的学习方法
- 命令:一般都是英文缩写,记住英文和语法,背一背
- JavaAPI
- 哪些类:每个类的作用和构建方式
- 哪些方法:增删改查
知识点02:课程目标
- Hbase存储设计
- 整个Hbase中的存储结构?
- Table与RegionServer的关系?
- Table怎么实现分布式?划分Region的规则是什么呢?写入数据分配的规则?【重要】
- Region内部的存储?【重要】
- Hbase数据与HDFS的关系?
- Hbase最严重的问题:热点
- 现象、原因
- 解决方案【重要】
- 预分区:一张表有多个Region分区
- 表的设计:Rowkey的设计
知识点03:存储设计:存储架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yYfd67AX-1616633798599)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210317190105892.png)]
- 问题:Hbase整体如何实现数据的存储?
- 分析
- Client:负责连接服务端
- 提供开发接口,将用户的命令或者代码提交给服务端执行
- 将服务端执行的结果返回给用户
- Zookeeper:存储Hbase部分元数据
- 所有Hbase客户端,都需要连接Zookeeper获取元数据
- Hbase:分布式内存
- HMaster:管理类功能
- HRegionServer:负责数据的存储,对外提供客户端读写
- HDFS:分布式磁盘
- DataNode:负责将Hbase内存中的数据写入磁盘
知识点04:存储设计:Table、Region、RegionServer的关系
- 问题:客户端操作的是表,数据最终存在RegionServer中,表和RegionServer的关系是什么?
- 分析
- Table:是一个逻辑对象,物理上不存在,供用户实现逻辑操作,存储在元数据的一个概念
- RegionServer:是一个物理对象,Hbase中的一个进程,管理一台机器的存储
- Region:Hbase中数据存储的最小单元
- 类似于HDFS中Block
- 就是分区的概念,每张表都可以划分为多个Region,实现分布式存储
- 每个Region由一台RegionServer所管理,Region存储在RegionServer
- 一台RegionServer可以管理多个Region
- 观察监控
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JyhZT7gp-1616633798601)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319091350259.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u8AXyrI7-1616633798603)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319091417912.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WvMurhSI-1616633798606)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319091609104.png)]
知识点05:存储设计:Region的划分规则
- 问题:一张表划分为多个Region,划分的规则是什么?写一条数据到表中,这条数据会写入哪个Region,分配规则是什么?
- 分析
- 回顾:HDFS划分规则
- 划分分区的规则:按照大小划分,文件按照每128M划分一个Block
- Hbase分区划分规则:范围划分【根据Rowkey范围】
- 范围划分:从整个-oo ~ +oo区间上进行范围划分
- 每个分区都会有一个范围:根据Rowkey属于哪个范围就写入哪个分区
[startKey,stopKey)
- 默认:一张表创建时,只有一个Region
- 自定义:创建表时,指定有多少个分区,每个分区的范围
- 举个栗子:创建一张表,有2个分区Region
- region0:-oo ~ 50
- region1: 50 ~ +oo
- 举个栗子:创建一张表,有4个分区Region
- region0:-oo ~ 30
- region1: 30 ~ 60
- region2: 60 ~ 90
- region3: 90 ~ +oo
- 数据分配的规则:根据Rowkey属于哪个范围就写入哪个分区
- 举个栗子:创建一张表,有4个分区Region
- region0:-oo ~ 30
- region1: 30 ~ 60
- region2: 60 ~ 90
- region3: 90 ~ +oo
- 写入数据的rowkey:比较是按照ASC码比较的,不是数值比较
- 10 => Region0
- 1000 => Region0
- 033 => Region0
- 789999999 => Region2
- 91 => Region3
- 观察监控
- 只有1个分区
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fSsgCtLA-1616633798607)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319093313002.png)]
- 多个分区的情况
create 'itcast:t3','cf',SPLITS => ['20', '40', '60', '80'] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eY7aX5N6-1616633798608)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319093457846.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nARHgEC6-1616633798608)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319093602323.png)]put 'itcast:t3','0300000','cf:name','laoda' => -oo ~ 20
put 'itcast:t3','7890000','cf:name','laoda' => 60 ~ 80 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SwnDDMT6-1616633798609)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319093903377.png)]
知识点06:存储设计:Region内部存储结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PMqZdtFr-1616633798610)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210317191716413.png)]
- 问题:数据在Region的内部是如何存储的?
- 分析
- Table【逻辑】/ RegionServer【物理】
- Region:分区层,根据rowkey判断属于哪个分区,就写入哪个Region
- Store:存储层,对每个分区内部数据存储的划分,根据列族划分,一个列族就对应一个Store
- 每个列族对应一个Store,不同列族的数据存储在不同的Store中
- 如果一张表,有2个列族,这张表的region中就会有两个Store
- 优点:划分不同的数据存储
- 假设有100列,如果没有列族,100列存储在一起,想查询其中1列,最多会比较100次
- 假设有100列,如果有两个列族,50列存储在一起,想查询某个列族中的某1列,最多比较51次
- Store中的存储
- 一个MemStore:Region中的内存区域,会为每个Store分配一部分
- 0个或者多个StoreFile文件:Store中的数据文件,如果Memstore存储达到阈值,就会将内存数据写入HDFS
- StoreFile:逻辑上属于Store的
- 物理上存储在HDFS上:本质上存储的是HFILE:有序的二进制文件
- 总结
- RegionServer:Region存储在Regionserver中
- Region:一张表有多个Region,根据Rowkey判断写入哪个region
- 一个表中有多个列族,每个列族对应一个Store,一个region中有多个store
- Store:根据列族判断写入哪个Store
- memstore:内存区域
- storefile:HDFS上的文件
知识点07:存储设计:HDFS中的存储结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLHCvTK8-1616633798610)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210317191754182.png)]
- 问题:Hbase的数据在HDFS中是如何存储的?
- 分析
- 整个Hbase在HDFS中的存储目录:由配置决定
hbase.rootdir=hdfs://node1:8020/hbase [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LE98p1w6-1616633798611)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103050484.png)]
- Namespace的目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j0kiin6w-1616633798611)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103216678.png)]
- 表的目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MgYZIbnt-1616633798612)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103307682.png)]
- Region的目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYjAQ9yu-1616633798612)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103437641.png)]
- Store的目录:按照列族划分的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cNt2Oxbn-1616633798612)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103636158.png)]
- 观察数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OwP9fqL8-1616633798613)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319103835828.png)]hbase> flush 'TABLENAME'
hbase> flush 'REGIONNAME'
hbase> flush 'ENCODED_REGIONNAME'
hbase> flush 'REGION_SERVER_NAME'
#强制将内存的数据写入HDFS变成StoreFile
flush 'itcast:t3' [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sNA9vzoZ-1616633798613)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319104124012.png)]
知识点08:热点问题:现象及原因
- 现象:在某个时间段内,大量的读写请求全部集中在某个Region中,导致这台RegionServer的负载比较高,其他的Region和RegionServer比较空闲
- 问题:这台RegionServer故障的概率就会增加,整体性能降低,效率比较差
- 原因:本质上的原因,数据分配不均衡
- 情况一:如果这张表只有一个分区
- region0:-oo ~ +oo
- 所有数据都是读写这一个分区
- 肯定会出现热点
- 情况二:如果这张表有多个分区,如果你的Rowkey写入时是连续的
- region0:-oo ~ 30
- region1:30 ~ 70
- region2:70 ~ +oo
- 写入的rowkey
- 00000001
- 00000002
- 00000003
- ……
- 29999999:都在往Region0中写入
- 30000000:开始写入region1
- ……
- 全部写region1
- ……
- 原因:region的设计是按照范围有序的,Rowkey也是有序的,连续的rowkey写入同一个region
- 解决
- 创建表的时候给定多个分区
- Rowkey写入时不能是连续的
知识点09:分布式设计:预分区
- 需求:在创建表的时候,指定一张表拥有多个Region分区
- 分析
- 划分多个分区,实现分布式并行读写,将无穷区间划分为几段
- 段的划分的依据:Rowkey或者Rowkey的前缀来划分
- 举个栗子:如果分区都是按照数值划分的
- region0:-oo ~ 3
- region1:3 ~ 7
- region2:7 ~ +oo
- Rowkey:都是以字母开头的
a143434343
ydfjdkfjd4
……
- 出现了热点问题
- 实现
- 方式一:指定分隔段,实现预分区
create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40']
#将每个分割的段写在文件中,一行一个
create 't1', 'f1', SPLITS_FILE => 'splits.txt'
- 方式二:指定Region个数,自动进行Hash划分:字母和数字的组合
#你的rowkey的前缀可能是字母可能是数字
create 'itcast:t4', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'} [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gEmrClkI-1616633798614)(20210319_分布式NoSQL列存储数据库Hbase(四).assets/image-20210319111755041.png)]
- 方式三:Java API
HBASEAdmin admin = conn.getAdmin
admin.create(表的描述器对象,byte[][] splitsKey)
- 总结
- 原则:必须根据rowkey或者rowkey前缀来设计分区的划分
- 方式:三种方式任何一种只要能满足需求都可以
知识点10:Hbase表设计:Rowkey设计
- 问题
- Rowkey功能
- 唯一标识符
- 作为Hbase唯一索引
- 划分Region的标识,不能连续
- 问题
- Rowkey不重复
- 尽量保证按照rowkey查询数据是最快的
- Rowkey是散列的,无序的
- 需求:根据业务需求,来合理的设计rowkey,实现高性能的数据存储
- 分析:不同的业务需求的表,Rowkey设计都不一样
- 设计规则
- 业务原则:Rowkey设计必须贴合业务需求,尽量实现基于Rowkey数据检索,走索引
- Rowkey是Hbase中的唯一索引,按照Rowkey的查询是按照前缀匹配实现的
- 如果不按照Rowkey检索,就是全表扫描
- 尽量将最常用的查询条件作为Rowkey的前缀
- 唯一原则:Rowkey必须唯一标识一条数据,Rowkey是不能重复的
- 组合原则:尽量将最常用的几个查询条件组合作为Rowkey,最常用的那一个作为前缀
- 散列原则:Rowkey不能是按照有序生成的,由于Region范围划分的,如果rowkey是有序的,会导致热点,必须构建无序的Rowkey
- 长度原则:Rowkey的长度不建议过长
- 原则:能满足业务需求的情况下越短越好
- 问题:如果rowkey越长,索引占用的空间越大,比较rowkey就越慢,性能就越差
- 建议:不超过100个字节
- 总结
- 业务原则:保证前缀是最常用的查询字段
- 唯一原则:每条rowkey表示一条数据
- 组合原则:常用的查询条件作为Rowkey
- 散列原则:rowkey构建不连续
- 长度原则:满足业务需求越短越好
9】0_1616124723000_user001_order001
4_1616124723000_user002_order002
9_1616124723000_user003_order003
0_1616124723001_user001_order004
0_1616124723002_user001_order005
1_1616124723000_user001_order001
```
- 缺点:每次查询时,挨个试,读的性能降低
- 长度原则:Rowkey的长度不建议过长
- 原则:能满足业务需求的情况下越短越好
- 问题:如果rowkey越长,索引占用的空间越大,比较rowkey就越慢,性能就越差
- 建议:不超过100个字节
- 总结
- 业务原则:保证前缀是最常用的查询字段
- 唯一原则:每条rowkey表示一条数据
- 组合原则:常用的查询条件作为Rowkey
- 散列原则:rowkey构建不连续
- 长度原则:满足业务需求越短越好
|
免责声明:
1. 本站所有资源来自网络搜集或用户上传,仅作为参考不担保其准确性!
2. 本站内容仅供学习和交流使用,版权归原作者所有!© 查看更多
3. 如有内容侵害到您,请联系我们尽快删除,邮箱:kf@codeae.com
|