HBase笔记:原理与最佳实践

一、HBase简介

HBase 是一种分布式、面向列的 NoSQL 数据库,其设计思想来源于 Google 的 Big Table。HBase 能存储并处理海量的数据,仅需使用普通配置的硬件,就能够处理大型数据。HBase 与传统关系型数据库的对比:

对比

本文从 HBase 的逻辑结构、数据结构、物理架构三个方面介绍 HBase 的原理与架构。

二、逻辑结构

HBase逻辑结构
  • 行键(Rowkey):行键是 HBase 用来检索记录的主键。行键可以是任意字符串,存储时按照行键的字典序排序存储。访问 HBase 中的行有三种方式:(1)通过单个行键访问;(2)通过行键的范围查询访问;(3)使用过滤器进行全表扫描。
  • 列族(Column Family):HBase中的每个列都归属于某个列族,列族在使用表之前定义,后续修改成本较大。HBase中列族数量有限制。
  • 列(Column):一般都是从属于某个列族,跟列族不一样,列的数量一般的没有强限制的,一个列族当中可以有数百万个列,而且这些列都可以动态添加的。
  • 时间戳(Time Stamp):HBase 中同一个数据可以被保存多个版本,版本通过时间戳来索引。

通过 {行键,列族,列,时间戳} 可以唯一确定一个列单元(Cell)并获取数据。和关系型数据库不同的是,HBase 中的数据是没有类型的,都是以字节码形式存储。

Rowkey设计

一条数据的唯一标识就是 rowkey。一个 HBase 数据库是否高效,很大程度会和 rowkey 的设计有关。随着数据访问方式的不同,rowkey 的设计也会有所不同。不过概括起来的宗旨只有一个,那就是尽可能选择一个 rowkey,可以使你的数据均匀的分布在集群中。具体的建议如下:

  1. 当客户端需要频繁的写一张表,随机的 rowkey 会获得更好的性能。
  2. 当客户端需要频繁的读一张表,有序的 rowkey 则会获得更好的性能。
  3. 对于时间连续的数据(例如 log),有序的 rowkey 会很方便查询一段时间的数据(Scan 操作)。

常用的打散 rowkey 的方案:

  • 生成随机数、hash、散列值
  • 字符串反转
  • 字符串拼接

二级索引

HBase 不像 MySQL,它本身是没有二级索引的,只能根据 rowkey 来访问行。二级索引表就是把需要作为索引的列,拼到 rowkey 中,对应的列多了一个主表的 row key。通过上面的方法,确定出二级索引表的 start row key和 end row key,然后根据 filter 和索引表的列,过滤出需要行,取出其中的主表 rowkey 值,再去主表通过单个 rowkey 访问。

三、数据结构

很多数据库或文件系统都使用 B+ 树作为存储数据的数据结构,但是HBase 却使用的是 LSM(Log-Structured Merge Tree)树,这是为什么呢?

B+树

B+ 树虽然适合在磁盘中存储,并且从原理上来看它的读速度很快。但是它并非总是顺序读写磁盘,例如它的节点进行分裂操作时在内存中会拆成两个新的页表,存储到磁盘上很可能就是不连续的;或者其他更新插入删除等操作,需要循环利用磁盘快,也会造成不连续问题。这也是 HBase 不使用 B+ 树的原因,不进行优化的话随机 I/O 太多,范围查询和大量随机写时尤其明显。

LSM 树在读写之间作出取舍,通过牺牲部分读性能,使用顺序写来大幅提高写性能,因此适合写多读少,以及大规模数据读取的场景。

LSM树

LSM 树首先在内存中构建一颗有序的小树,随着小树的逐渐增大,达到一定阈值时会 flush 到磁盘上。所以 LSM 树不像 B+ 树一样是一棵完整的大树,一棵 LSM 树就是一个个 B+ 树合起来。多次flush之后会形成多个数据存储文件,后台线程会按照配置自动将多个文件合并成一个,此时多颗小树就会被合并成一棵大树。但是读取时,由于不知道数据在哪棵小树上,因此必须遍历所有小树(所以才说 LSM 牺牲了部分读的性能),每棵小树内部数据是有序的。查询是先查内存中的部分,再去查磁盘上的部分。

四、物理架构

HBase 物理结构

HBase 是一个分布式数据库,采用的是主从式架构,如上图所示。一个HBase 集群中包括一个 HMaster 和多个 Region Server,通过 Zookeeper 做分布式管理服务。

4.1 主要组件介绍

Zookeeper

HBase 使用 Zookeeper 做分布式管理服务,来维护集群中所有服务的状态。Zookeeper 维护了哪些 servers 是健康可用的,并且在 server 故障时做出通知;Zookeeper 使用一致性协议来保证分布式状态的一致性。

HMaster

  • 管理用户的 DDL 操作(创建、删除、更新表)
  • 统筹协调所有 Region Server:
    (1)启动时分配 Regions,在故障恢复和负载均衡时重分配 Regions
    (2)监控集群中所有 Region Server 实例(从 Zookeeper 获取通知信息)

Region Server

Region Server 是管理一批 Region 的机器节点,负责处理数据的读写请求。客户端请求数据时和 Region Server 交互。Region Server 主要包含以下部分:

Region

HBase 表(Table)根据 rowkey 的范围被水平拆分成若干个 Region。每个 Region 都包含了这个 Region 的 start key 和 end key 之间的所有行(row)。Regions 被分配给集群中的某些节点来管理,即 Region Server,由它们来负责处理数据的读写请求。每个 Region Server 大约可以管理 1000 个 regions。

HLog

又叫 WAL(Write Ahead Log )是分布式文件系统上的一个文件,所有写数据会首先被写入该文件中(更新 WAL 是在文件尾部追加的方式,这种磁盘操作性能很高,不会太影响请求的整体响应时间),它被用来做故障恢复。

