小石是一个非学历程序员。虽然他是电子专业的,但通过自己的努力顺利通过了面试,现在即将开始新的生活。今天,小石的姐姐和陆先生一起来看小石。一进房间,就闻到一股难闻的气味。可这不,小诗姐进了厕所,发现地上的一个盆里全是没洗的袜子。肖石:当然不是。当盆里的袜子装满时,先放入桶中,再继续装。当桶里的袜子装满后,可以一次性放入洗衣机中清洗。这不仅效率高,而且还能节省水电费。小石得意洋洋地介绍着自己洗袜子的过程。小石听说全世界都在黑程序员,有些不高兴,没想到还没成为程序员就被姐姐黑了。说完,他就进了自己的房间,把妹妹和陆老爷子留在了外面。小诗姐也意识到自己不应该拿程序员开玩笑了,但是现在她不知道该怎么办才好,看向了陆老师。陆老师走进了肖石的房间。HBase的历史是什么:不要吹它。除了能够存储海量数据之外,构建在HDFS上还有很多缺点。我没有忘记你上次给我介绍的HDFS的缺点。不支持小文件,不支持并发写入,不支持随意修改文件,查询效率也低。肖石仔细回忆HDFS:陆老师:HDFS确实有很多缺点,但是HBase是分布式数据库系统,支持极高并发写入,支持实时查询,适合存储稀疏数据。卢老师:HBase主要用在大数据领域。在这方面,它确实比MySQL好很多。它的存储方式与MySQL完全不同。MySQL是行存储,HBase是列存储。列式存储卢先生:对,这就是行存储系统存储稀疏数据的问题。我们来看看列式存储是如何解决这个问题的。它的存储结构是这样的:小石:这个我理解,相当把每一行的每一列拆开,然后通过Rowkey关联起来,Rowkey相同的数据其实就是原来的行。卢老师:你这里只说了一个好处,就是把一行数据转化成了这样的key-value格式。因此,HBase可以存储百万列,而且由于HBase是基于HDFS的,所以HBase可以存储数亿行,是真正的海量数据库。卢老师:这就是HBase的强大之处,还不止于此。其实很多时候,我们在做Select查询的时候,只是关注某些列。人们的工资呢?小石:哦,我大概明白了,原来是这样的,所以HBase的查询效率也是很高的,但是我有一个疑问,如果我要查我所有的信息,这是一行数据,HBase会查询它吗?慢点?列粗鲁先生:柱簇顾名思义就是把一些柱子放在一起。在HBase中,列簇中的列会存储在一起。比如我们把工作相关的Salary和Job放在Work一栏。集群下。那么大致是这样的:小石:哦,我明白了。这样,一个列簇中的列将被一次性取出。如果我要查看所有列的信息,我会把所有的信息放在一个列簇中。好吧。注意:在HBase中,所有的列实际上都在列族中,需要在定义表的时候指定列族。生产环境出于性能考虑和数据平衡考虑,一般只使用一个列族,最多使用两个列族。Rowkey设计说明:当然也有一些中间件将SQL翻译成HBase的查询规则,从而支持SQL查询HBase,这不在本文讨论范围之内。小石:嗯?这和我想象的不一样。如果我想查询工资超过20w的记录,在MySQL中,我只需要使用一个非常简单的SQL。如何在HBase中查看?卢老师:在HBase中,需要巧妙的在Rowkey中设置要查询的字段。你可以把一个Rowkey理解为一个字符串,HBase根据Rowkey建立索引。对B+树不熟悉的同学可以看看这篇文章。HBase的HFile底层原理是一样的。卢先生:假设员工的工资上限为9999w,查询可能是根据员工的工资或者具体的员工姓名,那么Rowkey可以这样设计:注意:上面的Rowkey是简化版的设计,只是为了澄清查询的范围。在实际使用中,因为Rowkey需要考虑hashability,所以可能不会这样使用。Hashability将在后面详细讨论。卢老师:HBase提供了三种查询方式:全表扫描、Scan。基于Rowkey的查询。由Rowkey过滤的范围查询。比如要查询工资不低于20w的记录,可以使用范围查询,查找从startRow=0020到stopRow=9999的所有记录。这是HBase直接支持的一种查询方式。卢老师:这里有几点要注意。首先,Rowkey是按照字符串的字典序组织成B+树的,所以需要对数字进行填充,否则会出现123w小于20w的情况,但是如果都填充了,就可以了发现020w小于123w。小石:哦,我明白了,这个很好理解,因为Rowkey是字符串形式的,所以一定要按照字符串的先后顺序排序。而Rowkey有点类似于MySQL中的主键,所以保证其唯一性无可厚非。另外,由于每个key-value都包含Rowkey,Rowkey越短,越能节省存储空间。注意:如果Rowkey复杂,查询条件复杂,HBase也为Rowkey提供了自定义的Filter,所以只要数据反映在Rowkey中,可以解析,就可以根据自己的条件进行查询。肖石:但是陆先生,我有一个问题。前面说过HDFS不适合存储小文件,HBase中一条记录只有一点数据,但是记录很多。属于大量的小文件,存储在HDFS中不算内存爆炸。然而?LSM三层存储模型简史:哦,就像把浴缸里的袜子放到水桶里一样。但是陆老师,如果数据量很大,久而久之,会写很多,会形成很多小文件?这不是又一个海量的小文件吗?不记得HDFS原理的同学可以复习一下:卢老师:对了,HBase也是用同样的思路。其实这就是WAL预写日志的思路。有一天机器挂了,内存丢失了,可以从WAL日志中恢复数据。数据修改的小历史:但是陆老师,我还有疑问。我记得HDFS不能随意修改文件,只能追加。那么HBase中的数据写入后是不是就不能更改或者删除了呢?卢老师:删除也是添加了一条版本***的记录,只是把数据标记为删除了。查询时,如果看到版本***的记录是数据删除,就知道数据被删除了。卢老师:哈,小石,你想的很深。你还记得LSM的第三层吗?HBase在合并时会删除这些不用的记录,以节省存储空间。卢先生:不完全正确。实际上,HBase将合并分为两种类型:MinorCompact。这种方法只是简单的合并了几个文件,并没有清理数据。LargemergeMajorCompact,这种方法会合并大部分文件并清理数据。卢老师:基本正确,但是要知道,如果数据量很大,这个过程是非常耗性能的。一般情况下,生产环境是禁止大规模合并的。否则,当正常服务时突然发生大规模合并,可能会导致整个集群资源紧张。精疲力尽,没有正常的服务。HBase架构简史:HBase的架构好像是主从架构,有点像HDFS。HMaster是用来管理集群的,HRegionServer才是真正存储数据的地方吧?卢老师:啊,这样不对。HBase在查询和写入数据时,实际上并不像HDFS那样去问HMaster。在HBase中,每张表都有元信息,元信息也存储为一张HBase表,称为元信息表,也叫元表,是系统表的一种。肖石:但是还有一个问题。既然Meta表也存储在HBase上,那么HBase怎么知道Meta表存在于哪个HRegionServer上呢?这不是鸡生蛋还是蛋生鸡的问题吗?鲁老师:小石,我说Meta表是HBase表,也就是说Meta表也是存储Rowkey和Value键值的,但是我没有说Meta表是在HBase上的。实际上,Meta表并不存储在HRegionServer上,而是存储在分布式协调服务Zookeeper上。肖石:哦,所以这就是为什么其实是在固定的地方读取Meta表,然后我们根据Meta表就知道数据在哪个HRegionServer上了。但是Zookeeper是什么?卢老师:其实HMaster的任务比较轻,但是比较重要。主要通过调整和管理Region的分布来实现HRegionServer的负载均衡。HRegionServer架构卢老师:其实Region就是HBase在Rowkey上的划分。每个Region可以通过StartKey和EndKey来确定Rowkey的范围。一个HRegionServer上可能有多个Region。肖石:所??以数据按照Rowkey和一定的hash规则分布到不同的Region,Region属于某个HRegionServer。这种关系是否正确?Mr.Lu:是的,通过这个我们其实可以得到Rowkey设计的另外一个原则,就是hashability。Rowkey的前几个字母不能相同,否则会分布在同一个HRegionServer上,导致这个HRegionServer负载很高,耗尽,其他HRegionServer无事可做。一般一个数据摘要可以按照一定的规则进行计算,比如MD5,MD5的前几位拼在Rowkey前面。卢老师:哈哈,名词没讲,原理讲了。比如这个Store,我们之前说过,一个列簇中的列是存储在一起的。对应的,一个列簇中的数据存储在一个Store中。卢先生:对,这里的StoreFile只是一个名字。它以HFile格式存储在HDFS上。HFile是一种存储格式。在新版本的HFile存储格式中,是一种类似于B+树的索引形式。读写流程①HBaseClient需要写入输入,首先从Zookeeper中获取Meta表信息,根据数据的Rowkey找出写入哪个RegionServer。②然后HBase会将数据写入对应RegionServer的内存MemStore中,同时记录操作日志WAL。③当MemStore超过一定阈值时,会将内存MemStore中的数据写入硬盘,形成StoreFile。④当某些条件触发时,小的StoreFiles会被合并成一个大的StoreFile,有利于HDFS的存储。卢老师:当大量Rowkeys相似的数据分配给一个Region,导致这个Region的数据量过大,就会分裂Region,HMaster会将RegionServer重新分配给分裂后的Region,这就是负载均衡HMaster策略。①HBaseClient读取数据,首先从Zookeeper中获取Meta表信息,根据要查的Rowkey找出相应数据在哪些RegionServer上。②根据列簇在这些RegionServer上查找StoreFile和MemStore,得到大量的key-value结构数据。③根据数据的版本找到***数据并返回。OLTP和OLAP卢先生:OLTP应用称为联机事务处理应用,类似于银行转账等业务。这些应用对交易的要求比较高。另一方面,OLAP应用被称为在线分析处理应用,如推荐系统,在收集大量用户行为后进行分析并得出结论。他们主要以分析为主,交易要求很低。总结一下,小石把这次学习到的HBase的知识记下来了:HBase是列式存储,和MySQL的行式存储不同。HBase中有一个列族的概念,同一个列族下的列一起存储在一个Region的StoreFile中。HBase根据Rowkey进行查找,需要查询的字段必须放在Rowkey中。HBase内部使用LSM三层模型进行存储。数据先写入内存的MemStore,当内存达到一定阈值时,再刷写到硬盘StoreFile。当满足一定的条件时,小的StoreFile会被合并成一个大的StoreFile。HBase适用于类似OLAP的应用程序。学完HBase,做笔记后,小石开心地洗了袜子。
