ITPub博客

首页 > 大数据 > > Hbase快速入门(超精炼总结)

Hbase快速入门(超精炼总结)

作者:浪花小雨滴 时间:2020-05-09 10:40:03 0 删除 编辑

基本概念:

HBase是列簇式Key-Value存储系统,构建在HDFS之上的、支持随机插入和删除。

总结Hbase的架构核心,就两个字“有序” 。

磁盘的读写,随机与顺序,相差3个数量级(也就是300倍左右)【注意这里与存储介质无关】

逻辑上:

  1. rowkey(行键):唯一标识一行数据。 (等同于RDMS中主键)
  2. column family(列簇):包含多个列,组成一个簇。
  3. column qualifier(列标识):表的每列数据可通过family:qualifier唯一标识
  4. timestamp(数据版本):cell内部数据是多版本的,时间戳作为版本号。(默认最大保留三个版本,如果读取数据时未指定版本号,只会返回最新版本的值)
  5. 可以将[rowkey, column family, coluomn qualifier, timestamp]看做key,cell的值为value。

物理上:

Hbase 是由三种类型的 server 组成的的主从式(master-slave)架构:
  1. Region Server 负责处理数据的读写请求,客户端请求数据时直接和 Region Server 交互。(每个 Region Server 可以管理约 1000 个 regions(它们可能来自一张表或者多张表))
  2. HBase Master 负责 Region 的分配,DDL(创建,删除 table)等操作。
  3. Zookeeper,作为 HDFS 的一部分,负责维护集群状态。

存储结构:

rowkey

  1. 按照rowkey的范围[startKey, endKey],将数据划分成多个region(类似于分区),每个 region 的默认大小为 1GB。
  2. HBase 表中的数据是按照rowkey数据字典顺序升序排列。
  3. rowkey既要方便查找和定位,又要保证数据均衡分布在RegionServer上(分区均匀),避免数据热点、数据倾斜。

column family

  1. 相同的列簇的数据会分开存储在不同的目录下。

Region Server的内存主要分为两部分

  1. Memstore,主要用作写缓存;(每个 Region 的每个 Column Family 都会有一个 MemStore)
  2. BlockCache,主要用作读缓存;(Block是HBase中最小的数据存储单元,默认为64K,HBase会将一次文件查找的Block块缓存到Cache中,以便后续同一请求或者邻近数据查找请求)
  3. 默认情况下,BlockCache和Memstore的配置各占40%。

为何如此快

顺序写入,与顺序读取,是最重要的。

推数快(write):

  • WAL:(Write Ahead Log) 是分布式文件系统上的一个文件,用于存储新的还未被持久化存储的数据,它被用来做故障恢复。
  • MemStore:(写缓存),在内存中存储了新的还未被持久化到硬盘的数据。当被写入硬盘时,数据会首先被排序,注意每个 Region 的每个 Column Family 都会有一个 MemStore。
  • 视觉层面的快,内部并未持久化:
  1. 新数据会被追加到 WAL 文件尾部;
  2. 然后加入Memstore,停驻内存中;(Region Server会给每个region提供一个Memstore)
    1. 触发持久化两种情况:
      1. 溢出:当Memstore满128M(hbase.hregion.memstore.flush.size)以后,会启动flush刷新到磁盘。
      2. 当Memstore的总大小超过限制时(heapsizehbase.regionserver.global.memstore.upperLimit0.9),会强行启动flush进程,从最大的Memstore开始逐个flush。


