HBase 是一个通过大量廉价机器解决海量数据的调整存储和读取的分布式数据库解决方案
HBase 的特点:
- 高并发,易扩展,解决海量数据集的随机实时增删改查
- HBase 本质依然是 Key-Value 数据库,不支持 join 等复杂操作
- 不支持复杂的事务,只支持行级的事务
- HBase 中支持的数据类型:byte[] (底层所有数据的存储都是字节数组)
- 主要用来存储结构化和半结构化的松散数据
HBase 中表的特点:
- 大:一个表可以有上十亿行,上百万列
- 面向列:列可以灵活指定,面向列(族)的存储和权限控制,列(族)独立检索
- 稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏
- 无严格模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列
1. HBase 的表结构
HBase 的本质是 Key-Value 数据库,Key 是行键 RowKey,value 是所有真实 key-value 的集合。
HBase 可以抽象成为一张四维表格,四维分别是:行键(RowKey)、列簇(Column Family)、列(Column)、时间戳(TimeStamp)。其中,一张 HBase 的所有列划分为若干个列簇(Column Family),即一个列簇包含一个或多个列。
1.1 行键(RowKey)
与 NoSQL 数据库一样,RowKey 是用来检索记录的主键。访问 HBase Table 中的行,有如下三种方式:
- 通过单个 RowKey 访问
- 通过 RowKey 的 range 访问
- 全表扫描
RowKey 可以是任意字符串(最大长度是 64KB,实际应用中一般为 10-100bytes),最好是 16bytes。在 HBase 内部,RowKey 保存为字节数组。HBase 会对表中的数据按照 RowKey 排序(字典排序)
在进行数据存储时要将经常一起读取的数据存放在一起(通过 RowKey 的字典排序的特性实现)
Note:行的一次读写是原子操作(无论一次读写多少列)
1.2 列簇(Column)
HBase 表中的每个列,都归属于某个列簇。Column Family 是表 Schema 中的一部分(Column 不是),必须在创建表的时候指定。指定好了列簇就不能更改。列簇可以增加或者删除,删除的时候会删除这个列簇中的所有数据。
列名都是心列簇作为前缀,例如:courses:History, courses:Math 都属于 courses 这个列簇。访问控制、磁盘和内存的使用统计都是在列簇层面进行的。
列簇越多,在读取一行的数据时所要参与 IO、搜寻的文件就越多,所以,如无必要,不要设置太多的列簇,官网推荐是小于等于 3(最好就是一个列簇)
1.3 时间戳(TimeStamp)
HBase 中通过 RowKey 和 Column 确定的为一个存储单元,称为 Cell。每个 Cell 都保存着同一份数据的多个版本。版本通过时间戳来索引。
时间戳的类型是 64 位整型,时间戳可以由 HBase (在数据写入时自动)赋值,此时,时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。
如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个 Cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。HBase 在查询的时候,默认返回最新版本/最近的数据。如果需要读取旧版本的数据,可以指定时间戳。
为避免数据存在过多版本造成的管理(包括存储和索引)负担,HBase 提供了两种数据版本回收方式:
保存数据的最新 n 个版本
保存最近一段时间内的所有版本(设置数据的生命周期 TTL–>Time To Live)
用户可以针对每个列簇进行设置
1.4 单元格(Cell)
由 {RowKey, Column(= + ), Version} 唯一确定的单元。
Cell 中的数据是没有类型的,全部都是字节码形式存储。
2. HBase 的应用场景
-
半结构化或非结构化数据
对于数据结构字段不够确定或杂乱无章很难按一个概念去进行抽取的数据适合用 HBase,而且 HBase 是面向列的,HBase 支持动态增加字段。 -
记录非常稀疏
RDBMS 的行有多少列是固定的,为 null 的列浪费了存储空间。而 HBase 为 null 的 Column 是不会被存储的,这样既节省了空间又提高了读性能。 -
多版本数据
对于需要存储变动历史记录的数据,使用 HBase 就再合适不过了。HBase 根据 RowKey 和 Column Key 定位到的 Value 可以有任意数量的版本值。 -
超大数据量的随机、实时读写
当数据量越来越大,RDBMS 数据库就撑不住了,此时就出现了读写分享策略,通过一个 Master 专门负责写操作,多个 Slave 负责读操作,服务器成 本倍增。随着压力增加,Master 撑不住了,这时就要分库了,把关联不大的数据分开部署,一些 join 查询就不能用了,需要借助中间层。随着数据量的进一步增加,一个表的记录越来越大,查询就变得很慢,于是又得分表,比如按 ID 取模分成多个表以减少单个表的记录数。而采用 HBase 就简单的多,只需要增加节点即可,HBase 会自动水平切分扩展,跟 Hadoop(HDFS) 的无缝集成保障了其数据可靠性和数据分析的高性能(MapReduce)。
3. HBase 集群结构
- Region:
是 HBase 将一个表中的所有数据按照 RowKey 的不同范围进行切割的逻辑单元,每个 Region 负责一定范围数据的读写访问。Region 由 RegionServer 负责管理。HBase 中的 Region 的概念就和 HDFS 中的数据块概念差不多,Region 是 HBase 表切分出来的一个 Block,数据块是 HDFS 中的一个大文件切片出来的一个 Block。
HMaster: HBase 的主节点,负责整个集群的状态感知、负载分配、负责用户表的元数据(Schema)管理(可以配置多个用来实现 HA),HMaster 负载压力相对于 HDFS 的 NameNode 会小很多。HBase 的 HMaster 其实就算是宕机一段时间也可以正常对外提供服务。 - RegionServer:
HBase 中真正负责管理 Region 的服务器,也就是负责为客户端进行表数据读写的服务器。每一台 RegionServer 会管理很多的 Region,一个 RegionServer 上面管理的所有 Region 并不属于同一张表。负责 Region 的拆分,负责和底层的 HDFS 的存储交互,负责 StoreFile 的合并。 - ZooKeeper:
整个 HBase 中的主从节点协调,元数据的入口,主节点之间的选举,集群节点之间的上下线感知等都是通过 ZooKeeper 来实现。 - HDFS:
用来存储 HBase 的系统文件,或者表的 Region 文件。 - Client:
Client 包含了访问 HBase 的接口,另外 Client 还维护了对应的 Cache 来加速 HBase 的访问,比如 Cache 的 .META 元数据。
4. HBase 和 Hive 的比较
-
相同点:
HBase 和 Hive 都是架构在 Hadoop 之上,用 HDFS 做底层的数据存储,用 MapReduce 做数据计算。 -
不同点:
- Hive 是建立在 Hadoop 之上为了降低 MapReduce 编程复杂度的 ETL 工具
HBase 是为了弥补 Hadoop 对实时操作不足的缺陷 - Hive 表是纯逻辑表,因为 Hive 的本身并不能做数据存储和计算,而是完全依赖 Hadoop
HBase 是物理表,提供了一张超大内存 Hash 表来存储索引,方便查询 - Hive 是数据仓库式,需要全表扫描,就用 Hive,因为 Hive 是文件存储
HBase 是数据库,需要索引访问,则用 HBase,因为 HBase 是面向列的 NoSQL数据库 - Hive 表中存入数据(文件)时不做校验,属于读模式存储系统
HBase 表插入数据时,会和 RDBMS 一样做 Schema 校验,所以属于写模式系统 - Hive 不支持单行记录操作,数据处理依靠 MapReduce,操作延时高
HBase 支持单行记录的 CRUD,并且是实时处理,效率比 Hive 高得多