一.概述
再次学习HBase实战和HBase权威指南时,对HBase了解又深了许多。本文列出一些值得关注的点。
二.HBase物理和逻辑存储结构
user表包含两个列族info activity,为此表预分区[1,3) [3,正无穷),此时user表在HBase里的物理和逻辑存储结构如上图。
一个user表的数据存储在两个region上,这两个region可能在一个RegionServer上,也可能在两个不同的RegionServer上。
一个RegionServer可以有多个region,这些region共享一个WAL(write-ahead log预写式日志,也称HLog)。
一个region可以包含多个列族的数据。
一个列族由一个MemStore,一个BlockCache和多个HFile组成。两个不同列族的MemStore BlockCache 毫无关系。
也有书里谈到Store这个概念,实际就是对于一个列族的管辖区域。
三.HBase读写路径
执行写入时会写到两个地方:WAL和MemStore,只有当这两个地方的变化信息都被成功写入并确认后,才认为写动作完成。MemStore填满(hbase.hregion.memstore.flush.size默认64M,在hbase0.96 habse-default里为128M)后被flush到硬盘,所以客户端的写操作不会与底层的HFile直接交互。
从HBase中读出一行,首先会检查MemStore等待被flush的数据,其次检查BlockCache是否包含该行的Block信息,最后访问硬盘上的HFile。BlockCache使用LRU算法,缓存的是Block块而非Block所有。
四.客户端写缓冲区
每一个put操作实际上都是一个RPC操作。当然,HBase的API配备了一个写缓冲区,它负责收集put请求,然后调用RPC操作一次性将put发送给服务器。
注意这个缓冲区位于客户端,默认情况下是禁用的。HTable的setAutoFlush(false)方法可以将自动刷新autoflush设置为false来激活缓冲区。
@Override
public boolean isAutoFlush() {
return autoFlush;
}
Deprecated
@Override
public void setAutoFlush(boolean autoFlush) {
setAutoFlush(autoFlush, autoFlush);
}
/**
* {@inheritDoc}
*/
@Override
public void setAutoFlushTo(boolean autoFlush) {
setAutoFlush(autoFlush, clearBufferOnFail);
}
/**
* {@inheritDoc}
*/
@Override
public void setAutoFlush(boolean autoFlush, boolean clearBufferOnFail) {
this.autoFlush = autoFlush;
this.clearBufferOnFail = autoFlush || clearBufferOnFail;
}
也可以配置此缓冲区大小。默认大小为2MB。
@Override
public long getWriteBufferSize() {
}
public void setWriteBufferSize(long writeBufferSize) throws IOException {
}
当需要强制把数据写到服务器时,使用
@Override
public void flushCommits() throws InterruptedIOException, RetriesExhaustedWithDetailsException {
// As we can have an operation in progress even if the buffer is empty, we call
// backgroundFlushCommits at least one time.
}
此缓冲区没有任何备份,这些数据可能丢失。
五.大小合并 自动分区
首先要明白一个概念,大小合并是针对HFile,自动分区是针对region。
当一个region里的存储文件增长到大于配置的hbase.hregion.max.filesize默认256M时,region会被一分为二。关于分区的过程,我还没弄太明白。
大小合并
小合并:
将多个HFile合并成一个HFile。经过读-合并写-删除步骤。
小合并的文件数量由hbase.hstore.compaction.min默认3且要求大于等于2和hbase.hstore.compaction.max默认10决定。
小合并的文件大小由hbase.hstore.compaction.min.size默认64M和hbase.hstore.compaction.max.size默认Long.MAX_VALUE决定。hase.hstore.compaction.min.size比较奇葩,小于这个值才被include。既然这样,hbase.hstore.compaction.max.si还有何用?
大合并:
将给定region的一个列族的所有HFile合并成一个HFile。
大合并是HBase清理被删除的唯一机会。如果一个单元的版本超过了最大数量,也会在大合并时删掉。
触发大合并:shell命令或客户端API;距离上次大合并是否超过hbase.hregion.majorcompaction默认24小时;小合并的文件就是一个列族的所有文件且满足文件大合并大小要求,小合并被提升为大合并。
六.HFile
我们已经知道HFile的两种来源:由MemStore flush而来,由其它HFile合并而来。所以我们并不知道HFile到底有多大,实际上我们也不需要知道。需要了解的是,HFile只是一个逻辑上的概念,真正存储的是HDFS,而HFile与HDFS的块之间没有匹配关系,HBase把文件透明的存储在HDFS上,如一个HFile232M,将被存储在两个Block上,Block1 128M,Block2 104M。
HFile块大小64KB怎么理解?先看一个HFile的结构。
这里的块指的就是Data块(一系列KeyValue的集合),也就是一个HFile由许多大小为64KB的Data块以及其它项组成。
KeyValue的结构
这个比较好理解。通过此图可以看到,如果一个rowkey存在多个版本,每个版本都将对应一个KeyValue,因为它们TimeStamp不同。
当然HBase还有许多值得深究的地方,后面会不断学习不断更新本文。如有错误,欢迎指出。
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com