Hbase学习笔记(一)

HBASE介绍

特点:

1.大:行列可存储的数据量大
2.面向列:面向列簇的存储和权限控制,列簇单独索引。
3.稀疏:对于为空的列,并不占用存储空间(物理存储以row key,版本号和单独列簇组成对应hfile,相同rowkey为同一行)。
4.强一致性:对于客户端来说,并发写入的数据对后续的读取可见(每个值只存储于一份region中,牺牲可用性;行内操作都是原子的;通过api返回的行的内容都是一个完整的行;Hlog实现WAL负责redo)

整体架构

HMaster

负责处理跨regionServer操作,不负责管理元数据。
1.负责region的分配,负载均衡。
2.倾听region server心声,重新分配region。
3.处理schema更新请求,建表,删表。

RegionServer

负责处理对region的io请求。
1.region切分。
2.数据的读取和写入。
3.compaction操作。

Zookeeper

集群元数据管理,状态管理。
1.保证集群master数量,监控region server状态,同步给master。
2.存储region寻址入口(-ROOT-和.META.位置信息表),schema和table元数据。

Region

表在行的方向分割为多个Region,不同的region分布在不同region server上。
1.region是hbase分布式存储和负载均衡的最小单元,一个region的数据一定在同一个region server。
2.region按大小分割,当region的某个列簇达到阈值时,也会分为两个。
3.每个region由<表名.startRowkey.创建时间>标识。

相关概念

KeyValue(Cell接口的实现)

hbase数据存储核心:keyValue类,包括keyLength,valuelength,key,value四个部分。无论数据块大小是多少,keyvalue都不会被被拆分。
key:row(row key内容),column family(列簇),column qualifier(列字段),time stamp,key type(key类型,包括put,delete等) 例:put : rowkey=index,cf:attr=value
Row key是用于检索记录的主键。访问hbase table中的行,只有3种方式
1.通过单个Row key
2.通过rk的range,startRow和stopRow进行scan
3.全表扫描。
row key可以是任意字符串,在hbase内部,rowkey为字节数组。
keyValue相关:
1.keyValue以字节数组存储所有数据,内部有多个方法用以截取不同数据的字节数组。
2.每行数据的每个列都由一个keyValue用于存储相关数据,会造成rowkey等数据的冗余。

HLOG(WAL预写日志实现)

WAL的作用是灾难恢复,记录数据的改动,通过redo log恢复崩溃前的数据。如果写入WAL失败,整个操作视作失败(和更新处于一个事务)。包含有已经写入memstore但还未flush到hfile的更改(edits)。每个regionServer默认一个hlog,多个region共享。

WAL处理过程:
1.客户端通过rpc操作发送更新命令,命令封装到keyValue对象实例中,批量发送给HRegion server。
2.hs将kv发送给hregion实例:首先被写到hlog(wal),然后被存入memStore,两者写入成功返回成功给客户端。
3.memstore满足条件会将数据写入文件系统,生成hfile。

memstore:
每个hstore中都由一个memstore和多个hfile组成。memstore位于hs的内存,hfile被写入到文件系统。memStore底层使用ConcurrentSkipListMap来保证数据的有序性,保证增删查的操作都会在O(logN)时间复杂度完成。同一hs的memstore使用同一内存空间,会导致GC问题,Hbase使用MSLAB内存管理方式减少full gc。列簇的数量对应memstore的数量,规划合理的列簇数量,避免过大的内存负担。
memstore的作用:1.对每个hfile根据rowkey进行排序,方便将来的检索优化。2.内存级缓存,将来的数据查询优先查memstore。

WAL相关:
1.WAL功能可以关闭,数据导入等过程中可以关闭以提升性能。
2.一个hs上的多个region共享同一个WAL,通过HLogKey记录的kv实例,sequence number(读取位置)等信息,可以定位对应的region区域。
3.wal恢复数据时,hmaster负责处理hlog文件到相应的region目录;新的hs在加载region时会通过replay的方式将hlog中的数据写到memstore,进行一次flush,完成数据恢复。
4.memstore调用flush之后,wal中的相对应数据会作废。可以通过wal的大小限制来触发memstore的flush操作。

SequenceID:region级别的行级事务的自增序号(在行事务中用于实现数据对读操作的可见性),保存在hlog中。多个region的log文件记录于同一个hlog,根据sequenceid和regionServer维护的region的对应变量,可以判断hlog中的数据是否已经落盘,对hlog进行清理。

HBASE使用

region定位

hbase的客户端通过和zookeeper的交互来获取元数据信息。
region标识:由表名,开始行键,regionID信息组成,用于唯一标识一个region。
meta表:将region和hregion Server对应,用于客户端查找。meta表每一行记录了一个region信息,rowKey包含表名,起始行键,时间戳信息和信息编码。表里列簇info,包含regionInfo列,server列和serverStatrcode列。regionInfo记录了region详细信息,包括行键范围startKey和endKey,列簇列表和属性。server记录hregionserver的地址。
二层架构:zookeeper存放meta表所在regionServer地址,客户端通过地址找到meta表,再通过meta表找到对应的region所在的regionServer地址。

