图片来源:尚硅谷大数据HBase课程
HBase的结构很是重要!!!必定要牢记分清!缓存
对比MySQL记忆安全
HBase | MySQL |
---|---|
NameSpace | DataBase |
Table | Table |
Row key | id |
columns family | columns... |
Region | SELECT * FROM TABLE WHERE nu BETWEEN AND j |
Store | SELECT columns... FROM TABLE WHERE id BETWEEN AND j |
meta表记录了HBase中全部表的元数据,包括各个表的Region的元数据(分配在哪一个RegionServer上、Row key范围等等)。注意:meta自己也是一张表,所以也须要存储在RegionServer上
Step1获得的mata表元数据(meta表的存储位置)和Step2获得的Region的元数据(该Region的所在位置和Row key范围)会被客户端做为缓存,必定时间内查询相近数据时可以直接读取缓存进行定位,提升查询效率
对Step3的深刻分析前首先必须明确Store的结构:MemStore(内存) + HFile(写入到磁盘的文件) + Block Cache(一个缓存区,也是内存)。MemStore和Block Cache都是实时运行的内存,前者存放着还没有Flush为HFile的数据,后者则保存着以前读取的缓存记录(缓存的是HFile中的数据记录,MemStore自己也是内存,不必进行缓存)并发
以上图为例,当Block Cache中无缓存时,读取数据的数据流程至关于将HFile1和HFile2加载到内存MemStore中,与MemStore中本就存在的数据记录一块儿进行筛选,返回符合查找条件的数据记录。而若是在HFile2中找到了知足条件的记录,Block Cache会对HFile2进行缓存,下一次的查找就会检索Block Cache、MemStore和HFile1中的数据,少了一次文件的IO,会提高查找效率ide
写数据的流程前两步和读数据同样,都是通过ZooKeeper定位到所须要进行操做的RegionServer大数据
通常来讲,写入数据的流程应该是先写入到内存,[进行排序(写入多条时)],而后再刷写到磁盘上。但这个机制在大数据场景下有很严重的风险,当大量数据写入并在MemStore中进行排序时,若是设备出现断电等故障,将会丢失大量数据。所以在Hbase中,RegionServer维护了一个WAL文件,充当临时的写入文件,当发生写入时,数据行先是写入到WAL中,而后再加载到MemStore中进行排序后刷写到HFile中,这样即使中途断电等故障,过后重启HBase服务也不会丢失这些数据。this
那么,Hbase何时,或者说什么条件下才会触发刷写(Flush)机制,将MemStore中的数据写入磁盘成为HFile文件呢?spa
flush + 表名
便可将当前表的全部Store中MemStore的全部数据排序后刷写为一个HFile文件<!--触发该条件的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>