HBase总结

什么是HBase?

HBase是Google Bigtable的开源实现,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
HBase的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。

HBase特点
大:一个表可以有上亿行,上百万列。
面向列:面向列表(簇)的存储和权限控制,列(簇)独立检索。
稀疏:对于为空(NULL)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
无模式:每一行都有一个可以排序的主键和任意多的列,列可以根据需要动态增加,同一张表中不同的行可以有截然不同的列。
数据多版本:每个单元中的数据可以有多个版本,默认情况下,版本号自动分配,版本号就是单元格插入时的时间戳。
数据类型单一:HBase中的数据都是字符串,没有类型。

Hbase与关系型数据库比较:
(1)Hbase的表模型与关系型数据库的表模型不同:
(2)Hbase的表没有固定的字段定义;
(3)Hbase的表中每行存储的都是一些key-value对
(4)Hbase的表中有列族的划分,用户可以指定将哪些kv插入哪个列族
(5)Hbase的表在物理存储上,是按照列族来分割的,不同列族的数据一定存储在不同的文件中
(6)Hbase的表中的每一行都固定有一个行键,而且每一行的行键在表中不能重复
(7)Hbase中的数据,包含行键,包含key,包含value,都是byte[ ]类型,hbase不负责为用户维护数据类型
(8)HBASE对事务的支持很差

Hbase与其它NoSQL数据库比较:
HBASE相比于其他nosql数据库(mongodb、redis、cassendra、hazelcast)的特点:
Hbase的表数据存储在HDFS文件系统中,从而,hbase具备如下特性:存储容量可以线性扩展; 数据存储的安全性可靠性极高!

Hbase的应用场景:
Hbase非常适合需对数据进行随机读操作或者随机写操作、大数据上高并发操作,比如每秒对PB级数据进行上千次操作以及读写访问均是非常简单的操作。

hive与hbase之间的区别?
Hive的定位是数据仓库,虽然也有增删改查,但其删改查对应的是整张表而不是单行数据,查询的延迟较高。
其本质是更加方便的使用mr的威力来进行离线分析的一个数据分析工具。
HBase的定位是hadoop的数据库,是一个典型的Nosql,所以HBase是用来在大量数据中进行低延迟的随机查询的。

HBase组件
HMaster的作用
HBase中的每张表都通过键按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过256M就要被分割成两个,这个过程由HRegionServer管理,而HRegion的分配由HMaster管理
1.为HRegionServer分配HRegion
2.负责HRegionServer的负载均衡
3.发现失效的HRegionServer并重新分配
4.HDFS上的垃圾文件回收
5.处理Schema更新请求
HRegionServer的作用
1.维护HMaster分配给它的HRegion,处理对这些HRegion的IO请求
2.负责切分正在运行过程中变得过大的HRegion可以看到,Client访问HBase上的数据并不需要HMaster参与,寻址访问ZooKeeper和HRegionServer,数据读写访问HRegionServer,HMaster仅仅维护Table和Region的元数据信息,Table的元数据信息保存在ZooKeeper上,负载很低。HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列簇创建一个Store对象,每个Store都会有一个MemStore和0或多个StoreFile与之对应,每个StoreFile都会对应一个HFile,HFile就是实际的存储文件。因此,一个HRegion有多少列簇就有多少个Store。
3 一个HRegionServer会有多个HRegion和一个HLog。
HRegion的作用
Table在行的方向上分割为多个HRegion,HRegion是HBase中分布式存储和负载均衡的最小单元,即不同的HRegion可以分别在不同的HRegionServer上,但同一个HRegion是不会拆分到多个HRegionServer上的。HRegion按大小分割,每个表一般只有一个HRegion,随着数据不断插入表,HRegion不断增大,当HRegion的某个列簇达到一个阀值(默认256M)时就会分成两个新的HRegion。
1、<表名,StartRowKey, 创建时间>
2、由目录表(-ROOT-和.META.)记录该Region的EndRowKey
HRegion定位:HRegion被分配给哪个HRegionServer是完全动态的,所以需要机制来定位HRegion具体在哪个HRegionServer,HBase使用三层结构来定位HRegion:
1、通过zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一个region。
2、通过-ROOT-表查找.META.表的第一个表中相应的HRegion位置。其实-ROOT-表是.META.表的第一个region;
.META.表中的每一个Region在-ROOT-表中都是一行记录。
3、通过.META.表找到所要的用户表HRegion的位置。用户表的每个HRegion在.META.表中都是一行记录。
-ROOT-表永远不会被分隔为多个HRegion,保证了最多需要三次跳转,就能定位到任意的region。Client会将查询的位置信息保存缓存起来,缓存不会主动失效,因此如果Client 上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的HRegion,其中三次用来发现缓存失效,另外三次用来获取位置信息。

