HBase补充学习(一)

前言

最近选的一门选修课需要学生进行知识分享,好巧不巧的选了HBase,本来以为对其已经学得很ok了,结果自查以后才发现自己学得还是比较表面,冰山一角就是冰山一角,没啥好推脱的,利用一周的时间充实预分享的知识,昨天已经分享结束,虽然还是由于拖拉导致没能按以往惯例准备好讲解稿和几次试讲,但时长是够了。想着也是花了时间就把一些东西放在这当记录好了(里面也主要是搜集的各种资料的总结)。

知识点

  1. 为什么要不用RDBMS?
  • 数据量爆炸式增长并数据种类急剧增加下,使用RDBMS二维表会变得很高很宽,查询效率大大降低
  • RDBMS对单机依赖很强,集群部署难;升级维护难,需要进行停机维护,耗费人力物力
  • 对数据模式要求严格,对数据格式约束很强。对于非结构化和半结构化数据只能存储数据的存储路径,存储方面需要舍弃部分数据,在数据分析的背景下不合适
  1. 为什么不用HDFS?
  • hadoop设计的初衷是大规模数据的计算和olap分析, 应用场景区别与数据库,所以在HDFS设计时候就侧重在一次写入多次读取。绝大部分文件的修改是采用在文件尾部追加数据,而不是覆盖原有数据的方式。对文件的随机写入操作在实际中几乎不存在。一旦写完之后,对文件的操作就只有读,而且通常是按顺序读。
  • HDFS虽然因为文件的分布式存储和强扩展性,具有海量数据存储的能力,但文件本身是只支持增加数据的,如果查询数据需要遍历整个HDFS集合找到目标HDFS,并对整个HDFS文件从头到尾进行遍历,效率过低
  • 对于数据删除,HDFS只支持整个文件删除,不支持文件中单个数据的删除
  • 对于数据修改,HDFSdatanode需要进行同步更新,消耗大。并且在同步的时候有读请求的话还需考虑读的是脏数据还是加锁不让读。如果是第二种情况加速不让读提供强一致性分布式事务,不仅大大降低HDFS性能而且违背hadoop设计的初衷. 如果提供一个脏读数据,为什么不直接删除数据a然后重新插入修改后数据a,让用户有个正确的读取操作呢?
  1. 为什么要用NoSQL?
  • NoSQL,not only sql。对比RDBMS,对数据模式要求不严谨,适合存储非结构化数据,数据以二进制形式存储
  • 扩展性很强,在分布式环境中应用较多
  1. 为什么要用HBase?
  • 对于HDFS无法支持随机读写问题,想到如果提前先对数据进行排序,查询效率相对会提高些。HBase是基于HDFS之上的一个数据库引擎,主要做的就是数据排序和无效数据简单的处理
  • HBase属NoSQL,对表约束不强,无模式设计,所有字段按照Byte字节数据格式存储
  • HBase扩展性强,支持海量数据存储
  1. HBase各个特点的具体解释
  • 松散表结构:NULL不占存储空间,在HBase中只有列真正插入数据才有产生列信息,MySQL中NULL为属性的值,占存储空间
  • 海量分布式存储:支持PB级数据存储,Region和RegionServer为多对1关系,底层由Hadoop支持可以进行分布式存储
  • 列式存储:Region下的Store按列族分割,一个Store即一个HFile
  • 易于扩展:RegionServer的扩展(即添加一个集群节点即可完成)
  • 高并发:对数据进行查看时无需遍历所有数据(关系型数据库以MySQL为例,找一条数据首先需要遍历整个表,其次需要拿到这个条目所有的属性值;HBase则根据Rowkey找到目标数据的一行,在找到这一行的某一列族即可)
  • 支持多版本:HBase支持一个数据有多个版本,并且支持用户自定义支持的版本数量,适用于需维护如登录记录、交易记录等最近N次变更值的数据。并且HBase支持TTL(Time To Live),每一行中的每一列数据一旦达到到期时间,将被自动删除,这点适用于如日志、浏览记录等无需永久保存的数据
  1. HBase各组件功能记录
    6.1 Master
  • 在ZooKeeper辅助下分配Region给RegionServer
  • HBase表的DDL操作,表创建及表删除
  • 处理RegionServer的负载均衡问题,通过ZooKeeper侦测各个RegionServer之间的状态。如果发现失效/过忙的RegionServer就将其上的Region分配到其他空闲并健康的RegionServer上,并完成原有RegionServer上HLog的拆分(HLog回滚)。(此处需要注意虽然RegionServer失效了,但是由于数据是存在HDFS中而RegionServer只是一个单纯的管理作用,所以即使RegionServer失效也对其管理的Region中的数据无影响,故可通过Master的协调将该Region的管理工作分配给其他正常工作的RegionServer中去。)
  • 维护集群元数据信息,主要是Master将存储HBase表的Meta表信息的Region信息存储在ZooKeepr中

