IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 一篇搞定HBase(上) -> 正文阅读

[大数据]一篇搞定HBase(上)

1.简述hbase

hbase是一种分布式、可扩展、支持海量数据存储的nosql数据库(基于列式存储)。

存储表大,稀疏(空列,不占存储),高可用(zookeeper)、高可靠(HDFS)、可伸缩的分布式数据库。

hbase的物理存储结构
在这里插入图片描述

hbase架构构成
在这里插入图片描述

Region

每一个region都是表的一部分,而每一个region又划分为多个store,store中存储的是该部分一个列族的信息。(一台机器放2-3个region)

storeFile

保存实际数据的物理文件,storeFile以HFile的形式存储在HDFS上。每个Store会有多个StoreFile(HFile),数据在每个storeFile中都是有序的。

HFile

一个列族存储在一个HFile(二进制格式文件)中。我们可以认为HBase是一个有序多维的Map,每一个rowkey,都对应多个列和其值。

HFile由多个Block数据块组成,并且有一个固定的结尾块。数据块中由一个Header和多个Key-Value的键值对组成。结尾的数据块中包含了数据相关的索引信息。

在这里插入图片描述

每个store保存一个列族,每个store由一个memstore、0至多个storefile组成,storefile以Hfile的格式存储在HDFS上。

blocksize大小问题

推荐数据块的大小设置为8KB至1MB。大的数据块比较适合顺序的查询(比如Scan),但不适合随机查询,每一次随机查询可能都需要你去解压缩一个大的数据块。小的数据块适合随机的查询,但是需要更多的内存来保存数据块的索引(Data Index),而且创建文件的时候也可能比较慢,因为在每个数据块的结尾我们都要把压缩的数据流Flush到文件中去(引起更多的Flush操作)。

MemStore

写缓存,由于HFile的数据要求是有序,所以数据会先存储在MemStore中,排序以后,等待到刷写时机刷写到HFile中,每次刷写都会形成一个新的HFile。

WAL

由于数据要经 MemStore 排序后才能刷写到 HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。

2.hbase架构组成作用

在这里插入图片描述

HDFS为hbase提供高可靠的底层存储支持;mapreduce为hbase提供高性能的计算能力;zookeeper为hbase提供稳定的服务和失败恢复机制;hive,pig为hbase提供高层语言支持,使得在hbase上进行数据统计变得简单;sqoop为hbase提供了RDBMS数据导入功能,方便数据的迁移。
hbase的逻辑结构

主从结构:

zookeeper

实现HMaster的高可用,每个子znode包含当前作为热备的HMaster信息。

记录META表(不会split)的位置,可从META表中获取存储数据的位置,完成读写功能。

HRegionServer的监控,活动HMaster对/hbase/rs路径下的znode注册监听。

Log Split管理,HMaster会在ZK上注册/hbase/splitlog临时节点,存储存活RegionServer与其应该处理的Region HLog的映射关系。RegionServer分配得到region,重放HLog。

Replication管理,主集群和从集群之间的数据同步,从而支持容灾和备份,保证数据的最终一致性,整个Replication的状态信息都储存在ZK的/hbase/replication中。

Hmaster

管理用户对Table表的DDL操作;

实现RegionServer的负载均衡;

实现故障转移,当有Region失效时,将实现对其进行转移恢复。

HRegionServer

维护Region,处理Region的IO请求

切分超过阈值的Region。

BlockCache 读缓存,memstore写缓存,加快读写速度

HLog记录数据变更信息,恢复数据用途。

3.hbase读写底层实现

写过程

在这里插入图片描述

1)Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey, 查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以 及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。
3)与目标 Region Server 进行通讯;
4)将数据顺序写入(追加)到 WAL;
5)将数据写入对应的 MemStore,数据会在 MemStore 进行排序;
6)向客户端发送 ack;
7)等达到 MemStore 的刷写时机后,将数据刷写到 HFile

注意:Memstore达到阈值会刷写成HFile文件,当多个HFile文件达到一定大小,触发Compact操作,合并为一个HFile。

当HFile大小达到一定阈值,会将Region切分为两个,并由Hmaster分配到对应的HRegionServer,实现负载均衡。

读过程
在这里插入图片描述

1)Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
2)访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey, 查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以 及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。
3)与目标 Region Server 进行通讯;
4)分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将 查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不 同的类型(Put/Delete)。
5) 将从文件中查询到的数据块(Block,HFile 数据存储单元,默认大小为 64KB)缓存到 Block Cache。
6)将合并后的最终结果返回给客户端。

MemStore Flush时机

当某个 memstroe 的大小达到hbase.hregion.memstore.flush.size(默认值 128M),其所在 region 的所有 memstore 都会刷写。 当 memstore 的大小达到了 hbase.hregion.memstore.flush.size(默认值 128M) * hbase.hregion.memstore.block.multiplier(默认值 4) 时,会阻止继续往该 memstore 写数据。