数据插入

数据写入可以分为三个阶段:
1.客户端将写入请求进行处理,定位rs和发送请求。
2.rs接收请求,将数据写入WAL,再写入对应列簇的memstore(客户端在写入memstore后返回,剩下的异步执行,行锁释放,执行sync wal成功后结束写事务)。
3.memstore容量超过阈值,异步执行flush操作,将内存中的数据落盘成Hfile。

一. 客户端处理阶段

1.客户端根据写入的表和rowkey在元数据缓存中查找对应地址,如果没有找到,访问zookeeper依次进行查找。
2.客户端发送请求给rs,rs解析并写入数据。

二. Region写入阶段

1.Acquire Locks:申请行锁,保证行级更新的互斥和原子性。
2.更新所有keyValue对象的时间戳。
3.构建WALEdit对象:保证数据可靠性;一次写入操作的所有KeyValue会构建成一条WALEdi记录(属性名cells的arraylist记录所有keyValue对象)保证操作的原子性(hbase的mvcc)。
4.将WALEntry(WALEdit+HLogKey)写入HLog。(HBase使用追加写入的方式,高效的写入日志文件)
5.数据写入MemStore。
6.释放行锁。
7.HLog同步到hdfs,释放行锁后执行fsync操作减少写锁持有时间,提升写性能;如果fsync失败,执行回滚操作,移除memstore中的数据。
8.结束写事务,该线程的更新操作对其他读线程可见(hdfs正在写入的文件对reader不可见)。

追加写入HLog:

HBase使用了Disruptor的无锁有界队列,通过生产者-消费者完成HLog同步到磁盘的过程。过程分为append(此操作释放行锁,生成包含WALEdit和HLogKey信息的FSWALEntry对象放入ringbuffer)和sync(生成的syncFutrue放入ringBuffer),阻塞生产者线程后等待消费者负责执行append(记录追加到hdfs文件,只是写入到文件缓存)和sync(异步刷盘)操作。

随机写入memstore:

MemStore使用concurrentSkipListMap来存储KeyValue,保证并发写入和有序存储。
MSLAB内存管理机制:一次申请一个2M大小的Chunk;写入的keyValue顺序复制到chunk中,写满后再申请下一个;chunk内的keyValue生成cell对象,指向Chunk中的KeyValue内存区域;将cell对象作为key和value写入skipListMap中;原生KeyValue失去引用被回收。

三. MemStore Flush阶段
一. flush的触发时机

1.MemStore级别限制:region中任一ms大小到达上限,触发flush;
2.region级别限制:region中所有ms大小总和到达上限,触发flush;
3.regionServer级别限制:regionServer中所有ms大小总和到达低水位阈值,按照ms大小依次对region flush;到达高水位阈值,rs阻塞更新强制执行flush。
4.rs的hlog数量到达上限,选取最早的hlog对应region进行flush。
5.定期对ms执行flush,默认1小时。

二. flush流程

1.prepare阶段:对ms中的CellSkipListSet做快照snapshot(为当前文件新建一份指针,记录文件元数据);此过程需要持有updateLock。
2.flush阶段:snapshot持久化未临时文件,放在.tmp目录下。
3.commit阶段:临时文件移动到指定ColumnFamily目录下,针对hfile生成storeFile,添加到Store的文件列表下。

三. hfile的构建

hfile结构:
1.Data block:保存表中数据
2.meta block:保存用户自定义kv对;
3.file info:hfile元数据(大小,last key,avg key len)
4.data block index:data block的索引(被索引block的第一条记录的key)
5.meta blcok index
6.trailer:存储各个block的偏移量,大小(读取hfile时,首先读取trailer,根据trailer判断需要读取到内存的block)

compaction

一. compaction是什么。

hbase使用lsm-tree架构模式,用户将数据先写入wal,再写入缓存,达成条件后flush到磁盘,已经落盘的hfie不允许原地修改。hfile数据文件不断增加导致了查询io次数增加。hbase尝试不断将这些文件进行合并,合并过程就是compaction。

1.每个region中的store中选择一些hfile进行合并,从这些hfile中读取需要合并的keyValues,排好序后写入新文件。
2.compaction分为minor compaction和major compaction;

  • minor compaction:选取小的,相邻的store file合并,忽略key type为deleted和过期的数据。
  • major compaction:将所有store file合并为欸一个store file,舍弃被删除的数据,ttl过期数据,版本号超过设定版本号的数据。
二.compaction作用。
  • 降低hfile数量变多带来的io消耗。
  • compaction时具有大量的带宽和io的压力,会导致读写的放大,通过短时间的服务消耗换后续查询的低延迟。
三.compaction流程。
1.触发compaction。

触发时机:1.memstore flush:每次执行flush后都会对当前store的文件数进行判断。2.后台线程周期性检查:根据周期检查文件数大小,是否需要compaction;如果不满足,接着检查是否满足major compaction。3.手动触发:一般是为了major compaction,避免自动compaction影响业务,降低磁盘容量等。