HLog简介
默认情况下,所有写入、更新、删除操作都会把数据先写入HLog,再写入MemStore。大多数情况下,HLog并不会被读取。但是在HBase的RegionServer故障,MemStore中数据尚未flush到磁盘,这时就需要回放HLog进行数据恢复。此外,HBase主从集群数据复制也是通过将HLog日志发送给从集群,然后从集群再执行回放来完成。

什么是HFile?
HFile是HBase中KeyValue数据的存储格式(这里不要把KeyValue想成Map的那种形式,理解起来会好一点),HFile是Hadoop的二进制格式文件,实际上StoreFile就是对HFile做了轻量级包装,即StoreFile底层就是HFile 。

HFile由什么组成?
HFile由六部分组成:
Data(数据块):保存表中的数据(KeyValue的形式),这部分可以被压缩。
Meta (元数据块):存储用户自定义KeyValue
File Info:定长;记录了文件的一些元信息,例如:AVG_KEY_LEN,AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY等
Data Index(数据块索引):记录了每个Data块的起始索引
Meta Index(元数据块索引):记录了每个Meta块的起始索引
Trailer:定长;用于指向其他数据块的起始点。

HBase的过滤器
单个列过滤器
列过滤器
列族过滤器
前缀过滤器
键值过滤器

HBase读数据流程:
1,Client先访问zookeeper,从meta表读取region的位置,然后读取meta表中的数据。meta中又存储了用户表的region信息。
2,根据namespace、表名和rowkey在meta表中找到对应的region信息
3,找到这个region对应的regionserver
4,查找对应的region
5,先从MemStore找数据,如果没有,再到StoreFile上读(为了读取的效率)。

HBase写数据流程:
1,Client先访问zookeeper,从meta表获取相应region信息,然后找到meta表的数据
2,根据namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息
3,找到对应的regionserver
4,把数据分别写到HLog和MemStore上一份
4,MemStore达到一个阈值后则把数据刷成一个StoreFile文件。(若MemStore中的数据有丢失,则可以总HLog上恢复)
5,当多个StoreFile文件达到一定的大小后,会触发Compact合并操作,合并为一个StoreFile,(这里同时进行版本的合并和数据删除。)
6,当Storefile大小超过一定阈值后,会把当前的Region分割为两个(Split),并由Hmaster分配到相应的HRegionServer,实现负载均衡

HBase删流程:
Delete命令不立即删除内容,一条新墓碑记录写入,作为删除的标记。在大合并的时候墓碑记录才会被处理,被删除记录,占用的空间才会释放。
大合并将处理给定region的一个列族的所有HFile,大合并后,列族的所有HFile合并成一个文件大合并耗费资源,不经常使用,但是是真正删除数据的机会,Hbase可以确保同时访问到两种记录。

RowKey设计原则
(1)RowKey 长度原则
RowKey 是一个二进制码流,RowKey 的长度被很多开发者建议说设计在10~100 个字节,不过建议是越短越好,不要超过 16 个字节。
原因如下:
① 数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 RowKey 过长比如 100 个字节,1000 万列数据光 RowKey 就要占用 100*1000 万=10 亿个字节, 将近 1G 数据,这会极大影响 HFile 的存储效率;
② MemStore 将缓存部分数据到内存,如果 RowKey 字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。 因此RowKey 的字节长度越短越好。
③ 目前操作系统是都是 64 位系统,内存 8 字节对齐。控制在 16 个字节,8 字节的整数倍利用操作系统的最佳特性。
(2)RowKey 散列原则
如果 RowKey 是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将 RowKey 的高位作为散列字段,由程序循环生成,低位放时间字段, 这样将提高数据均衡分布在每个 Regionserver 实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的 热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。
(3)RowKey 唯一原则
必须在设计上保证其唯一性。

