ToB企服应用市场:ToB评测及商务社交产业平台

标题: HBase [打印本页]

作者: 去皮卡多    时间: 2024-9-24 04:38
标题: HBase
HBase是什么

Apache HBase(Hadoop DataBase)是一个开源的、高可靠性、高性能、面向列、可伸缩、及时读写的分布式数据库,其设计思想来源于 Google 的 BigTable 论文。利用 Hadoop HDFS 作为其文件存储体系,利用 ZooKeeper 作为其分布式协同服务。重要用来存储非结构化和半结构化的疏松数据(列式存储 NoSQL 数据库)。 HBase 属 于 CP 架构,降低了可用性,具备强同等性读/写。

特点:
1. 易扩展
一个是基于运算能力(HRegionServer)通过增长 HRegionServer 节点数量提高其运算能力,一个是基于存储能力的扩展(HDFS)通过增长 DataNode 节点数提高数据储存能力
2. 容量大
HBase 单表可以有十亿行、百万列,数据矩阵横向和纵向两个维度所支持的数据量级都非常具有弹性。HBase 的重要作用就是面向 PB 级别数据的及时入库和快速随机访问。
3. 面向列
HBase 是根据列族来存储数据的,列族下面可以有非常多的列。列式存储的最大利益就是,其数据在表中是按照某列存储的,如许在查询只需要少数几个字段时,能大大减少读取的数据量。还可以动态增长列,可单独对列举行各方面的操作。
4. 多版本
HBase 的每个列的数据存储支持多个 Version,比如住址列,大概有多个变更。
5. 稀疏性
为空的列并不占用存储空间,表可以设计的非常稀疏。不必像关系型数据库那样需要预先知道所有列名然后再举行 null 添补。
6. 高可靠
WAL(Write Ahead Log)日志先行机制,保证数据写入的时间不会因为集群非常而导致写入数据丢失。Replication 机 制,保证了集群在出现严重题目的时间,数据不会发生丢失或者损坏。HBase 底层使用 HDFS,本身也有备份。
7. 高性能
底层的 LSM 树数据结构和 RowKey 有序分列等架构上的独特设计,使得 HBase 写入性能非常高。HRegion 切分、主键 索引、缓存机制使得 HBase 在海量数据下具备一定的随机读取性能,该性能针对 RowKey 的查询能够到达毫秒级别。LSM 树属于树形结构,最末端的子节点是以内存的方式举行存储的,内存中的小树会 Flush 到磁盘中(当子节点达到一定阈值 以后,会放到磁盘中,且存入的过程会举行及时 Merge 成一个主节点,然后磁盘中的树定期会做 Merge 操作,合并成一棵大树,以优化读性能)。
HBase 数据模子



在 HBase 表中,一条数据拥有一个全局唯一的主键(RowKey)和任意数量的(Column Qualifier),每个列的数据 存储支持多个版本(Version),一列或多列组成一个列族(Column Family),同一个列族中列的数据在物理上都存储在同一个 HFile 中。如许基于列存储的数据结构有利于数据缓存和查询。
所以,在 HBase 中定位一条数据需要通过:RowKey → Column Family → Column Qualifier → Version。
HBase 表中的数据是疏松地存储的,因此用户可以动态地为数据定义各种不同的列。HBase 中的数据按主键排序(字 典序),同时 HBase 会将表按主键划分为多个 HRegion 存储在不同的 HRegionServer 上,以完成数据的分布式存储和读取。
1. NameSpace

命名空间类似于关系型数据库中的数据库的概念,他其实是表的逻辑分组。这种抽象为多租户相关功能奠定了基础。 命名空间是可以管理维护的,可以创建,删除或更改命名空间。HBase 有两个特别预定义的命名空间

2. Table

Table 和关系型数据库中的表一个意思,由行和列组成。
3. RowKey

RowKey 的概念与关系型数据库中的主键相似,是一行数据的唯一标识。RowKey 可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100 Bytes),RowKey 以字节数组生存。存储数据时,数据会按照 RowKey 的字典序排序存储,所以设计 RowKey 时,要充实利用排序存储这个特性,将常常一起读取的行存放到一起。
访问 HBase 数据的方式有三种:

