HBase的介绍与安装教程1(基本介绍、系统架构说明)
作者:hangge | 2020-08-28 08:10
一、基本介绍
1,基本介绍
(1)HBase 的全称是 Hadoop Database。它是一个高可靠、高性能、面向列、可伸缩的 NoSQL 分布式存储数据库。Hbase 依托于 Hadoop 的 HDFS 作为最基本存储基础单元。Hbase 最初是 Apache Hadoop 中的一个子项目,2010 年 5 月,HBase 脱离 Hadoop 项目,晋升为 Apache 的顶级项目。
Hadoop 是这些年崛起的拥有着高性能,高稳定,可管理的大数据应用平台。其已经快变成大数据的代名词了。
Hadoop 实现了一个分布式文件系统(HDFS)。HDFS 有高容错性的特点,被设计用来部署在地低廉的硬件上,而且它提供高吞吐量以访问应用程序的数据,适合那些有着超大数据集的应用程序。基于 Hadoop 意味着 HBase 与生俱来的扩展性和吞吐量。
Hadoop 实现了一个分布式文件系统(HDFS)。HDFS 有高容错性的特点,被设计用来部署在地低廉的硬件上,而且它提供高吞吐量以访问应用程序的数据,适合那些有着超大数据集的应用程序。基于 Hadoop 意味着 HBase 与生俱来的扩展性和吞吐量。
(2)作为一种 NoSQL 数据库,HBase 不像传统的 RDBMS 数据库那样支持 SQL 作为查询语言,也缺少很多 RDBMS 系统的特性,比如列类型,辅助索引,触发器,和高级查询语言等等。不过 HBase 自生也有如下特性:
- 强读写一致,但是不是“最终一致性”的数据存储,这使得它非常适合高速的计算聚合
- 自动分片,通过 Region 分散在集群中,当行数增长的时候,Region 也会自动的切分和再分配
- 自动的故障转移
- Hadoop/HDFS 集成,和 HDFS 开箱即用,不用太麻烦的衔接
- 丰富的“简洁,高效”API,Thrift/REST API,Java API
- 块缓存,布隆过滤器,可以高效的列查询优化
- 操作管理,Hbase 提供了内置的 web 界面来操作,还可以监控 JMX 指标
2,应用场景
(1)超大数据量
- 如果数据库量足够多,比如有十亿及百亿行数据,那么 Hbase 是一个很好的选项。在 百亿行 * 百万列 情况下,Hbase 查询可以做到百毫秒以内。
- 并且随着数据量的增加,只需要动态扩容 HBase 集群的机器即可,HBase 集群会自动水平切分,不需要人工干预。
(1)如果单表数据量不超过千万(比如只有几百万行甚至不到的数据量),使用 MySQL 或者 Oracle 之类的产品会更加适合。因为数据量小的话,真正能工作的机器量少,剩余的机器都处于空闲的状态。而且做数据分析时 RDBMS 也比 HBase 的 MapReduce 来的简单。
(2)RDBMS 面对海量数据的应对策略以及挑战:
(2)RDBMS 面对海量数据的应对策略以及挑战:
- 当数据量越来越大,RDBMS(关系型数据库)“撑不住”了,就出现了读写分离策略。Master 专门负责写操作,多个 Slave 负责读操作,这样会造成服务器成本倍增。
- 随着数据量增加,Master 可能会“撑不住”,这时就要分库,把关联不大的数据分开存储。此时一些 JOIN 查询就不能用了,需要借助中间层。
- 随着数据量的进一步增加,一个表的记录越来越大,查询会变得很慢,于是要分表,减少单个表的记录数。这个过程是非常麻烦的。
(2)半结构化或非结构化数据
- 对于数据结构字段不够确定,或杂乱无章很难按一个概念去进行抽取的数据,适合使用 HBase 进行存储。例如文章的 Tag(标签)信息,它会不断地增加/删除。
提示:每个文章的 Tag 信息是不一样的,并且 Tag 信息会经常变化,用户可能随时会对文章
的 Tag 信息进行修改。
- 如果使用 MySQL 存储,可以选择把文章的所有标签信息通过逗号分割拼接成一个字符串存储到一个字段里面,这样存储的时候方便了,但是使用的时候比较麻烦,每次都需要解析这个字符串进行处理。
- 当然也可以选择在 MySQL 中将每一个标签都存储到一个独立的字段中,这样使用起来比较方便,但是这样表结构就需要经常变化了,可能会存在某一篇文章有 10 个标签信息(需要 10 个标签字段),另一篇文章只有 1 个标签信息的情况(只需要 1 个标签字段),这样表结构中至少需要增加 10 个标签字段,这样就会存在字段冗余的情况,额外浪费存储空间。
(3)记录非常稀疏
- HBase 中值为 NULL 的列不会被存储,这样既节省了空间,又提高了读性能。
提示:RDBMS(关系型数据库)的每一行有多少列是固定的,值为 NULL 的列浪费了存储空间。
(4)多版本数据
- HBase 中的列可以存储多个版本的值,因此,对于需要存储历史变动记录的数据,使用 HBase 就非常方便了。
提示:在 MySQL 中,如果要保存某个列的多个历史版本数据,则只能存储多行记录。
3,优缺点总结
(1)优点
- 高可靠:指的是 HBase 集群支持多个主节点,多个从节点,集群可靠性比较高,并且 HBase 的数据是存储在 HDFS 上的,数据可靠性也比较高。
- 高性能:指的是 HBase 可以存储上亿或者十亿级别的数据,实现毫秒级别查询。
- 支持动态列:支持随时动态增加或者减少列。例如:第一条数据有 10 列,第二条数据可以有 100 列,互相不影响,也不需要修改表结构。
- 支持海量数据存储
- 适合半结构化和非结构化数据
- 适合记录稀疏
- 支持多版本
(2)缺点
- 不支持SQL数据分析:HBase 属于 NoSQL 数据库,所以不支持常见的 SQL 语法。
- 不擅长多条件组合查询:HBase 中根据多个列进行组合条件查询相当于全表扫描,所以效率不高。
- 不适合大范围扫描查询:大范围扫描效率不高,数据量过大时容易导致扫描超时或者失败。
4,集群架构
(1)一般一个 HBase 集群有一个 Master 服务器和几个 RegionServer 服务:
- Master 服务器负责维护表结构消息,可以控制 RegionServer 的故障转移和 Region 的切分。由于其不负责存储数据,因此 Master 挂掉之后我们依然可以查询 、存储、删除数据,但就是不能新建表了。
- RegionServer 是直接负责存储数据的服务器(可理解为数据节点),RegionServer 保存的表数据直接存储在 Hadoop 的 HDFS 上。并且 RegionServer 要实时的向 Master 报告信息,Master 知道全局的 RegionServer 运行情况
(2)ZooKeeper 类似 HBase 中的管家,它管理了 HBase 所有 RegionServer 的信息,包括具体的数据端存放在哪个 RegionServer 上。
- 客户端每次与 HBase 连接,其实都是先与 ZooKeeper 通信,查询出哪个 RegionServer 需要连接,然后在连接 RegionServer。
(3)Region 就是一段数据的集合。HBase 中的表一般拥有一个到多个 Region。Region 有以下特性:
- Region 不能跨服务器,一个 RegionServer 上有一个或者多个 Region
- 数据量小的时候,一个 Region 足以存储所有数据;但是当数据量大的时候,HBase 会拆分 Region。
- 当 HBase 在进行负载均衡的时候,也有可能从一台 RegionServer 上把 Region 移动到另一台 RegionServer 上。
- Region 是基于 HDFS 的,它的所有数据存储操作都是调用了 HDFS 的客户端接口来实现的。
5,全局详细架构
下面从整体到局部详细分析一下 HBase 的底层架构,注意图中的 HMaster、HRegionServer 和 HRegion 对应的就是前面分析的 Master、RegionServer 和 Region。
(1)Client(客户端)在连接 HBase 时,需要先连接 Zookeeper,然后在 Zookeeper 中找到“/hbase/meta-region-server”节点,该节点中存储了 meta 表和 Reginserver 节点的信息。
(2)Clinet 会把 meta 表的信息加载到缓存中,这样就不用每次都去重新加载了。meta 表中存储了 HBase 中所有普通表的相关信息,如果都加载到内存则可能会存不下。所以,客户端并不会加载 meta 表的所有数据,只会把当前需要的相关表信息加载到内存中。
(3)meta 表中存储的有 HBase 表所在的 Regionserver 信息,所以,客户端可以先获取对应 Regionserver 节点的 IP 地址和端口信息,然后通过 RPC 进行远程通信。
(4)HRegionServer 中包含两块内容:HLog 和 HRegion。HLog 只有 1 个,HRegion 有多个。
- HLog 用于负责记录操作日志,会记录 Regionserver 中的所有写操作,包括 Put、Delete 等操作。只要是会对数据产生变化的操作,都会被记录到日志中。在写数据时,会先把具体操作记录到这个日志中,再把数据写到对应的 HRegion 中。
- HRegion 中有多个 Store,每个 Store 对应 1 个列族。所以,1 个 Region 里面可能会有多个 Store。
(5)客户端在写数据时,先写入 HLog,再写入 HRegion。在写入 HRegion 时,会根据指定的列族信息写入不同的 Store 中。所以,在写数据时表名及列族名称都必须指定。
(6)数据在写入 Store 时,会先写入 MemStore(基于内存的 Store)。当 MemStore 写满后,再把数据 Flush 到 StoreFile 文件中。每一次内存满时,做 Flush 时会生成 1 个 HFile 文件。
(7)最终,HLog 和 HFile 都会被 DFS Client(HDFS 的客户端)写入对应的 DataNode 中。
6,HFile 介绍
(1)HFile 是 HBase 中重要的一个存在,可以说是 HBase 架构中最小的结构,HBase 的底层数据都在 HFile 中。HFile 从根本上来说是 HDFS 中的文件,只是它有自己特殊的格式。
(2)HFile 文件由6部分组成:
- Data(数据块):保存表中的数据(key-value 的形式),这部分可以被压缩,每个数据块都有一个 Magic 头,负责存储偏移量和第一个 Key。
- Meta(元数据块):存储用户自定义的 key-value。
- File Info:定长,记录了文件的一些元信息,例如:AVG_KEY_LEN,AVG_VALUE_LEN,LAST_KEY 等
- Data Index(数据块索引):记录了每个数据块(Data)的起始索引。
- Meta Index(元数据块索引):记录了每个元数据块(Meta)的起始索引。
- Trailer:定长,用于指向其他数据块的起始点。
附:存储架构
1,总体介绍
HBase 的存储结构如下,HBase 最基本的单元是列(colume),一个列或者多个列形成一行。每个行(row)都拥有唯一的行键(row key)来标定这个行的唯一性。每个列都有多个版本,多个版本的值存储在单元格(cell)中。若干个列又可以被归类为一个列族。
与传统的关系型数据库对比:
- 传统数据库是严格的行列对齐。比如这行有三列 a、b、c,下行肯定也有三列 a、b、c。其中每个行都是不可分割的,也就是说三个列必须在一起,而且要被存储在同一台机器上,甚至是同一个文件里面。
- HBase 中行跟行的列可以完全不一样,比如这一行有三列 a、b、c,下一个行也许是 4 列 a、e、f、g。并且这个行的数据跟另一个行的数据也可以存储在不同的机器上,甚至同一个行内的列也可以存储在完全不同的机器上。
2,行键(rowkey)
(1)rowkey 类似 MySQL、Oracle 中的主键,不过它是由用户指定的一串不重复的字符串,规则随我们定义。在 HBASE 内部,RowKey 保存为字节数组。提示:RowKey 可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes)
(2)rowkey 决定这个 row 的存储位置。HBase 中无法根据某个 column 来排序,系统永远是根据 rowkey 来排序的,排序规则为:根据字典排序。因此设计 RowKey 时,要充分利用排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)
(1)比如,以下三个 rowkey:
- row-1
- row-2
- row-11
- row-1
- row-11
- row-2
(3)访问 HBASE table 中的行,只有三种方式:
- 通过单个 RowKey 访问
- 通过 RowKey 的 range(正则)
- 全表扫描
(4)插入 HBase 的时候,如果用了之前已经存在的 rowkey 的话,会把之前存在的那个 row 更新掉。
提示:更新后之前存在的值并不会丢掉,而是会被放在这个单元格的历史记录里面,只是我们需要带上版本参数才可以找到这个值。
3,列族(column family)
(1)在 HBase 中,若干列可以组成列族。或者说表中的每个列,都归属于某个列族。(2)建表的时候我们不需要指定列,因为列是可变的。但是一个表有几个列族必须一开始就定好。
(3)表的许多属性,比如过期时间、数据块缓存以及是否压缩等都定义在列族上,而不是定义在表或者列上。
(4)同一个表里的不同列族可以有完全不同的属性配置,但是同一个列族内的所有列都会有相同的属性。
(5)列名都以列族作为前缀。例如 courses:history、courses:math 都属于 courses 这个列族。
(6)列族存在的意义是:HBase 会把相同列族的列尽量放在同一台机器上。所以如果想让某几个列被放在一起,我们就要给他们定义相同的列族。
一个表的列族数量建议越少越好:
- 因为虽然 HBase 是分布式数据库,但是数据在同一台物理机上依然会加速数据的查询过程。而列族太多会极大程度地降低数据库性能(不同列族列会更容易被分配到不同的服务器上)
- 而且根据目前的 HBase 实现,列族定得太多,容易出 BUG。
4,单元格(cell)
(1)虽然列已经是 HBase 的最基本单位,但一个列上可以存储多个版本的值,多个版本的值被存储在多个单元格里,多个版本之间用版本号(Version)来区分。(2)唯一确认一条结果的表达式应该是“行键:列族:列:版本号”(rowkey:column family:column:version)
版本号说明:
- 确定单元时如果不写版本号,HBase 默认获取最后一个版本的数据返回。
- 版本通过时间戳来索引。时间戳的类型是 64 位整型。这个时间戳默认由 Habse(在数据写入时自动)赋值,也可以有用户指定。
- 每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
- 为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBASE 提供了两种数据版本回收方式。一是保存数据的最后 n 个版本,二是保存最近一段时间内的版本(比如最近七天)。 用户可以针对每个列族进行设置。
全部评论(0)