当 region server 中 memstore 的总大小达到 java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4) * hbase.regionserver.global.memstore.size.lower.limit(默认值 0.95), region 会按照其所有 memstore 的大小顺序(由大到小)依次进行刷写。直到 region server 中所有 memstore 的总大小减小到上述值以下。 当 region server 中 memstore 的总大小达到java_heapsize * hbase.regionserver.global.memstore.size(默认值 0.4)时,会阻止继续往所有的 memstore 写数据。

到达自动刷写的时间,也会触发 memstore flush。自动刷新的时间间隔由该属性进行配置 hbase.regionserver.optionalcacheflushinterval(默认 1 小时)。

当 WAL 文件的数量超过 hbase.regionserver.max.logs,region 会按照时间顺序依次进行刷写,直到 WAL 文件数量减小到hbase.regionserver.max.log 以下(该属性名已经废弃,现无需手动设置,最大值为 32)。

StoreFile Compaction

Minor Compaction:不会清理过期和删除数据

只选取一些小的、相邻的HFile将他们合并成一个更大的Hfile。当所合并的HFile个数大于3时,相当于Mager Compaction,会清理过期和输出数据。

Major Compaction:会清理过期和删除数据

会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期 和删除的数据。

在这里插入图片描述

Region Split

当 1 个 region 中 的 某 个 Store 下所有 StoreFile 的 总 大 小 超 过 Min(R^2 * “hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize(10G)"),该 Region 就会进行拆分,其 中 R 为当前 Region Server 中属于该 Table 的个数

问题:可能出现热点问题(64,256…9.99G分区问题),因此需要预分区。

4.列族设计、预分区和rowkey设计

列族设计:

建表至少指定一个列族,但一般不超过三个,一般一个。flush是以region为单位,当某个column family在flush的时候,他临近的column family 也会因关联效应被触发flush,产生更多的io。

列族名字不宜过长,会冗余存储。

不能设置太多列族。当region下所有的storeFile中最大的storeFile大小超过阀值时将进行split。由于不同的列族会共享一个region,可能会出现一个A列族存储几千万行的数据,而另一个B列族则存储了几百行的问题,使得B列族数据不多却可能被分散在多个region中,导致扫描查询B列族的性能下降(产生更多的io和占有更多的cpu资源)。

预分区

默认Region Split机制,造成热点问题

防止数据一直往同一个region上写入,造成热点问题

Region Split会消耗宝贵的I/O资源。

每一个 region 维护着 StartRow 与 EndRow,如果加入的数据符合某个 Region 维护的 RowKey 范围,则该数据交给这个 Region 维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,创建多个空region,设计合理的rowkey,并确定其startkey和endkey,以提高 HBase 性能。

rowkey设计原则

唯一性原则

rowkey在设计上保持其唯一性。rowkey是按照字典顺序排序存储,设计rowkey应把经常读取的数据存储到一起,将最近可能访问的数据放到一块。

长度原则

因为字典顺序存储的原因,rowkey的长度应相等且与分区的划分长度保持一致或者大于,保证可读性。

rowkey是二进制码流,可以是任意字符,最长长度为64kb,实际为10-100bytes,以byte[] 形式保存,一般设计为定长。建议越短越好,不超过16字节(但应该根据实际情况满足实际需求)。因为数据的持久化文件HFile是按照KeyValue存储,如果rowkey过长,将会极大地影响HFile的存储效率;Block Catch读数据会将部分缓存内容到内存,而MemStore写数据也会将内存内容写到缓存中,如果rowkey过长,内存的有效利用率就会降低,系统不能缓存更多的数据,降低读写速度。另外根据操作系统都是64位,内存8字节对齐,控制在16字节,8字节的整数倍,利用了操作系统的最佳特性。

散列原则(应实现负载均衡和快速查询)

散列的同时应注意将想要同时读取的数据放到一起(将想要读取数据的信息在rowkey中提取出来计算分区,再加到前缀即可,具体根据业务而定)

加盐

若rowkey按照时间戳的方式递增,不要将时间放在二进制码的最前面,建议将rowkey的高位作为散列字段,由程序随机生成,低位放时间字段,使数据均衡分布在每个RegionServer,实现负载均衡。(若没有散列字段,很可能使得数据集中在一个RegionServer上,造成热点问题,降低查询效率)。加盐的前缀种类数量应该和region数量相同。

哈希

哈希使得同一行永远用同一个前缀加盐。可以达到负载均衡的目的,并使得读是可以预测的。

反转

反转固定长度或者数字格式的rowkey。使得rowkey经常改变的部分放在最前面。(牺牲了有序性)比如手机号的反转,可以避免了例如手机号那样比较固定开头导致热点的问题。

时间戳反转

可以快速的获取数据的最近版本,使得反转的时间戳作为rowkey的一部分对这个问题十分有用。可以将Long。Max_Value-timestamp追加到rowkey的末尾,比如【key】【reverse_timestamp】。因为rowkey的有序性,就会将最后录入的数据放到第一条进行记录。

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:36:15  更:2021-08-22 13:37:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/31 13:22:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码