4. Column Family

Column Family 即列族,HBase 基于列划分数据的物理存储,同一个列族中列的数据在物理上都存储在同一个 HFile 中。一个列族可以包罗任意多列,一般同一类的列会放在一个列族中,每个列族都有一组存储属性:

HBase 在创建表的时间就必须指定列族。HBase 的列族不是越多越好,官方保举一个表的列族数量最好小于或者即是三,过多的列族不利于 HBase 数据的管理和索引。
5. Column Qualifier

列族的限定词,明白为列的唯一标识。但是列标识是可以改变的,因此每一行大概有不同的列标识。使用的时间必须 列族 : 列 ,列可以根据需求动态添加或者删除,同一个表中不同行的数据列都可以不同。
6. Timestamp

Timestamp 是实现 HBase 多版本的关键。在 HBase 中,使用不同的 Timestamp 来标知趣同 RowKey 对应的不同版本 的数据。相同 RowKey 的数据按照 Timestamp 倒序分列,默认查询的是最新的版本,当然用户也可以指定 Timestamp 的值 来读取指定版本的数据。
为了避免数据存在过多版本而造成管理(包括存贮和索引)负担,HBase 提供了两种数据版本采取方案:

7. Cell

Cell 由 Row,Column Family,Column Qualifier,Version 组成。Cell 中的数据是没有范例的,全部使用字节码情势存贮,因为 HDFS 上的数据都是字节数组。
HBase架构模子



流程:

客户端根据 RowKey 发出读哀求给 Zookeeper -> Zookeeper 拿到客户 RowKey -> Zookeeper 发给 HMaster Active -> HMaster Active 根据 RowKey 找到具体的 HRegionServer -> HRegionServer 先去BlockCache块缓存 找数据 -> 未找到去 MemStore 缓存中找数据 -> 未找到去磁盘中的 StoreFile 找数据 -> 从 HFile 中找到记载所存在的 HDFS 中 DataNode 的位置 -> HDFS Client -> DataNode
1. ZooKeeper

HBase 通过 ZooKeeper 来完成选举 HMaster、监控 HRegionServer、维护元数据集群配置等工作。


2. Client

HBase Client 为用户提供了访问 HBase 的接口,可以通过元数据表(客户端负责发送哀求到数据库)来定位到目标数据的 HRegionServer。客户端连接的方式有很多种:

发送的哀求重要包括:

Client 维护着一些 Cache 来加快对 HBase 的访问,比如 HRegione 的位置信息。
3. HMaster

HMaster 是 HBase 集群的主节点,负责整个集群的管理工作,HMaster 可以实现高可用(Active 和 Standby),通过 ZooKeeper 来维护主备节点的切换。HMaster 重要工作职责如下:



4. HRegionServer

HRegionServer 直接对接用户的读写哀求,是真正干活的节点,属于 HBase 具体数据的管理者。重要工作职责如下:


5. HRegion

一个 HRegionServer 包罗了多个 HRegion。HBase 将表中的数据基于 RowKey 的不同范围划分到不同 HRegion 上,每个 HRegion 都负责一定范围的数据存储和访问。
HRegion 是 HBase 中分布式存储和负载均衡的最小单位,不同的 HRegion 可以分布在不同的 HRegionServer 上。每个表一开始只有一个 HRegion,随着数据不停插入表,HRegion 不停增大,当增大到指定阀值(10G)的时间,HRegion 就会等分成两个 HRegion,切分后其中一个 HRegion 会被转移到其他的 HRegionServer 上,实现负载均衡。
当 Table 中的行不停增多,就会有越来越多的 HRegion。为了防止前期数据的处理都集中在一个 HRegionServer,我们可以根据自己的业务举行预分区。
由于数据被划分到不同的 HRegion上,每个 HRegion 都可以独立地举行读写, HBase 读写数据的时间还可以与多 HRegion 分布式并发操作,所以访问速度并不会有太大的降低。
6. Store