MemStore

写缓存,在内存中存储了新的还未被持久化到硬盘的数据。注意每个 Region 的每个 Column Family 都会有一个 MemStore。MemStore 中累积了足够多的的数据后,整个有序数据集就会被写入一个新的 HFile 文件到 HDFS 上。整个过程是一个顺序写的操作,速度非常快,因为它不需要移动磁盘头。

HFile

HFile 在硬盘上(HDFS)存储 HBase 数据,以有序 KeyValue 的形式。HBase 为每个 Column Family 都创建一个 HFile,里面存储了具体的 Cell,也即 KeyValue 数据。HFile 使用类似于 B+ 树的索引来查询数据。

下图是数据的逻辑存储与物理存储的映射关系:

数据映射

4.2 HBase读流程

  1. Client 先访问 zookeeper,获取是哪一台 Region Server 负责管理 meta table
  2. 访问该Region Server,根据 namespace、表名和 rowkey 在 meta table 中找到对应的 Region 信息,及其 Region Server。客户端会缓存这个信息,以及 meta table 的位置信息本身
  3. 先从 MemStore 找数据,如果没有再到 StoreFile 上读(StoreFile 是对 HFile 的封装)

对于以后的的读请求,客户端从可以缓存中直接获取 meta table 的位置信息,以及之前访问过的 rowkey 的位置信息。除非因为 Region 被迁移了导致缓存失效,这时客户端会重复上面的步骤,重新获取相关位置信息并更新缓存。

读合并

我们已经发现,每行(row)的 KeyValue cells 可能位于不同的地方,这些 cell 可能被写入了 HFile;可能是最近刚更新的,还在 MemStore 中;也可能最近刚读过,缓存在 Region Server 的读缓存中。所以,当读一行 row 时,一次 read 操作会将缓存、MemStore 和 HFile 中的 cell 进行合并。

由于每个 MemStore 可能会有多个 HFile,所以一次 read 请求可能需要多读个文件,这可能会影响性能,这被称为读放大(Read Amplification)

4.3 HBase写流程

写数据流程

  1. Client 向 Region Server 发送写请求(找到 Region Server 的过程与上文相同)
  2. Region Server 将数据写到 HLog,为了数据的持久化和恢复
  3. Region Server 将数据写到内存(MemStore),并反馈 Client 写成功
  4. 数据Flush:当 MemStore 数据达到阈值,将数据有序写入一个新的 HFile 文件到 HDFS 上,将内存中的数据删除,同时删除 HLog 中的历史数据。然后记录最后写入的数据的最大序列号(sequence number)

Minor Compaction

HBase 会自动合并一些小的 HFile,重写成少量更大的 HFiles。这个过程被称为 minor compaction。它使用归并排序算法,将小文件合并成大文件,有效减少 HFile 的数量。

Major Compaction

Major Compaction 合并重写每个 Column Family 下的所有的 HFiles,成为一个单独的大 HFile,在这个过程中,被删除的和过期的 cell 会被真正从物理上删除,这能提高读的性能。但是因为 major compaction 会重写所有的 HFile,会产生大量的硬盘 I/O 和网络开销。这被称为写放大(Write Amplification)。

Major compaction 可以被设定为自动调度。因为存在写放大的问题,major compaction 一般都安排在周末和半夜。

Region 分裂

一开始每个 table 默认只有一个 Region。当一个 Region 逐渐变得很大时,它会分裂(split)成两个子 Region,每个子 Region 都包含了原来 一半的数据,这两个子 Region 并行地在原来这个 Region Server 上创建,这个分裂动作会被报告给 HMaster。出于负载均衡的目的,HMaster 可能会将新的 Region 迁移给其它 Region Server。

Bulkload

除了通过 api 写入数据之外,HBase 还支持 bulkload 将大量数据进行批量导入,其过程是通过启动 MapReduce 任务直接生成 HFile 文件,再将 HFile 文件注册到 HBase。Bulkload 适合如下场景:

  • 大量数据一次性加载到 HBase
  • 每天定时产出的离线数据
  • 使用 put 加载大量数据到HBase速度变慢,且查询速度变慢时

4.4 小结

上文 HBase 的架构,保证了 HBase 的如下优点:

  • 强一致性: 当 write 返回时,所有的 reader 都会读到同样的值
  • 扩展性:数据变大时 Region 会分裂;使用 HDFS 存储备份数据
  • 故障恢复: 使用 Write Ahead Log (类似于文件系统中的日志)
  • 与 Hadoop 结合:使用 MapReduce 处理 HBase 数据会非常有效率

但是,它也存在一些不足之处,即业务持续可靠性:

  • WAL 回放很慢
  • 故障恢复很慢
  • Major Compaction 时候 I/O 会飙升

参考资料

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容

  • HBase Architectural Components(HBase架构组件) HBase架构也是主从架构,由...
    陌上疏影凉阅读 2,378评论 0 7
  • Hbase概述 Hdfs之上(也可存储在本地)分布式面向列的开源数据存储 Hdfs高可靠有备份分布式(分而治之) ...
    时待吾阅读 836评论 0 3
  • 一、简介 Hbase:全名Hadoop DataBase,是一种开源的,可伸缩的,严格一致性(并非最终一致性)的分...
    菜鸟小玄阅读 2,362评论 0 12
  • 一、HBase简介 Hbase是什么 HBase是一种构建在HDFS之上的分布式、面向列、多版本、非关系型的数据库...
    便利蜂数据平台阅读 971评论 0 4
  • 原创文章,转载请注明原作地址:http://www.jianshu.com/p/0f9578df7fbc 一. 架...
    EchoZhan阅读 15,127评论 4 33