公众号来源:编程新说
作者:李新杰
?§团结力量大 原始社会,由若干血缘相近的宗族、氏族结合起来集体生活,这就是部落。最高首领就是酋长,此外还可能会有军事首领,他们一起繁衍生息。 到了原始社会末期,频繁战争,若干个亲近的或有共同利益的部落,结成暂时的或永久的联盟,一起去和别人PK,这就是部落联盟。 部落联盟的性质和部落相同,它们也有最高首领,权利机关等。中国古籍记载的黄帝、蚩尤,以及尧、舜、禹都是部落联盟的首领。 通过这个事情,至少记住两点:第一个是团结力量大。这很显然。第二个是外交上比较有名的一句话,“没有永恒的敌人,只有永恒的利益”。 ?§把部落搬进计算机 计算机的历史才几十年而已,与人类社会相比,那是货真价实的“后生”。虽然现在计算机已经很厉害了,但是单台的能力总是有上限的。 原始社会都知道团结力量大,那就让计算机团结起来吧。把若干台计算机通过网络结合起来,就形成了计算机界的部落(或部落联盟)。 我们也要选出一台计算机当“酋长”啊,于是被选出来的那一台通常称为Master节点,剩余的称为Slave节点。就是我们常说的Master/Slave。但是Slave有奴隶的意思,会被一些国家反对,所以就有了另外一套叫法,Leader/Follower,中文称为主/从。 这个计算机界的部落就称为集群。 ?§Hbase集群 Hbase的设计目标就是海量存储能力,所以它必须是一个集群。它的“酋长”就称为Master节点,剩余的每个节点就称为Region Server。 酋长为了更好地管理本部落人员,一般还会设置一个最高军事首领,来辅助自己。可以理解为我们常说的军师。 Hbase集群也有自己的“军师”,它就是ZooKeeper。ZooKeeper本身也是一个集群。 酋长这个角色是很重要的,一旦战死,整个部落将群龙无首,容易内讧,所以必须立马再选出一个酋长。 酋长需要具有很强的能力,不是谁都能当的。所以平时需要一个后备酋长时时刻刻候着,以防不测。其实就是个备胎。 所以Hbase中正常的那个Master节点称为Active Master节点,至少还有一个后备的Master节点称为Backup Master节点。这两个Master节点之间经常互通有无,保持信息一致。
一旦这个Active Master节点英勇就义后,由“军师”ZooKeeper负责从Backup Master节点中选出一个成为新的老大。因为它本来就是后备待命状态,所以一上来就可以接替工作,没有“实习期”的。 Master节点主要负责管理类的工作,其余的Region Server节点则主要负责干活了,如数据的读/写等。 ?§化整为零 Hbase是以行的形式实现面向列的存储,其实还是行存。能够支持数十亿行,可见它是一个非常长的表。 实际生活中,超长物体的加工、运输都很麻烦,所以人们就截成一段一段的,分段处理好,最后再拼接到一起。 采用相同的方法,把Hbase的超长表分成若干段,每一段称为一个Region。相当于传统关系型数据库的横向分表。
所有的Region拼接起来就形成了Hbase中的一个完整表。就像所有车厢拼接起来就形成了一列完整的列车一样。 Hbase是面向列的,所以在存入一行数据时,某些列族可以完全没有数据。比如一个刚毕业的学生就没有工作经历,那工作经历这个列族就是空的。 可见列族与列族之间的差别有时非常大,所以存储时也是分开的,即一个列族一个存储,把这个存储称为Store。 所以一个Region里可以有一到多个Store。
?§存储结构 Hbase集群中负责实际数据工作的是很多的Region Server服务器。每个表从逻辑上被切分为很多Region。 很明显最后要把这些Region分配到这些Region Server服务器上,这个分配的工作是由Master节点完成的。
Hbase的设计目标就是要支持实时的读写。所以写入的速度必须要快,还有个隐形的前提就是数据也要安全才行。 数据写入内存的速度非常快(想想Redis),但只有写入磁盘才算安全。 一个Region Server上有很多Region,如果有大量并发写入,这些数据最终落到磁盘上的不同位置上,光磁头来来回回的寻道时间就是一个非常大的开销。剩下的就是实际写数据的时间了。 ?§如何优化 复制或删除很多小文件时,非常耗时。如果把它们打包成一个压缩文件,再复制或删除,会快很多。 所以可以通过减少写入的文件个数来优化。如果我们只写一个文件,且每次都在文件末尾追加,这应该最大限度的减少了磁头的移动。 这种方式在Hbase中叫做预写日志,即Write Ahead Log(WAL)。所有的写入操作只要把数据追加到这个日志文件中就立即返回。 一个Region Server服务器只有一个这样的WAL文件,被服务器上的所有Region以及它里面的所有Store共享。 预写日志的数据格式并不适合进行最终的存储,所以在Store里面还有一个MemStore这样的数据结构驻留在内存里,会收集所有写入的数据,且按row key已排序。
当某些条件被满足时,MemStore中的数据会被flush到磁盘上进行持久化,最终这些数据以StoreFile的形式存储到HDFS中。