一个 HRegion 由多个 Store 组成每个 Store 都对应一个 Column FamilyStore 包罗 1 个 MemStore 和 0 或多个 StoreFile 组成

7. HFile

StoreFile(HFile) 是 HBase 最终存储数据的介质,这里需要相识几个相关的名词:

8. HLog

一个 HRegionServer 只有一个 HLog 文件。负责记载数据的操作日志,当 HBase 出现故障时可以举行日志重放、故障恢复。比方磁盘掉电导致 MemStore 中的数据没有持久化存储到 StoreFile,这时就可以通过 HLog 日志重放来恢复数据。
9. HDFS

HDFS 为 HBase 提供底层数据存储服务,同时为 HBase 提供高可用支持。HBase 将 HLog 存储在 HDFS 上,当服务器发 生非常宕机时,可以重放 HLog 来恢复数据。
比如:MySQL 数据直接落入磁盘,HBase 数据落入 HDFS,HDFS 数据落入磁盘。

三层索引

1. HBase 0.96 以前
HBase 0.96 以前内部维护了两张特别的表: -ROOT- 表和 .META. 表,用来查找各种表的 HRegion 位置。这两张特别 的表也像 HBase 中的其他表一样会切分成多个 HRegion。 -ROOT- 表比 .META. 更特别一些,永远不会切分凌驾一个 HRegion,如许保证了只需要三次跳转,就能定位到任意 HRegion。

整个流程为: Client → ZooKeeper → -ROOT- → .META. → 用户的表的 HRegion 。

-ROOT- 表永远只有一个 HRegion,也就是说只会存放在一台 HRegionServer 上,这个信息至关紧张,是所有客户端定位 HRegion 的入口,所以这个映射信息存储在 ZooKeeper 上面。

2. HBase 0.96 以后
HBase 0.96 以后,-ROOT- 表被移除,直接将 .META. 表 HRegion 位置信息存放在 ZooKeeper 中,并将 .META. 表更名为 hbase:meta 。
此时整个流程为: Client → ZooKeeper → hbase:meta → 用户的表的 HRegion 。
hbase:meta 表结构如下:

部分内容如下:


读取数据流程





默认环境下:先从 BlockCache 查找数据,如果没有,再从 MemStore 上查找,如果 MemStore 中也没有,再到 StoreFile 上举行查找。其中 StoreFile 的扫瞄先会使用 Bloom Filter(布隆过滤器) 过滤那些不大概符合条件的 HFile,然后使用 Data Block Index 快速定位 Cell(细胞,单位格),并将其加载到 BlockCache 中,然后从 BlockCache 中读取,目标是为了加快后续的查询,然后在返回结果给客户端。
口试题:为什么 HBase 可以做到百亿数据秒级查询?

总结:
正因为以上流程,即使数据量剧增,也不会导致 HBase 的查询性能下降。同时,HBase 是一个面向列存储的数据库 (列族机制),当表字段非常多时,可以把其中一些字段独立出来放在一部分机器上,而另外一些字段放到另一部分机器分散存储分散列查询。 正是由于如许复杂的存储结构和分布式的存储方式,保证了 HBase 海量数据下的查询服从。
数据刷写



1. 触发机遇

