zoukankan      html  css  js  c++  java
  • hbase(一)region

    前言

    文章不含源码,只是一些官方资料的整理和个人理解

    架构总览

     

    这张图在大街小巷里都能看到,感觉是hbase架构中最详细最清晰的一张,稍微再补充几点。

    1) Hlog是低版本hbase术语,现在称为WALs。

    2) 1个region包含了多个store,1个store包含了1个colum family,这样就比较好理解

    3) 1个store包含了多个storefile,1个sotrefile就是1个hfile文件

    这在HDFS路径也能体现,大概长这样

    table/region/column family/hfile

    region

    region就是一些连续的hfile集合,也就是说连续的hfile被存储在一个region目录下。

    我们知道,hbase索引一个数据其实是通过遍历的方式,当然是经过优化的遍历,而region就起到了一个很大的作用。想象一下,如果你要在一堆文件中找到你要的内容,怎么样的文件结构才是更快。

    ·有序

    假如你要找的文件有关键字a,那么如果所有文件是按关键字(hbase的rowkey)排序的,那么a就有迹可循,Hbase采用了lexicographic order(这个单词有点不想单词..)也就是字典排序(ASCII码),对每个rowkey从高位到地位排序。

    ·分块

    Rowkey已经是排序的,但还是要遍历啊,万一有个rowkey是z开头的,不是要哭死。Hfile就出现了,一个hfile里有一段连续的rowkey,并且记录了所有rowkey的长度和整个hfile的rowkey是起始和终止。这样就方便了很多,遍历的时候只要看一个文件夹是否包含了该rowkey,而不用一个一个对比。(先忽略column family机制,bloom filter机制)

    ·进一步分块

    但是hfile还是很多啊,要是把hfile容量扩大也不利用读。

    最容易想到的就是把多个hfile统一管理,再做封装,这里就引申出了region。一些连续的hfile被一个region管理,region记录了rowkey的起始和终止等信息。这样遍历起来又快了很多。

    region split

    上面说的解决了遍历的性能问题,但是region也会变大,就像hfile会变大一样。这时候region split就出现了。

    当region被认为需要split的时候(max size超过阈值),一系列操作就出现了。

    1) region是否需要分割是否regionserver决定的,当需要的时候,通过zookeeper和master沟通一下

    2) regionserver关闭该region,并且把memstore的相关数据flush到hfile。这时候有client来请求,则会抛出NotServingRegionException异常

    3) 找到分割点,也就是midkey,查找流程是这样的。先找到该region中最大的一个hfile,然后找到这个hfile的midkey(在hfilev2版本以上,会在hile末记录midkey,否则需要找到data block数据/2的那个block的startkey作为midkey)

    4) 准备子region的相关环境(路径啊,文件夹啊什么的,都是临时的),创建两个文件来指向父region(也就是待split的region)

    5) 创建两个真正的子region(文件夹),并把那两个文件移过去

    6) regionserver向hbase:meta表发起Put请求,把待分割的region设置为offline,并且增加子region的信息。在这过程中,客户端并不能真正看到子region(还不是独立的region),只是能知道有个父region在split。当put请求成功后,父region才会正真的split。(如果put请求失败了,那么由master分配新的regionserver来重新region split,在此之前会把上一次split失败的相关脏数据清除)

    7) 打开子region,接收写操作。为之后无缝接入服务做准备

    8) regionserver再向hbase:meta表添加相关信息。然后客户端再请求就能搜索到子region。当然由于region是新建的,所以之前的缓存都不可用。

    9) regionserver通过zookeeper和master交互,让master知道有新region split好了。Master可以决定新region由哪个regionserver管理

    10) 最后就是善后工作,由于新region实际上没有父region的数据,只有一些引用来指向父region。所以在子region compaction的时候,会重写这些数据。另外hbase的master还有一个GC task(不是jvm的GC),来定期轮询,查看是否还有引用父region,当没有的时候就删除父region

    总结

    整个流程虽然看上去很复杂,其实效率很高,region split的过程中是不可用的,但是这时间很短,因为不涉及大量的io,只有引用和交互。

    master和regionserver之间的配合,master主要做协调,regionserver做实际的工作

    Region compaction

    其实用storefile compaction来表示更合适,compaction分为两种,compaction和major compaction。参考类`CompactionPolicy`,默认的实现是`ExploringCompactionPolicy`

    Compaction

    如果该列族下总hfile数量-正在合并的hfile数量 >= ` hbase.hstore.compaction.min`默认3,那么就会触发compaction,单次compaction的hfile数量上限是`hbase.hstore.compaction.max`默认10。compaction的定位是主要合并一些小的相邻的hfile,重写进一个新的hfile。重写的过程不包括数据的drop,filter,delete等移除操作,只是简单的把小文件合并成大文件。

    Major Compaction

    参考RatioBasedCompactionPolicy的实现,首先是计算major compaction的时间周期,默认周期是1周,通过配置`hbase.hregion.majorcompaction`。为了避免major compaction风暴(多个region同时major compaction导致hbase服务不可用),hbase还引用了时间偏差`hbase.hregion.majorcompaction.jitter`,默认是0.5,也就是说实际major compaction的时间是总周期上下浮动0.5个周期内的时间。如果需要合并hfiles中最小的文件修改时间戳比当前时间-合并周期小,那么视为可进行major compaction,但是如果只有一个hfile需要marjor compaction,那么hbase还会深入判断ttl和hfile的block本地化系数,从而获取最优解。

    major compaction会把所有需要清除的数据都移除,最终合并成一个storefile。合并过程中服务还是可以使用,但是合并过程中会读取全量的数据,这样会大量的占用磁盘的IO,导致查询效率大幅下降,甚至不可用。

    数据需要被移除一般有三种情况

    1) 客户端显示的声明delete

    2) 某些column family的version超过max version

    3) 某些设置了TTL的column family

    RegionServer和Region

    官方建议一个RegionServer的Region数量控制在100个以内,但是这还受到RegionServer分配的内存大小,由于每个Region都有自己的memstore,而默认的memstore大小为128MB(hbase.hregion.memstore.flush.size),那么100个region直接就会使用10GB的内存

    当全局MemStore的大小超过了该RegionServer内存的hbase.regionserver.global.memstore.upperLimit大小,默认40%的内存使用量。那么此时当前HRegionServer中所有HRegion中的MemStore都会Flush到HDFS中,Flush顺序是MemStore大小的倒序,直到总体的MemStore使用量低于RegionServer的hbase.regionserver.global.memstore.lowerLimit,默认38%的内存使用量。

    参考资料

    //hbase官网推荐的region split 博客

    https://hortonworks.com/blog/apache-hbase-region-splitting-and-merging/

  • 相关阅读:
    Python 爬虫js加密破解(一) 爬取今日头条as cp 算法 解密
    Python 爬虫实例(2)—— 爬取今日头条
    Python 爬虫实例(1)—— 爬取百度图片
    python 操作redis之——HyperLogLog (八)
    python 操作redis之——有序集合(sorted set) (七)
    Python操作redis系列之 列表(list) (五)
    Python操作redis系列以 哈希(Hash)命令详解(四)
    Python操作redis字符串(String)详解 (三)
    How to Install MySQL on CentOS 7
    Linux SSH远程文件/目录 传输
  • 原文地址:https://www.cnblogs.com/ulysses-you/p/7605652.html
Copyright © 2011-2022 走看看