HBase的优化
一、写入数据方面
1.Auto Flash
通过调用HTable.setAutoFlushTo(false)方法可以将HTable写客户端自动flush关闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只有当put填满客户端写缓存的时候,才会向HBase服务端发起写请求。默认情况下auto flush是开启的。
2.Write Buffer
通过调用HTable.setWriteBufferSize(writeBufferSize)方法可以设置HTable客户端的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer将会被flush到服务端。其中,writeBufferSize的单位是byte字节数,可以根基实际写入数据量的多少来设置该值。
3.WAL Flag
在HBase中,客户端向集群中的RegionServer提交数据时(Put/Delete操作),首先会写到WAL(Write Ahead Log)日志,即HLog,一个RegionServer上的所 有Region共享一个HLog,只有当WAL日志写成功后,再接着写MemStore,然后客户端被通知提交数据成功,如果写WAL日志失败,客户端被告知提交失败,这样做的好处是可以做到RegionServer宕机后的数据恢复。
对于不太重要的数据,可以在Put/Delete操作时,通过调用Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函数,放弃写WAL日志,以提高数据写入的性能。
注:如果关闭WAL日志,一旦RegionServer宕机,Put/Delete的数据将会无法根据WAL日志进行恢复。
4.Compression 压缩
数据量大,边压边写也会提升性能的,毕竟IO是大数据的最严重的瓶颈,哪怕使用了SSD也是一样。众多的压缩方式中,推荐使用SNAPPY。从压缩率和压缩速度来看,性价比最高。
HColumnDescriptor hcd = new HColumnDescriptor(familyName);
hcd.setCompressionType(Algorithm.SNAPPY);
5.批量写
通过调用HTable.put(Put)方法可以将一个指定的row key记录写入HBase,同样HBase提供了另一个方法:通过调用HTable.put(List)方法可以将指定的row key列表,批量写入多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高,网络传输RTT高的情景下可能带来明显的性能提升。
6.多线程并发写
在客户端开启多个 HTable 写线程,每个写线程负责一个 HTable 对象的 flush 操作,这样结合定时 flush 和写 buffer(writeBufferSize),可以既保证在数据量小的时候,数据可以在较短时间内被 flush(如1秒内),同时又保证在数据量大的时候,写 buffer 一满就及时进行 flush。
二、读数据方面
1.批量读
通过调用 HTable.get(Get) 方法可以根据一个指定的 row key 获取一行记录,同样 HBase 提供了另一个方法:通过调用 HTable.get(List) 方法可以根据一个指定的 row key 列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络 I/O 开销,这对于对数据实时性要求高而且网络传输 RTT 高的情景下可能带来明显的性能提升。
2.缓存查询结果
对于频繁查询 HBase 的应用场景,可以考虑在应用程序中做缓存,当有新的查询请求时,首先在缓存中查找,如果存在则直接返回,不再查询 HBase;否则对 HBase 发起读请求查询,然后在应用程序中将查询结果缓存起来。至于缓存的替换策略,可以考虑 LRU 等常用的策略。 ?
三、数据及集群管理
1.预分区
默认情况下,在创建HBase表的时候会自动创建一个Region分区,当导入数据的时候,所有的HBase客户端都向Region写数据,知道这个Region足够大才进行切分,一种可以加快批量写入速度的方法是通过预先创建一些空的Regions,这样当数据写入HBase的时候,会按照Region分区情况,在进群内做数据的负载均衡。
2.Rowkey优化
rowkey是按照字典存储,因此设置rowkey时,要充分利用排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放到一块。
rowkey若是递增生成的,建议不要使用正序直接写入,可以使用字符串反转方式写入,使得rowkey大致均衡分布,这样设计的好处是能将RegionServer的负载均衡,否则容易产生所有新数据都在集中在一个RegionServer上堆积的现象,这一点还可以结合table的与分区设计。
减少Column Family数量
不要在一张表中定义太多的column family。目前HBase并不能很好的处理超过 2-3个column family的表,因为某个column family在flush的时候,它临近的column family也会因关联效应被触发flush,最终导致系统产生更过的I/O;
3.设置最大版本数
创建表的时候,可以通过 HColumnDescriptor.setMaxVersions(int maxVersions)设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)。
4.缓存策略(setCaching)
创建表的时候,可以通过HColumnDEscriptor.setInMemory(true)将表放到RegionServer的缓存中,保证在读取的时候被cache命中。
5.设置存储生命期
创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置表中数据的存储生命周期,过期数据将自动被删除
6.磁盘配置
每台RegionServer管理10-1000个Regions。每个Region在1-2G,则每台server最少要10G,最大要1000*2G=2TB,考虑3备份,需要6TB。方案1是3块2TB磁盘,2是12块500G磁盘,带宽足够时,后者能提供更大的吞吐率,更细力度的冗余备份,更快速的单盘故障恢复。
分配何时的内存给RegionServer
在不影响其他服务的情况下,越大越好。在HBase的conf目录下的hbase-env.sh的最后添加export HBASE_REGIONSERVER_OPTS="- Xmx16000m $HBASE_REGIONSERVER_OPTS"其中16000m为分配给REgionServer的内存大小。
7.写数据的备份数
备份数与读性能是成正比,与写性能成反比,且备份数影响高可用性。有两种配置方式,一种是将hdfs-site.xml拷贝到hbase的conf目录下,然后在其 中添加或修改配置项dfs.replication的值为要设置的备份数,这种修改所有的HBase用户都生效。另一种方式是改写HBase代码,让HBase支持针对列族设置备份数,在创建表时,设置列族备份数,默认为3,此种备份数支队设置的列族生效。
客户端一次从服务器拉取的数量
通过配置一次拉取较大的数据量可以减少客户端获取数据的时间,但是他会占用客户端的内存,有三个地方可以进行配置
在HBase的conf配置文件中进行配置hbase.client.scanner.caching;
通过调用HTble.setScannerCaching(int scannerCaching)进行配置;
通过调用Sacn.setCaching(int caching)进行配置,三者的优先级越来越高。
8.客户端拉取的时候指定列族
scan是指定需要column family,可以减少网络传输数据量,否则默认scan操作会返回整行所有column family的数据
拉取完数据之后关闭ResultScanner
通过 scan 取完数据后,记得要关闭 ResultScanner,否则 RegionServer 可能会出现问题(对应的 Server 资源无法释放)。
9.RegionServer的请求处理IO线程数
较少的IO线程适用于处理单次请求内存消耗较高的Big Put场景(大容量单词Put或设置了较大cache的scan,均数据Big Put)或RegionServer的内存比较紧张的场景。
较多的IO线程,适用于单次请求内存消耗低,TPS要求(每次事务处理量)非常高的场景。这只该值的时候,以监控内存为主要参考
在hbase-site.xml配置文件中配置项为hbase.regionserver.handle.count
10.Region大小设置
配置项hbase.hregion.max.filesize,所属配置文件为hbase-site.xml,默认大小是256m。在当前RegionServer上单个Region的最大存储空间,单个Region超过该值时,这个Region会被自动split成更小的Region。小Region对split和compaction友好,因为拆分Region或compact小Region里的StoreFile速度非常快,内存占用低。缺点是split和compaction会很频繁,特别是数量较多的小Region不同的split,compaction,会导致集群响应时间波动很大,Region数量太多不仅给管理上带来麻烦,设置会引起一些HBase个bug。一般 512M 以下的都算小Region。大 Region 则不太适合经常 split 和 compaction,因为做一次 compact 和 split 会产生较长时间的停顿,对应用的读写性能冲击非常大。
此外,大 Region 意味着较大的 StoreFile,compaction 时对内存也是一个挑战。如果你的应用场景中,某个时间点的访问量较低,那么在此时做 compact和split,既能顺利完成 split 和 compaction,又能保证绝大多数时间平稳的读写性能。compaction 是无法避免的,split 可以从自动调整为手动。只要通过将这个参数值调大到某个很难达到的值,比如 100G,就可以间接禁用自动split(RegionServer 不会对未到达 100G 的 Region 做 split)。再配合RegionSplitter 这个工具,在需要 split 时,手动 split。手动 split 在灵活性和稳定性上比起自动 split 要高很多,而且管理成本增加不多,比较推荐 online 实时系统使用。内存方面,小 Region 在设置 memstore 的大小值上比较灵活,大 Region 则过大过小都不行,过大会导致 flush 时 app 的 IO wait 增高,过小则因 StoreFile 过多影响读性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值