2.选择合适hifle(compaction重点)。
  • 排除非候选文件:1.排除正在执行compact的文件和比这些文件更新的文件。2.排除大于某个阈值的大文件。
  • 是否执行major compaction:1.用户手动触发。2.长时间没有compact且候选文件数小于阈值。3.store中含有reference文件。
    不满足major compaction条件时,执行minor compaction。
  • minor策略:ratiooBasedCompactionPolicy,exploringCompactionPolicy;
3.挑选合适线程池。

compact线程池包括largeCompactions和smallCompactions,根据文件总大小分配。

4.执行hfile合并。
  • 读出待合并hfile的kv,顺序写到./tmp目录下的临时文件中(这步出现问题则本次compaction失败,多出一份冗余数据)。
  • 临时文件移动到对应region的数据目录。
  • 将compaction的输入文件路径和输出文件路径封装为kv写入wal日志,打上compaction标记,强制执行sync(此步成功后,可以保证第四步成功执行)。
  • 将对应region数据目录下的compaction输入文件全部删除。

region切分

默认切分策略:
1.constanSizeRegionPolicy(-v0.94):根据region中最大store的压缩后的文件大小是否达到阈值决定是否区分。缺点:切分策略对大表和小表没有区分。
2.increasingToUpperBoundRegionSplitPolicy(v0.94-2.0):阈值根据region个数不断升高的constantSizeRegionPolicy。优点:自适应大表和小表,大集群条件下对大表的表现良好。缺点:小表会在1大集群下产生过多小region。
3.steppingSplitPolicy(v2.0):region个数为1,切分阈值为flush size*2,否则为MaxRegionFileSize。优点:对于大集群中的大表和小表更友好,小表不会产生过多小region。
定位SplitPoint:整个region中最大store中最大文件中最中心的一个block的首个rowkey。如果定位到的rowkey是整个文件的首个rowkey或者最后一个rowkey(一个文件只有一个block),就认为没有切分点。

切分流程:

  • prepare:
    • 生成HRegionInfo对象,包含tableName,regionName,startKey,endKey等信息;
    • 生成transaction journal,记录切分进展。
  • execute:
    • regionserver向zk修改region状态为SPLITING;
    • master修改region状态;
    • 在父region存储目录下新建临时文件夹.split保存两个daughter region信息;
    • 父region关闭写入,数据全部落盘;
    • .split文件夹下生成两个daughter文件夹,分别生成记录对应文件的reference文件;
    • 子region拷贝到hbase根目录,形成新的region;
    • parentregion修改.meta表下线,标注split列,offline列为true并记录两个子region
  • rollback:如果执行阶段出现异常,执行rollback操作。

region的切分过程并没有实际的数据移动,只是生成对应reference对象用于查找子region对应的父region文件,只有当子region执行major_compaction(store中存在reference文件时,触发major compaction)时会将父目录中属于子region的数据读到ziregion目录数据文件中。当父region的两个子region中都不存在reference文件时,父region相关文件就会被删除。

数据读取

1.客户端获取待检索的rowkey所在的regionServer信息。
2.regionServer接收客户端请求,构建scanner体系。

Scanner:hbase的scanner分为三级,包括regionScanner,storeScanner(和列簇个数相同),storeFileScanner/memStoreScanner(由store中file个数和memstore决定,负责读取的真正执行)。

  • regionScanner:构建storeScanner
  • storeScanner:构建storeFileScanner(为每个hfile和memstore创建scanner);过滤淘汰storeFileScanner(time range,rowkey range进行过滤,淘汰不存在待检索结果的scanner);
  • storeFileScanner:
    • 定位block offset(在blockCache读取hfile的索引,获取检索rowKey的block Offset和block size);
    • load block(根据offset在blockCache中查找data block,如果不在缓存,则在hfile中加载);
    • seek key(在data block中通过二分查找法定位具体key)

根据storeFileScanner构建最小堆,由scanner指向的keyvalue进行排序(排序根据rowkey,cf,qualifier,timeStamp(倒序),keyType),便于多版本读取
storeScanner构建最小堆,按照列簇进行排序。

查询过程:在查询对应rowkey的数据时,根据过滤后剩下所有storeFilescanner或者memstoreScanner指向的keyValue数据结构构建最小堆,获取最小堆堆顶数据并进行判定(例如是否keyType是否是Deleted,时间戳版本是否是用户设定的范围等),判定结束后对应scanner指向下一个keyValue,重新构建最小堆。

block Cache:storeFileScanner通过索引定位待查找的key是否在block cache中,如果存在则直接取出,不存在则到相应的storeFile中读取。
storeFile的过滤过程:1.storeFile记录由文件起始key范围,判断待查询rowKey范围和文件起始范围是否有交集;2.根据storeFile元数据中的时间戳范围进行过滤;3.根据storeFile中的bloom数据进行过滤。

学习参考:hbasefly.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值