1. 内存阈值
HRegion 中的每个 MemStore 占用的内存凌驾相关阈值 hbase.hregion.memstore.flush.size 时会触发刷写,默以为 128MB。
如果我们的数据增长得很快,达到了 512MB 的时间,除了触发 MemStore 刷写之外,HBase 还会在刷写的时间阻塞所有写入该 Store 的哀求。
2. 内存总和
整个 HRegionServer 的 MemStore 占用内存总和大于相关阈值时会触发刷写。如果达到了 HRegionServer 级别的刷写, 当前 HRegionServer 的所有写操作将会被阻塞,这个阻塞大概会持续到分钟级别。
3. 日志阈值
HBase 使用了 WAL 机制(日志先行),当数据到达 HRegion 时是先写入日志的,然后再被写入到 MemStore。如果日志的数量越来越大,这就意味着 MemStore 中未持久化到磁盘的数据越来越多。当 HRegionServer 挂掉的时间,恢复时间将会变得很长,所以有必要在日志到达一定的数量时举行一次刷写操作
4. 定期刷写
当定时器到达 1 小时 时, HBase 会自动触发刷写。一般发起调大,比如 10 小时,因为很多场景下 1 小时 Flush 一次会产生很多小文件,一方面导致 Flush 比较频繁,另一方面导致小文件很多,影响随机读性能。
5. 更新频率
如果 HBase 的某个 HRegion 更新的很频繁,而且既没有达到自动刷写阀值,也没有达到内存的使用限制,但是内存中的更新数量已经足够多,比如凌驾 hbase.regionserver.flush.per.changes 参数配置,默以为 30000000 次,也会触发刷写。
6. 手动刷写
  1. hbase> flush 'TABLENAME'     //TABLENAME(表名)
  2. hbase> flush 'REGIONNAME'    //REGIONNAME(区名)
  3. hbase> flush 'ENCODED_REGIONNAME' //ENCODED_REGIONNAME(编码区名)
  4. hbase> flush 'REGION_SERVER_NAME'        //区服务器名
复制代码
7. 留意
以上所有条件触发的刷写操作最后都会查抄对应的 Store 包罗的 StoreFiles 文件数是否凌驾 hbase.hstore.blockingStoreFiles 参数配置的个数,默以为 16。如果满足这个条件,那么当前刷写会被推迟到 hbase.hstore.blockingWaitTime 参数设置的时间后再刷写。
如果是阻塞刷写,HBase 还会哀求压缩 Compaction 或者分割 Split 操作。
刷写策略

HBASE 1.1 之前:MemStore 刷写是 HRegion 级别的。就是说,如果要刷写某个 MemStore ,MemStore 所在的 HRegion 中其他的 MemStore 也是会被一起刷写的(简单的明白:Flush 一个列族时其它列族也会一起 Flush)。

HBASE 2.x 之后:


数据合并



承载了大量 IO 哀求但是文件很小的 HFile,Compaction 本身不会斲丧太多 IO,而且合并完成之后对读的性能会有显 著提升。
1. 合并分类

HBase 根据合并规模将压缩 Compaction 分为了两类:Minor Compaction 和 Major Compaction。

1. Minor Compaction(次要/小 | 小合并)
选取一些小的、相邻的 StoreFile 将他们合并成一个更大的 StoreFile,在这个过程中不做任何删除数据、多版本数据的清理工作,但是会对 minVersion=0 而且设置 TTL 的过期版本数据举行清理。一次 Minor Compaction 的结果是让小的 StoreFile 变的更少而且产生更大的 StoreFile。

2. Major Compaction(重要/大)
将所有的 StoreFile 合并成一个 StoreFile 清理三类无意义数据:被删除的数据、TTL 过期数据、版本号凌驾设定版本号 的数据。一般环境下,Major Compaction 时间会持续比较长,整个过程会斲丧大量体系资源,对上层业务有比较大的影 响。因此线上业务都会关闭自动触发 Major Compaction 功能,改为手动在业务低峰期触发。


2. 合并机遇

触发 Compaction 的方式有三种:MemStore 刷盘、后台线程周期性查抄、手动触发

1. MemStore 刷盘
MemStore Flush 会产生 HFile 文件,文件越来越多就需要 Compact。每次实行完 Flush 操作之后,都会对当前 Store 中 的文件数举行判定,一旦文件数大于配置,就会触发 Compaction。Compaction 都是以 Store 为单位举行的,整个 HRegion 的所有 Store 都会实行 Compact。
2. 周期性查抄
后台线程定期触发查抄是否需要实行 Compaction,查抄周期可配置。线程先查抄文件数是否大于配置,一旦大于就 会触发 Compaction。如果不满足,它会接着查抄是否满足 Major Compaction 条件(默认 7 天触发一次,可配置手动触发)。 周期性查抄线程 CompactionChecker 大概 2hrs 46mins 40sec 实行一次。默认值 1000万毫秒
3. 手动实行
一般来讲,手动触发 Compaction 通常是为了实行 Major Compaction,一般有这些环境需要手动触发合并:

3. 合并策略

1. 线程池
HBase CompacSplitThread 类内部对于 Split、Compaction 等操作专门维护了各自所使用的线程池。和 Compaction 相关的是 longCompactions 和 shortCompactions。前者用来处理大规模 Compaction,后者处理小规模 Compaction。默认值 为 2 * maxFlilesToCompact(默以为 10) * hbase.hregion.memstore.flush.size,如果 flush size 大小是 128M,该参数默认值就是 2 * 10 * 128M = 2.5G。
2. 合并策略
HBase 重要有两种 Minor Compaction 策略:RatioBasedCompactionPolicy(0.96.x 之前) 和 ExploringCompactionPolicy(当前默认)。

3. 文件合并
分别读出待合并 HFile 文件的 KV,并顺序写到位于 ./tmp 目次下的临时文件中,再将临时文件移动到对应 HRegion 的数据目次。将 Compaction 的输入文件路径和输出文件路径封装为 KV 写入 WAL 日志,并打上 Compaction 标记,最后强制实行 Sync。将对应 HRegion 数据目次下的 Compaction 输入文件全部删除。
数据切分

通过切分,一个 HRegion 变为两个近似相同大小的子 HRegion,再通过 balance 机制均衡到不同 HRegionServer上,使体系资源使用更加均衡。
1. 切分缘故起因

1. 数据分布不匀称
同一 HRegionServer 上数据文件越来越大,读哀求也会越来越多。
2. Compaction 性能损耗严重
Compaction 本质上是一个排序合并的操作,合并操作需要占用大量内存,因此文件越大,占用内存越多。
3. 资源泯灭严重
HBase 的数据写入量也是很惊人的,每天都大概有上亿条的数据写入不做切分的话一个热门 HRegion 的新增数据量就 有大概几十G,用不了多长时间大量读哀求就会把单台 HRegionServer 的资源耗光。
2. 触发机遇

在 HBase 中 Split 是一个很紧张的功能,HBase 是通过把数据分配到一定数量的 HRegion 来达到负载均衡的。
在 0.94 版本之前 ConstantSizeRegionSplitPolicy 是默认和唯一的 Split 策略。当某个 Store(对应一个 Column Family) 的大小大于配置值 hbase.hregion.max.filesize 的时间(默认 10G)HRegion 就会自动分裂。
而 0.94 版本之后 IncreasingToUpperBoundRegionSplitPolicy 是默认的 Split 策略。这个策略中,最小的分裂大小和 Table 的某个 HRegionServer 的 HRegion 个数有关,当 StoreFile 的大小大于以下公式得出的值的时间就会 Split。
比方:

我们可以通过配置体系文件来指定 Split 策略,也可以写我们自己的 Split 策略。

HBase 的 RowKey 设计需要遵循以下原则(办理 ROW_KEY 热门题目)







列族设计

1. 最优设计

寻求原则:在公道范围内,尽大概的减少列族。
最优设计:将所有相关性很强的 key-value 都放在同一个列族。如许既能做到查询服从最高,也能保证尽大概少的访问不同的磁盘文件。
控制长度:列族名的长度要尽量小,一个为了节省空间,一个为了加快服从,最好是一个字符,比如 d 表示 data 或 default,v 表示 value。
2. 列族属性

HFile 会被切分为多个大小相称的 Block,每一个 Block 大小可以在创建表列族的时间通过 BlockSize 参数指定,默认是 64K。Block 大的话一次加载进内存的数据就多,扫描查询 Scan 效果好,但是 Block 小的话,随机查询 Get 效果好。
BlockCache:数据块缓存默认是打开的,如果一些比较少访问的数据可以选择关闭缓存。
Compression:压缩会提高磁盘利用率,但是会增长 CPU 的负载,看环境举行控制。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4