HBase 的以前实现中,当一台 RegionServer 不可用时,需要数十秒甚至数分钟才可以完成发现和恢复工作,在这段时间内,这台 RegionServer 上的 Region 是不可用的。当一个 Region 不可用时,它需要一段时间才可以被其他 RegionServer 接管。
在最新的实现中,一个 Region 可以有多个副本(Region 是数据的管理者,是实际数据的抽象),分布在多个 RegionServer 上。
特点:
有一个主 Region,多个从 Region。
只有主 Region 接收写请求,并把数据持久化到 HDFS 上。
从 Region 从 HDFS 中读取数据并服务读请求。
从 Region 可能会读到脏数据(主 Region 内存中的数据)。
读操作可以只读主,或者既可以读主又可读从(可配置)。
这样在主 Region 不可用时,用户仍可以读从 Region 的数据。目前社区在进行的开发:主 Region 异步同步数据到从 Region,从而减少从 Region 缺少的数据量。
Family 粒度的 Flush(减少小文件,优化磁盘 IO,提高读性能 HBASE-10201)
我们先看一下 HBase 的写流程图
数据从客户端写到 RegionServer 上的 Region 后,先写入到内存中,积攒到阈值后写入磁盘,即 LSM-tree 架构。
在以前的实现中,服务端数据从内存刷写到 HDFS 上是 Region 粒度的,Region 下面所有的 Family 都会被 Flush。在很多应用场景中,HBase 中存储的是稀疏数据,在写入一行的数据中,有的 Family 具有值,有的为空,而且不同 Family 中存储的数据大小本身就不同,所以当大的 Family 到达阈值需要刷写数据时,小的 Family 也会跟着刷写,这样会导致很多小文件的产生,影响性能。
在新的实现中,提供了更小粒度的 Flush——Family 级别。它的特点是:
更加合理的使用内存的写延迟和聚合功能
减少 Compaction 的磁盘IO
提高读性能
RPC 读写队列分离(读写隔离,scan 与 get 隔离 HBASE-11355)
之前的实现中,RegionServer 上所有操作共享队列,各种操作互相影响。比如Scan 和 Get,在 RPC Call Queue 中,如果一个大的 Scan 请求排列在 Get 之前,那么 Get 就需要等待之前的 Scan 完成才可以执行,延迟较大。
在现在的实现中,RPC 可以具有多个 Call Queue,同时将它们分配给不同的操作使用,从而实现各种 Put、Scan 和 Get 等操作的隔离。具体配置的参数如下:
不能,因为从 Region 的数据就是过时的,主 Region 才是最新的数据。目前 HBase 的实现中,只有读主 Region 才可以获得最新数据,当主 Region 不可用时,如果可以忍受 stale 的数据,则可以读从 Region 来保证可用性。目前高可用实现的还不太好,这也是社区努力的方向之一。