1. HBase的结构(基础 & 重点!!!)

XX.png

YY.png

图片来源:尚硅谷大数据HBase课程

HBase的结构非常重要!!!一定要牢记分清!

对比MySQL记忆

HBaseMySQL
NameSpaceDataBase
TableTable
Row keyid
columns familycolumns...
RegionSELECT * FROM TABLE WHERE nu BETWEEN AND j
StoreSELECT columns... FROM TABLE WHERE id BETWEEN AND j

2. Read

R.png

2.1 读数据的流程

  • Step1:客户端递交请求到ZooKeeper,获取HBase集群的meta表存放在哪一个RegionServer(Linux设备)上
meta表记录了HBase中所有表的元数据,包括各个表的Region的元数据(分配在哪个RegionServer上、Row key范围等等)。注意:meta本身也是一张表,因此也需要存储在RegionServer上
  • Step2:客户端根据ZooKeeper返回的meta表找到meta表存放的RegionServer,并和该RegionServer建立通信,读取meta表信息,获取查询指令【查询指令中包含条件:Table & Row key】需要检索的Region存放在哪个RegionServer上
Step1得到的mata表元数据(meta表的存储位置)和Step2得到的Region的元数据(该Region的所在位置和Row key范围)会被客户端作为缓存,一定时间内查询相近数据时能够直接读取缓存进行定位,提高查询效率
  • Step3:客户端得到需要的Region位置后,与该Region所在的RegionServer进行通信并读取需要的数据记录(重点分析步骤)

2.2 Step3的深入分析

对Step3的深入分析前首先必须明确Store的结构:MemStore(内存) + HFile(写入到磁盘的文件) + Block Cache(一个缓存区,也是内存)。MemStore和Block Cache都是实时运行的内存,前者存放着尚未Flush为HFile的数据,后者则保存着之前读取的缓存记录(缓存的是HFile中的数据记录,MemStore本身也是内存,没必要进行缓存)
1596564038(1).png

以上图为例,当Block Cache中无缓存时,读取数据的数据流程相当于将HFile1和HFile2加载到内存MemStore中,与MemStore中本就存在的数据记录一起进行筛选,返回符合查找条件的数据记录。而如果在HFile2中找到了满足条件的记录,Block Cache会对HFile2进行缓存,下一次的查找就会检索Block Cache、MemStore和HFile1中的数据,少了一次文件的IO,会提升查找效率

3. Write

W.png

3.1 写数据的流程

写数据的流程前两步和读数据一样,都是经过ZooKeeper定位到所需要进行操作的RegionServer

一般来说,写入数据的流程应该是先写入到内存,[进行排序(写入多条时)],然后再刷写到磁盘上。但这个机制在大数据场景下有很严重的风险,当大量数据写入并在MemStore中进行排序时,如果设备出现断电等故障,将会丢失大量数据。因此在Hbase中,RegionServer维护了一个WAL文件,充当临时的写入文件,当发生写入时,数据行先是写入到WAL中,然后再加载到MemStore中进行排序后刷写到HFile中,这样即便中途断电等故障,事后重启HBase服务也不会丢失这些数据。

3.2 Flush机制

那么,Hbase什么时候,或者说什么条件下才会触发刷写(Flush)机制,将MemStore中的数据写入磁盘成为HFile文件呢?

  • 手动Flush:在HBase客户端命令行中执行flush + 表名即可将当前表的所有Store中MemStore的所有数据排序后刷写为一个HFile文件
  • MemStore达到内存限制:阻塞写的Flush和不阻塞写的Flush
<!--触发该条件的Flush不会阻塞写操作,可并发进行-->

<!--单个MemStore的最大内存,当实际达到这个限制,会触发Flush-->
<property>  
        <name>hbase.hregion.memstore.flush.size</name>  
        <value>134217728</value>  
        <description>  
            Memstore will be flushed to disk if size of the memstore  
            exceeds this number of bytes. Value is checked by a thread that runs  
            every hbase.server.thread.wakefrequency.  
        </description>  
</property>
<!--触发以下参数的Flush会阻塞写操作,即Flush完成前不支持写入-->

<!--Region中所有MemStore实际大小总和为默认单个MemStore分配内存大小的倍数-->
<property>  
       <name>hbase.hregion.memstore.block.multiplier</name> 
       <value>4</value>  
</property>  


<!--可以理解为一个安全的设置,有时候集群的“写负载”非常高,写入量一直超过flush的量,
这时,我们就希望memstore不要超过一定的安全设置。在这种情况下,写操作就要被阻塞一直
到memstore恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 * 0.4 * 0.95,也就
是当regionserver级别的flush操作发送后,会阻塞客户端写,一直阻塞到整个regionserver级
别的memstore的大小为 堆大小 * 0.4 *0.95为止 --> 
<property>  
    <name>hbase.regionserver.global.memstore.size.lower.limit</name>          
    <value></value> 
</property>  

<!--整个RegionServer中为所有Store分配的MemStore内存大小占堆内存的比例,默认为0.4-->
<property>
    <name>hbase.regionserver.global.memstore.size</name>  
    <value></value>   
</property>  
  • 到达自动刷写时间
<!--这个时间是指内存中最后一条数据最后一次编辑的时间之后如果1小时没有数据操作,将会触发自动刷写-->
<property>  
    <name>hbase.regionserver.optionalcacheflushinterval</name>
    <value>3600000</value>  
        <description>  
            Maximum amount of time an edit lives in memory before being automatically  
            flushed.  Default 1 hour. Set it to 0 to disable automatic flushing.  
        </description>      
</property>  
  • WAL文件数量达到限制:当WAL文件的数量超过32个时,region 会按照时间顺序依次进行刷写,直到WAL文件数量减小到32以下

Chord_Gll
51 声望74 粉丝

每一个领跑者,都曾是优秀而虔诚的追赶者


引用和评论

0 条评论