众所周知,HBase 0.94对性能做了很多优化,记录一下个人对其实现细节及如何更好应用的理解。
0.94引入了两个在HBase层的数据压缩:
一.DataBlock compression
1.1 作用
DataBlock compression指的是对HFile v2中的Data Block进行压缩,Data Block既存储在Disk上(HDFS中),也会存在于LRU Cache中,所以此压缩特性支持:
a)Disk、Cache上都不开启
b)Disk、Cache上都开启
c)Cache上开启,Disk上开启
但不支持
d)Cache上不开启,Disk开启
由此可见,此压缩特性的作用是:
a)节省LRU Cache的空间使用,提升cache命中率,优化读性能
b)节省Disk空间使用
当然,前者是主要目的,后者我们有对HFile的全局压缩算法,如LZO
1.2 副作用
目前,DataBlock压缩特性默认是关闭的,显然,其能优化某些业务场景,但盲然使用肯定会带来副作用:
a)Data Block解压缩,(如果一个Block(默认64KB)中包含很多KV,这个开销会比较大)
b)某些场景,压缩后数据更大
1.3 压缩算法
a)PREFIX
向Block中写入KV时,和前一条KV比较Key(这里的Key=Row+Family+Qualifier+Timestamp+Type,具体可见附件),对于相同的前缀byte, 则不再重复写入
根据KeyValue结构(见附件),某KV具体压缩后的内容:
*KeyLength压缩为1~5个字节(使用7-bit encoding,见附注)
*ValueLength压缩为1~5个字节
*和上个KV比较Key的内容,写入相同的前缀byte的长度,1~5个字节
*除相同前缀部分,剩余的Key内容
*Value内容
在最坏情况下,一条KV经过此算法压缩后会大小会增加3个字节
b)DIFF
向Block中写入KV时,会和前一条KV进行全面比较(如Key长度,value长度,Row,timestamp,type),对于相同的信息则不再写入,同时KV中的family内容只写一次(因为同个Block中,他们的family肯定是相同的)
某KV具体压缩后的内容:
*一个字节的flag(这个flag的作用后面解释)
*如果和上个KV的Key长度不一样,则写入1~5个字节的KeyLength
*如果和上个KV的Value长度不一样,则写入1~5个字节的KeyLength
*和上个KV比较Key的内容,写入相同的前缀byte的长度,1~5个字节(此比较不包含timestamp和type,而PREFIX算法中是包含的)
*剩余的Row内容(如果相同前缀比较少)
*如果是第一条KV,写入family内容
*剩余的qualifier内容
*写入1~8字节的timestamp或者与上个KV的timestamp的差(是原值还是写与上个KV的差,取决于哪个字节更小)
*如果和上个KV的type不一样,则写入1字节的type
*Value内容
在解压缩时,怎么判断和上个KV的Key长度是否一样,Value长度是否一样,写入的timestamp是原值还是差呢等等,这些都是通过最早写入的1个字节的flag来实现的,
这个字节中的8位bit,含义是:
第0位,如果为1,Key长度一样
第1位,如果为1,Value长度一样
第2位,如果为1,type一样
第3位,如果为1,则写入的timestamp是差值
第4,5,6位,这3位组合起来的值(能表示0~7),表示写入的timestamp或差值的字节数
第7位,如果为1,表示写入的timestamp或差值取反了(比如timestamp差值为负数,为了节省空间,会写入绝对值)
由此可见,DIFF算法是针对KeyValue的结构而量身设计的
c)FAST_DIFF
FAST_DIFF与DIFF的原理一样,只是减小了压缩量,提升了压缩速度,
某KV具体压缩后的内容:
*一个字节的flag
*如果和上个KV的Key长度不一样,则写入1~5个字节的KeyLength
*如果和上个KV的Value长度不一样,则写入1~5个字节的KeyLength
*和上个KV比较Key的内容,写入相同的前缀byte的长度,1~5个字节(此比较不包含timestamp和type,而PREFIX算法中是包含的)
*剩余的Row内容(如果相同前缀比较少)
*如果是第一条KV,写入family内容
*剩余的qualifier内容
*写入1~8字节的timestamp
*如果和上个KV的type不一样,则写入1字节的type
*如果和上个KV的Value内容不一样,则写入Value内容
1个字节的flag的8位bit含义:
第0,1,2位,这3位组合起来的值(能表示0~7),表示写入的timestamp的字节数
第3位,如果为1,Key长度一样
第4位,如果为1,Value长度一样
第5位,如果为1,type一样
第6位,如果为1,Value内容一样
第7位,闲置...
由此可见,相比DIFF,FAST_DIFF只是减少了对timestamp的压缩,但是增加了Value内容是否一样的判断,在某些情景(如value只是用来计数,或者value是一种类型选项值),那么可以大幅减少相同value内容的重复写入
1.4 应用场景及如何配置
上面介绍了3种压缩算法的原理,由此可简单分析下他们的应用场景:
1)PREFIX,这是一个比较公用的压缩算法,其压缩过程也比较简单快速,通用于存在相同的Row前缀的情景
2)DIFF, 相比于PREFIX,同样是需要应用在存在相同的Row前缀的情景,但其只写一份family内容,写入timestamp的差值,比较长度是否一样等特性,使其压缩幅度会更大,当然压缩的CPU开销也会稍大
3)FAST_DIFF,和DIFF类似,但是对于存在相同Value内容的场景,那肯定是使用它了
空口无凭,实验为据,具体场景,数据为准
如何配置?
Data Block的压缩算法选择是表中的一个列族属性,你可以通过api HColumnDescriptor#setDataBlockEncoding来开启或关闭或更改压缩算法,另外在开启压缩时,你可以通过HColumnDescriptor#setEncodeOnDisk决定是否在写入Disk时也采用压缩
二.HLog compression
2.1 为什么使用HLog压缩
为了保证数据安全性,每put一次,都会写入一条hlog记录,每一条hlog记录都会包含:table name、region name、row、family、qualifier等,如果数据写入集中在某表、某region乃至某row、某family,那么HLog的文件中就会存在大量重复的内容,压缩由此而生
2.2实现原理
HLog压缩采用的是词典压缩法,其写入一条log记录时的压缩行为:
*查找table是否在table词典中,如果不是,该table name写入到hlog 文件中,并加入到table词典中,对应一个short值;如果是,则hlog文件中写入一个short值,以代表该table name
*region family qualifier row,也是按照上述方法写入到hlog文件中
所以,写一个hlog文件时,会维护5个词典,即table词典、region词典、family词典、qualifier词典、row词典
2.3 作用
压缩的作用自然是减小hlog记录的写入大小,加快写hlog的速度,提升写性能;但是,个人认为,单条hlog记录压缩后减少几十或上百字节,对于其本身就不大而言,并不能提高多少HBase的写数据速度。
不过,其还存在着一个侧面作用,增加单个hlog文件的数据记录量,这会一定程度上提高memstore的内存使用率,从而提升全局的flush效率、compaction效率。
2.4如何配置及应用场景
Server端修改配置hbase.regionserver.wal.enablecompression为true(默认false)开启HLog压缩特性
应用场景:
*数据写入比较分散在各个表,各个region的,就不要考虑了
*数据写入比较集中的可以考虑开启,但测试数据为准,如果写性能没啥优化,那还是别尝这个鲜了,新特性免不了会有风险
以上只是个人见解,欢迎指正
附注:
7-bit 压缩法,针对Integer数据的一种压缩算法,可以将4个字节的Int型数据压缩为1~5个字节,数值越小,压缩后的字节数越少,所以对值小的Int型数据会有比较好的压缩效果,其具体压缩原理,简单介绍如下:
1.将一个Int型数据转换成32位;
2.0~7位,按原值写入
3.如果原值的第8位及以后存在1,则写入1,否则写入0,结束写入(即压缩为了1个字节)
4.如果没结束,则写入原值的第8~14位,如果原值的第15位及以后存在1,则写入1,否则写入0,结束写入
5...重复上述行为,直到写完
KV结构图:
HFileV2结构
- 大小: 63 KB
- 大小: 56.5 KB
分享到:
相关推荐
HBase是Apache Hadoop生态系统中的一个分布式、高性能、版本化、列族式数据库,它主要设计用于处理海量数据。在0.94版本中,HBase已经相当成熟,提供了稳定性和性能上的优化。这个源代码包是针对Java开发者的宝贵...
HBase 0.94 版本是该技术的一个重要里程碑,提供了稳定且高效的数据存储解决方案。 1. **HBase 架构** - **分布式模型**:HBase 是一个列式存储的分布式数据库,数据分布在多台服务器上,通过 ZooKeeper 进行协调...
HBase 0.94版本是在2012年发布的,虽然现在已经有了更新的版本,但了解其在特定环境如Cygwin中的运行问题仍然有价值,因为这可以帮助我们理解在不同平台上的兼容性和调试技巧。 Cygwin是一个在Windows操作系统上...
本教程主要涵盖的是在较旧版本的Hadoop 1.0.2上安装并配置HBase 0.94,以及相关的MapReduce开发和Hadoop-Eclipse插件的编译。这些内容对于理解大数据处理的基本流程和工具使用具有重要意义。 首先,我们来详细讨论...
在HBase这样的分布式数据库系统中,数据迁移是一个常见的任务,特别是在集群扩展、故障恢复或版本升级等场景下。本文档详细介绍了如何在HBase 0.94.1版本上手动进行数据迁移,主要涉及以下几个关键步骤: 1. **数据...
在`hdfs-site.xml`中,应设置副本因子(`dfs.replication`)为2,然后定义名称节点目录(`dfs.name.dir`)和数据节点目录(`dfs.data.dir`),例如分别指向`/opt/hadoop-2.4.0/datalog1`和`/opt/hadoop-2.4.0/data...
然而,在生产环境中,HBase的读写性能优化是一个比较复杂的问题,尤其对于读延迟的优化更是需要精心设计和调优。下面我们将根据标题和描述中提到的关于HBase读性能优化策略进行详细的知识点阐述。 首先,FullGC异常...
综上所述,HBase性能优化是一个综合性的任务,涉及硬件配置、数据模型设计、查询策略、运维管理等多个方面。只有全方位考虑并实践这些策略,才能最大化发挥HBase的性能潜力,满足大数据时代下的高效率需求。
HBase是Apache软件基金会的一个开源项目,是一款基于Google Bigtable理念设计的分布式列式数据库,专为处理海量数据而设计。HBase属于Hadoop生态系统的一部分,它能够在HDFS(Hadoop Distributed File System)上...
然而,随着数据量和访问量的增加,如何对HBase的写性能进行优化成为一个重要的议题。本文旨在提供一系列优化策略,以提高HBase的写入效率和数据写入的稳定性。 首先,要理解HBase写入数据的基本流程:数据首先顺序...
在HBase这样的分布式列式数据库中,读性能的优化至关重要,因为它直接影响到应用程序的响应速度和用户体验。本文主要探讨了HBase服务器端的读性能优化策略,这些策略可以帮助解决读延迟大、资源消耗高和负载不均衡等...
"HBase性能优化" HBase是一种高性能的NoSQL数据库,广泛应用于大数据存储和处理领域。然而,HBase的性能优化是非常重要的,特别是在大规模数据集群环境中。以下是HBase性能优化的相关知识点: 启用LZO压缩 HBase...
HBase api
HBase是Apache软件基金会开发的一个开源、分布式、版本化、基于列族的NoSQL数据库,设计用于处理海量数据。在2.5.6这个版本中,HBase继续提供高性能、高可靠性以及可扩展性的特性,使得它成为大数据存储的理想选择。...
HBase是一个分布式、基于列族的NoSQL数据库,它构建于Hadoop之上,提供实时访问大量结构化数据的能力。下面是详细的步骤和相关知识点: 1. **复制和解压HBase**: - 首先,你需要将HBase的压缩包复制到 `/usr` ...
HBase是Apache软件基金会旗下的一个开源分布式NoSQL数据库,它使用了Google的Bigtable模型,并运行在Hadoop文件系统(HDFS)之上。HBase具有良好的扩展性、水平扩展和高性能等特点,特别适合处理大量的稀疏数据。...
HBase是Apache Hadoop生态系统中的一个分布式、版本化、列族式存储系统,它提供了对大规模数据集的实时访问。这个压缩包“hbase-0.94.13.rar”包含了HBase 0.94.13版本的jar包和源代码,对于学习和开发基于HBase的...
然而,从HBase 0.94版本升级到新版本是一个具有挑战性的任务,因为HBase 0.96版本的RPC协议、数据格式、HDFS文件夹结构和API都发生了变化,称为“奇点”(Singularity)。这意味着无法在不停机的情况下进行升级。 ...