取数快(read):

    • Meta table(它其实是一张特殊的 HBase 表),包含了集群中所有 regions 的位置信息。Zookeeper 保存了这个 Meta table 的位置
    • 因为使用了LSM树型结构。
    • 客户端读写数据,实际上分了两步(强一致性保证)
      • 定位:从 Meta table 获取 rowkey 属于哪个 Region Server 管理。
      • 取数:去相应的 Region Server 读写数据。
  1. 从 Block Cache 读取 cells。(最近读取的 KeyValue 都被缓存在这里,这是 一个 LRU 缓存)
  2. 若取不到,则读MemStore,即写缓存。(包含了最近更新的数据)
  3. 没有在 Block Cache 和 Mem Store 都没找到对应的 cells,则 HBase 会使用 Block Cache 中的索引和布隆过滤器来加载对应的 HFile 到内存,查找到请求的 row cells。

内部优化:

  1. 内存孔洞问题,MemStore刷写数据到磁盘,产生的问题:
    RegionServer内存碎片增多,当生存时间较长的数据从堆的老年代空间刷写到磁盘,内存碎片增多,连续存储空间减少,就会产生内存孔洞。

解决方案: 启用本地memstore分配缓存区(Memstore-Local Allocation Buffers,MSLAB),也就是允许从堆中分配相同大小的对象,一旦这些对象分配并且最终被回收,就会在堆中留下固定大小的孔洞,这些孔洞可被重复利用,GC就无需使应用程序进程停顿来回收内存空间


2. 读放大(read amplification),每个 MemStore 可能会有多个 HFile:

解决方案:minor compaction,HBase 会自动合并一些小的 HFile,重写成少量更大的 HFiles,它使用归并排序算法,将小文件合并成大文件,有效减少 HFile 的数量。

3.写放大(Write Amplification),major compaction 会重写所有的 HFile,会产生大量的硬盘 I/O 和网络开销,它会将那些远方的数据重新移回到离 region server 节点附近的地方。

4. region分裂(split)

一开始每个 table 默认只有一个 region。当一个 region 逐渐变得很大时,它会分裂(split)成两个子 region,每个子 region 都包含了原来 region 一半的数据。

这两个子 region 并行地在原来这个 region server 上创建,这个分裂动作会被报告给 HMaster。处于负载均衡的目的,HMaster 可能会将新的 region 迁移给其它 region server。

5. 字段占用空间,尽量小:

每行数据中不同版本的cell value会重复保存【rowkey,column family,column qualifier】,数据在进行持久化到HFile文件时、读缓存(BlockCache)、写缓存(MemStore)都会用这几个字段,为了节省存储空间、内存空间和网络传输数据量,这几个字段值应尽可能短。

rowkey的设计就要在读写性能、数据热点、范围扫描之间进行取舍的艺术。


3种Block Cache方案:

1. LRUBlockCache是最初的实现方案,也是默认的实现方案。

a. 将所有数据都放入JVM Heap中,交给JVM进行管理。

b. 将内存从逻辑上分为了三块:single-access区、mutil-access区、in-memory区,分别占到整个BlockCache大小的25%、50%、25%。

c. 一次随机读中,一个Block块从HDFS中加载出来之后首先放入signle区。

d. 后续如果有多次请求访问到这块数据的话,就会将这块数据移到mutil-access区。

e. 而in-memory区表示数据可以常驻内存,一般用来存放访问频繁、数据量小的数据,比如元数据,用户也可以在建表的时候通过设置列族属性IN-MEMORY= true将此列族放入in-memory区。

2. SlabCache,HBase 0.92版本实现了第二种方案。(已废弃)

a. SlabCache BucketCache 这两种采用了不同机制将部分数据存储在堆外,交给HBase自己管理

3. BucketCache, HBase 0.96之后官方提供了另一种可选方案。(阿里提供的方案)

a. 这种演变过程是因为LRUBlockCache方案中JVM垃圾回收机制经常会导致程序长时间暂停,而采用堆外内存对数据进行管理可以有效避免这种情况发生。

b. 在初始化的时候就申请了一片固定大小的内存作为缓存,缓存淘汰不再由 JVM管理,数据Block的缓存操作只是对这片空间的访问和覆盖,因而大大减少了内存碎片的出现,降低了Full GC发生的频率。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3122032/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 安装docker
请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39904