6.2 ZooKeeper

  • 通过选举保证任何时候,集群中只有一个活跃的Master
  • 监控RegionServer,当RegionServer异常时通过回调的方式告诉Master当前RegionServer的情况
  • 元数据的入口,Region的状态存储在hbase:meta表里面,hbase:meta本身的Region状态存储在ZooKeeper中

6.3 HDFS

  • 存储数据的载体(HFile+HLog)

6.4 RegionServer

  • 处理来自Client的读/写请求
  • 负责与底层HDFS交互
  • 管理Master为其分配的Region
  • 负责Region的切分(动作由Master触发,RegionServer执行切分动作)
  • 负责StoreFile的合并

6.5 Region

  • HBase分布式存储和负载的最小单元
  • HBase表对弈一个Region

6.6 Store

  • 由内存中的MemStore和磁盘中的若干StoreFile组成。一个Store里有1个或多个StoreFile和一个MemStore。从HBase表的角度来看,每个Store存储一个列族

6.7 MemStore

  • 写缓存
  • 提前根据RowKey对数据进行排序

6.8 HFile/StoreFile

  • 数据存储在HFile中

6.9 hbase:meta表

  • 存储regionserver信息。Key: region、start key、region id;Values: RegionServer
  1. WAL机制
    write ahead log,预写入日志。由于HBase数据先写入内存,为防止服务器宕机或者断电等导致内存数据丢失,在数据写入内存前会先写入WAL以便异常恢复,WAL文件存放在/.log文件夹中。对WAL的写入必须是顺序写入
    7.1 客户端对数据执行一个修改操作,如put(),delete(),incr()等。
    7.2 每一个修改被封装到一个KeyValue对象实例,并通过RPC调用发送出来。
    7.3 上述调用成批地发送给含有匹配region的HRegionServer。
    7.4 数据先被写入到WAL,然后被放放到实际拥有记录的存储文件的MemStore中。
    7.5 当MemStore达到一定的大小或经历一个特定时间之后,数据会异步地连续写入到文件系统中
  • 回滚
    每隔固定检查间隔(默认一小时),会将当前WAL中的操作与实际持久化到HDFS上的操作比较,被持久化的操作会被移动到.oldlogs文件夹中即归档
  • 归档
    .oldlogs文件夹中的WAL文件定期会被Master清理
  1. MemStore刷写
    WAL 的数量越来越大,这就意味着 MemStore 中未持久化到磁盘的数据越来越多
    其实 internalFlushCacheAndCommit 里面包含两个步骤:flushCache 和 commit 阶段。flushCache 阶段其实就是将 prepareFlush 阶段创建好的快照写到临时文件里面,临时文件是存放在对应 Region 文件夹下面的 .tmp 目录里面。
  • 优化数据的存储:减少HDFS上无效数据的存储。比如一个数据添加后马上删除,MemStore刷写不会把这个数据写到HDFS上
  • 对数据进行排序
  1. Region切分
    在这里插入图片描述
  • regionserver 更改ZK节点 /region-in-transition 中该region的状态为SPLITING
  • master通过watch节点/region-in-transition检测到region状态改变,并修改内存中region的状态,在master页面RIT模块就可以看到region执行split的状态信息
  • 在父存储目录下新建临时文件夹,split保存split后的daughter region信息
  • 关闭parent region:parent region 关闭数据写入并触发flush操作,将写入region的数据全部持久化到磁盘,此后短时间内客户端落在父region上的请求都会抛出异常NotServingRegionException
  • 核心分裂步骤:在.split文件夹下新建两个子文件夹,称之为daughter A、daughter B,并在文件夹中生成reference文件(文件的命名方式是父region对应的HFile文件+父region),分别指向父region中对应文件
  • 父region分裂为两个子region后,将daughter A、daughter B拷贝到HBase根目录下,形成两个新的region
  • parent region通知修改 hbase.meta 表后下线,不再提供服务。下线后parent region在meta表中的信息并不会马上删除, 而是标注split列、offline列为true,并记录两个子region
  • 开启daughter A、daughter B两个子region。通知修改 hbase.meta 表,正式对外提供服务
    在父Region数据拷贝到子Region之前,使用reference文件读取文件。根据reference文件名(region名+真实文件名)定位到真实数据所在文件路径。
    在这里插入图片描述
  • 子region发生major_compaction时,将父目录中属于该子region的所有数据读出来并写入子region目录数据文件中
  • Master会启动一个线程定期遍历检查所有处于splitting状态的父region,确定检查父region是否可以被清理。检测线程首先会在meta表中揪出所有split列为true的region,并加载出其分裂后生成的两个子region(meta表中splitA列和splitB列),只需要检查此两个子region是否还存在引用文件,如果都不存在引用文件就可以认为该父region对应的文件可以被删除。
    在这里插入图片描述
  1. LSM树
    LSM树(Log-Structured Merge Tree)存储引擎和B树存储引擎一样,同样支持增、删、读、改、顺序扫描操作。而且通过批量存储技术规避磁盘随机写入问题。当然凡事有利有弊,LSM树和B+树相比,LSM树牺牲了部分读性能,用来大幅提高写性能。
    LSM树,此时的数据已是有序且顺序写入磁盘的,所以写入速度很快。但是随着数据量的不断增大, storefile会越来越多,数据查询时需要扫描所有文件,所以LSM树可以说得上是牺牲一部分读性能来提高写性能。这也是它的核心思想
    LSM中的merge操作就是为解决storefile越来越多造成读性能下降的问题。当memstore刷新后storefile达到配置的数量或者距离上次压缩时间满足配置的间隔时,出发compact操作,图中展示从内存刷写到磁盘,之后storefile存储的小树合并为一颗大树的过程。
  2. HFile合并
    由于内存里memstore是在数据插入的过程中就排序的,就是数据插入的时候按照顺序插入,所以memstore里的数据是有序的。当memstore的数据刷写到磁盘时,生成的storefile里的数据也是有序的,这样的话各个storefile里的数据就分别有序了。合并的时候需要将各个有序的storefile合并成一个大的有序的storefile。
  • Major Compaction:将会合并和重写一个Region的所有HFile文件,根据每个列族写一个HFile 文件,过滤被删除的数据、TTL过期数据、版本号超过设定版本号的数据。由于消耗较大,很少使用,一般是做了很多的minor compaction后进行一个major compaction将无效数据删除
  • Minor Compaction:将会自动选取相邻的一些小HFiles 文件重写为大的HFiles 文件
  1. HBase优化
  • RowKey设计
    避免热点,利用加盐、反转补齐方式。加盐是指在行键前面添加随机数字或者字母,使得数据随机分配到不同的分区,这种方式弊端显而易见。如果需要使用GET请求再次获取某行数据,则需要在插入时保存一个原始业务行键与添加的随机数的映射关系,或者使用某种散列函数计算原始业务行键的散列值,然后将该散列值作为最终行键的前缀。使用这种行键设计的应用通常只是用来做些分析统计,因此一般实时在线系统不建议使用该行键设计方式。反转补齐是指将通过反转(如12345反转为54321)可以将变化最多的部分放到行键前面,这样数据的写入也能够顺序地流入各个分区而使得集群负载比较均衡。反转补齐是避免热点区间常用的方法。
  • 跳过WAL
    对于一些能够容忍部分数据丢失的业务,如日志系统等,可以跳过WAL写入以提高写入速度
  • 增加Scan缓存
    Scan操作一般需要查询大量的数据,如果一次RPC请求就将所有数据都加载到客户端,则请求时间会比较长,同时由于数据量大,网络传输也容易出错,因此HBase Scan API提供了一个分批拉取数据然后缓存到客户端的功能,会根据业务需求做一个平衡,设置一个最适合业务的值。

总结

自查是挺痛苦的一件事情,但是好在自查后如果投入时间去补的话可以早点学更多东西。
不管怎么多,学习是永无止境的,还是继续脚踏实地,好好学习吧。

发布了41 篇原创文章 · 获赞 9 · 访问量 9771

猜你喜欢

转载自blog.csdn.net/qq_38586378/article/details/102753601