01_HBase概述
1. HBase在Hadoop生态圈中的位置
问题:HBase 是什么,用在哪里,解决什么样的问题?
解答:
1)简单来说, HBase 是一种类似于面向列的分布式数据库(集群), 底层利用HDFS 来作为其物理存储(但在特殊情况下也可以使用节点本机的文件系统), 存储稀疏数据;同时借助zookeeper来监测集群节点的运行状态(自带zookeeper或者外部zookeeper);
2)生态角度:HBase并不支持SQL,需要和Hive或者Phonenix结合; 前者一定会利用MapReduce框架,后者则可以绕开MapReduce,因此实时性上后者更好
2. HBase和RDBMS的区别
ACID
ACID 是数据库事务正确执行的四个基本要素:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)
支持事务(Transaction)的数据库系统,必需要具有这四种特性,否则无法保证数据的正确性,交易过程极可能达不到交易方的要求
* 原子性:一个事务要么全部执行,要么全部不执行;如果执行过程中发生错误,需要将事务状态回滚到最开始的状态;举例:两个账户之间的转账交易,一定要保证一个账户减少金额,另一个账户增加相应的金额,而不能出现只完成一半的情况
* 一致性:事务执行过程中的数据变化要跟上;还是转账的例子,1个账户增加x, 另一个账户要相应的减少x, 2个账户的总和不会改变
* 隔离性:两个以上事务的执行不能出现交错执行的状态,类似线程共享数据操作的锁机制,要保证只有1个事务在操作数据(事务串行)
* 持久化:事务执行成功后,该事务对数据的变更持久保存在数据库中,不能无缘无故的恢复到之前的数据状态
行存储和列存储
1)行存储: 数据一次写入,保证数据完整性; 数据取出是取出整行,然后过滤呈现
2)列存储: 只取出需要的列中的某个数据(根据row-key确定); 数据完整性的保证差,存储时只记录有数据的cell (稀疏数据),可以动态增加新的列(多次写入)
HBase和RDBMS的区别
Hbase | RDBMS | |
硬件架构 | 类似于 Hadoop 的分布式集群,硬件成本低廉 | 传统的多核系统,硬件昂贵 |
容错性 | 通过集群软件架构实现,不用担心1个或或几个节点宕机 | 额外的硬件设备及HA软件实现冗余 |
数据库大小 | PB,大表(数亿行,数百万列) | GB、TB |
数据排布方式 | 稀疏的、多个表 | 行和列组织 |
数据类型 | HBase中的数据都是String字符串类型,增删改查,并没有不同数据表之间的join(关联查询) | 多种数据类型 |
事务支持 | 行锁定,ACID只支持单个row级别 | 表锁定和行锁定,全面ACID |
查询语言 | Java API(除非和其他框架配合,Hive等) | SQL |
索引 | 只支持row-key(除非和其他框架配合,Hive等) | 支持 |
吞吐量 | 百万查询/秒 | 数千查询 |
数据在HBase中的排布
1)对于1个传统的行列二维表,HBase的每行数据都有1个row-key,并且一个表中的数据维持有序,根据row-key+CF:qualifier+时间戳做字节排序,数据查询时通过二分法就可以完成快速定位
row-key可以是任意字符串,最大长度64kb, 按照字典序进行排序,在HBase内部保存为字节数组byte array
2)通过Column Family(CF)将相关的列关联在一起, 创建表的时候进行CF指定,也可以在表建立后动态的增加和删除CF
3)CF中的每一列,都是1个qualifier; 1个qualifier只能属于1个CF
4) HBase中的每行数据,都有1个时间戳,默认情况下HBase可以保存同一行3个不同版本的信息
写入数据时,时间戳可以由HBase自动赋值(当前系统时间,精确到毫秒),也可以显式手动赋值
4) HBase中对一行数据的修改,通过新增一行和新时间戳的方式来实现(追加写)
不同版本的数据,根据时间戳倒序的方式来排序
5)在 Hbase 中,Row-key + CF + Qulifier + 一个时间戳 = 才可以定位到一个单元格cell(三维定位:row-key, CF:qualifier, timestamp)
cell中的数据都是二进制,没有数据类型(和RDBMS不同)
6)物理存储时,1个逻辑二维表格会根据CF,拆分为多个文件夹,1个CF对应1个文件夹,文件夹内是多个HFile
7)用户按照 Row-key 查询数据,HBase 会遍历HFile,通过相同的 Row-Key 标识,将相关的单元格组织成行返回,形成逻辑上的行数据
8) row-key 升序排序,CF:qualifier 升序排序, timestamp 倒序排序 (新的时间戳大)
9) HBase是行锁定,尽管可能是只读取某一列,锁定后其他进程不能读写该行记录的任何字段,直到获得行锁的进程操作完成
HBase数据表逻辑结构
HBase逻辑表和物理表映射
HBase中查询数据的三种方式
1)单个row-key, 查询单条记录
2)给定1个row-key范围,查询出多条记录
3)全表扫描,
3. HBase相关模块、HBase表格的特性
* Master
HBase集群的主
1)监测各个RegionServer的状态
2)分配Region给RegionServer (Region是HBase将数据进行分布式的基本单位)
3)平衡RegionServer间的负载
4)元数据管理(Table的结构)
5)权限控制
6)可以多个Master节点,但只有1个Master处于服务状态;工作的Master宕机,再选举1个Master接管HBase集群
*RegionServer
HBase中的数据表,初始只有一个Region,随着记录的增多单个Region的数据量逐渐增大,导致查找效率降低(多次二分查找才能定位到需要的行)
因此当Region增大到一定范围后,Region会进行分裂(1分2),从而产生多个Region,Master会将这些Region分配给不同的RegionServer进行管理,并在RegionServer所在节点的HDFS上进行物理存储
1)1个RegionServer,管理了1个或多个Region
2)RegionServer,对外提供读写服务
3)RegionServer在存储Region时,会尽量本地化(Region的多个CF,生成多个HFile,这些HFile尽量存储在本节点的HDFS上)
3)Client通过本地缓存或zookeeper获取要查询的row-key对应的数据落在那些RegionServer上,并直接连接RegionServer进行数据获取
*zookeeper
1) Zookeeper是HBase Master 的 HA 解决方案。保证了至少有一个 HBase Master 处于运行状态
2)zookeeper负责RegionServer的注册,并在RegionServer出现宕机后通知Master,通过HLog将宕机节点上的Region重新分配到其他RegionServer进行存储
3)zookeeper也存储了RegionServer的寻址列表(某1个table, 位于那些RegionServer), Client后首先通过zookeeper查找应该访问哪一个RegionServer,并且在本地将Table和RegionServer的映射关系进行缓存
HBase工作原理
1、 Client 需要访问 HBase 集群时,需要先和 Zookeeper 通信,找到对应的 Region Server
2、每一个 Region Server 管理着很多个 Region
3、1个Region 存储的数据是有上限的,当达到该上限时(Threshold),Region 会进行分裂,数据也会分裂到多个 Region 中,这样可以提高数据的并行化
4、每个 Region 包含着多个 Store 对象。每个 Store 包含一个 MemStore,和一个或多个 HFile, 1个Store对应逻辑概念中的1个CF
5、数据写入 Region ,会先根据CF,写入 多个Store中的MemStore,并且一般会按照row-key排序,当 MemStore 中的数据需要向底层文件系统倾倒(Dump)时(例如 MemStore 中的数据体积到达 MemStore 配置的最大值),Store 便会创建 StoreFile,而 StoreFile 就是对 HFile 一层封装。所以 MemStore 中的数据会最终写入到 HFile 中, HFile 都存储在 HDFS 之中
6、Region是分布式的基本单位,但不是存储的基本单位;
HBase物理存储
HTable, HRegion, HStore, HFile
HTable/HRegion
1个Table由多行记录组成,每行记录包括:row-key, CF:qualifier, timestamp, value
将Table在行的方向上进行分割,多行记录形成1个HRegion,1个Table划分为多个HRegion
每个HRegion内的记录,都按照row-key字典序进行排序
HRegion有一定的大小限制,初始状态1个Table只有1个HRegion
随着记录不断插入,HRegion开始增大,当增大到一个阈值后,1个HRegion会分裂为近似等分的2个HRegion
随着Table的不断增长,HRegion会越来越多
HRegion存在分裂,同时也可以手工合并,主要目的是让每个Region的请求量相当,尽量不出现某个Region的请求量太大,导致该Region所在的RegionServer负载过大的情况
HBase可以作为mapreduce的输入,1个Region对应1个map(1个split对应1个map)
HRegion的分布
HRegion是HBase分布式存储和负载均衡的最小单位
HBase中的Master负责将不同Table中的Region分配给某个RegionServer进行存储
HStore
HRegion是分布式存储的基本单位(1个HRegion只能属于1个RegionServer),但并不是物理存储的基本单位
HRegion中含有多个CF,而HBase的物理存储基于CF来进行,因此HRegion在存储时内部会划分出多个HStore, 每个HStore负责1个CF的物理存储
HStore内部则由内存部分(Memstrore)和磁盘部分(HFile)构成,数据先写入Memstore,并在Memstore溢出时生成HFile,HFile最终落地到HDFS的Block上
Memstore和HFile中的数据都是有序数据
BlockCache类似HStore中的memstore, 但用途不同,是读缓存;
HFile会有多个,需要定期的进行合并,并尽量本地化HDFS存储
HFile
1) HFile = 多个Data + 1个固定的结尾块
2)每个Data = Header + 多个 Key-Value 的键值对
3)Trailer包含了数据相关的索引信息,系统也是通过结尾的索引信息找到 HFile 中的数据
4)HFile 中的每个Data默认 64KB。如果访问 HBase 数据库的场景多为有序的访问,那么建议将该值设置的大一些。如果场景多为随机访问,那么建议将该值设置的小一些。一般情况下,通过调整该值可以提高 HBase 的性能
5) HFile的合并: 1个HStore(1个CF)最终会有多个HFile存在,HFile又是落地在HDFS,多个HFile就意味着多个HDFS上的小文件,因此需要将每个HStore中的HFile进行合并
Minor Compaction: 选取一些相邻的HFile进行合并,这个过程不处理deleted, expired的数据
Major Compaction: 将1个HStore的所有HFile进行合并生成1个HFile,这个过程会清除3类没有意义的数据:被删除的,过期的,版本号超过限定的
Major Compaction: 持续时间会比较长,整个过程消耗系统资源,对业务系统会有比较大的影响,因此一般会将Major Compaction放在业务低谷期手动进行,而关闭自动的Major Compaction
HLog
1)每个RegionServer会维护1个HLog,是预写日志的一种实现(WAL,Write-Ahead-Log)
2)RegionServer会将对自己维护的所有Region的数据写入、删除,都先记录在自己维护的HLog中
3)HLog中包含多个Region的数据操作记录
4)写入数据: 写入HLog -> 向Client反馈写成功 -> 异步写数据到memstore -> memstore达到一定阈值后dump,生成StoreFile(对HFile的封装)-> HFile通过不同的block散列到HDFS
HBase如何保证数据有效性
基于每个RegionServer维护的HLog来实现
1)每个 Region Server 中都会有一个 HLog ,HLog记录了这个RegionServer上所有Region的数据写入,删除操作
2)如果没有 WAL, Region Server 宕掉,MemStore 还没有写入到 HFile,或者 StoreFile 还没有保存,数据就会丢失
3)RegionServer宕机,将该RegionServer的
3)HFile 本身 HDFS 来保证多副本。默认会有 3 份,本身具有可靠性
HBase的数据映射关系
HBase 是一个有序的、多维 Map,其中每一个 Row-key 映射了许多数据,这些数据存储在 CF 中的 Column
HBase容错
*Master容错
1) 从备选Master中选举出新的Master
2)无master的过程中,读取HBase没有问题,但Region分裂/负载均衡就无法完成
*RegionSever容错
1)zookeeper向Master发送event
2)Master将RegionServer上的Hlog进行切分,并针对各个Region重新分配RegionServer
3)Master将切分后的HLog,发送给新的RegionServer
4) 新的RegionServer, 根据得到的Hlog, 重新恢复出该Region的数据
*zookeeper容错
1)zookeeper集群自己完成,最小3个节点构成
4. HBase的使用
HBase 的使用建议
HBase 并不适合所有问题,其设计目标并不是替代 RDBMS,而是对 RDBMS 的一个重要补充,尤其是对大数据的场景。
当需要考量 HBase 作为一个备选项时,我们需要考察如下几点:
1)有足够多的数据
如果有上亿或上千亿行数据,HBase 才会是一个很好的备选。
2)确认业务上可以不依赖 RDBMS 的额外特性,
例如,列数据类型, 二级索引,SQL 查询语言等。
3)有足够多的硬件资源
一般情况下当 HDFS 的集群小于 5 个数据节点时,也干不好什么事情 (HDFS 默认会将每一个 Block 数据备份 3 分),还要加上一个 NameNode
4)HBase表格设计
*首先,一个 HBase 是否高效,很大程度和 Row-Key 的设计有关。概括起来的宗旨只有一个,那就是尽可能选择一个 Row-Key,可以数据均匀的分布在集群中
更具体的可以参考:
** 当客户端需要频繁的写一张表,随机的 RowKey 会获得更好的性能
**当客户端需要频繁的读一张表,有序的 RowKey 则会获得更好的性能
**对于时间连续的数据(例如 log),有序的 RowKey 会很方便查询一段时间的数据(Scan 操作)
* 其次,ColumnFamily也会需要在不同场景下有不同的设计方案
在 RDBMS中,如果当用户的信息分散在不同的表中,需要根据一个 Key 进行 Join 操作。而在 HBase 中,我们需要设计 CF 来聚合用户所有相关信息。
一个 Region 对应于一个 CF。如果在一个表中定义了多个 CF 时,就必然会有多个 Region。当 Client 查询数据时,就不得不查询多个 Region。这样性能自然会有所下降,因此在大多数的情况下,一个表格不会超过 2 到 3 个 CF,而且很多情况下都是 1 个 CF 就足够了。
HBase中的特殊表
.ROOT表, .META表, 是HBase中特殊的两张表
1).ROOT表,记录.META表的Region信息
2).META表, 记录了用户表的HRegion信息 (Table, row-key, region, regionserver)
3).ROOT表,大小上只有一个Region; .META表,只有1个Region,不做Region分裂
4) 老版本的zookeeper中,通过znode记录了.ROOT表所在的RegionServer; 新版本的zookeeper则记录.META表的RegionServer
5)Client缓存row-key记录所在的HRegion及RegionServer地址