【技术领域】
本发明属于通用数据压缩技术领域,特别涉及一种基于分块排序思想的压缩预处理方法及两种解决方案。
背景技术:
每天有大量的网络数据产生于互联网。据统计,每过一秒,twitter上有超过6000条信息发布,google上有超过4万次搜索,全球有超过200万封邮件被发送。截至2016年3月,至少有46.6亿网页是可检索的。由此带来的线下日志记录数据,线下文件存储数据等的规模也非常大。这类数据具有规模相当巨大、格式相对一致的特点。高效的压缩算法是降低存储、传输开销,提升用户体验的最直接而有效的方式。现阶段广泛应用于大规模数据压缩的算法大部分都是lz77系列的算法,如gzip算法、snappy算法等。lz77系列算法的优势在于可以在相对短的时间内获得比较好的压缩效果。
lz77系列算法的原理为:将在当前字符之前读入的一部分字符串作为字典,当新字符与字典中字符匹配时,用三元组(偏移量off,匹配长度length,下个字符c)表示新字符。偏移量off表示搜索缓存中的匹配字符串相对于搜索缓存的起始位置的偏移量,匹配长度length表示匹配字符串的字符数目,下个字符c表示先行缓存中匹配字符串之后的第一个字符。简而言之,就是在一定范围内通过位置信息替换重复数据,以达到数据紧缩的目的。一个lz77算法的例子如表1所示。其中第五步中字符串the被三元组(4,3,o)替换,达到降低存储字节的目的。
表1
现实环境中,重复字符串的位置可能分布相对不集中,使得重复字符串的位置偏移量大于窗口长度,这样重复字符串便不能被三元组替换掉。
技术实现要素:
本发明的目的是克服现有技术存在的上述不足,提供一种通用的基于分块排序思想的压缩预处理方法,本发明在现有的lz77算法思想的基础上,通过对信源的结构化重组(分块、排序),将重复数据聚类,使lz77算法的优势更好地展现出来,进一步提高算法在压缩率和压缩速率上的表现。
本发明技术方案
一种通用的基于分块排序思想的压缩预处理方法,包括:
步骤1,按照预设尺寸或规则将信源分块,称作信源块,并按信源块的顺序进行编号;
步骤2,每一个信源块视作一个整体,依照字典序对信源块排序,按照排序后的顺序记录信源块编号;
步骤3,对步骤2记录的信源块的编号,首先进行二进制化以整数形式存储而不是字符串形式的操作初步降低存储字长,之后使用lz77系列算法压缩;对排序后的信源块集合,直接使用lz77系列算法压缩;
步骤4,将压缩结果以二进制形式输出至文件;
其中所述预设尺寸是根据实际信源的特征决定的,需要同时考虑到信息的完整性和信息块的独立性;对于日志一类的信源,适合将一行数据作为一个信源块;对文件集一类的信源,适合取一个不大于平均文件大小的阈值作为信源块的尺寸。
其中,步骤1所述的分块形式包括:严格按照固定尺寸将完整信源切分成若干块;或按照设定的尺寸阈值,在保证信息完整的情况下分块大小在阈值上下波动;或在保证信息完整的情况下,根据信源特征预设分块规则,将信源切分成若干块,对信源块的尺寸没有强制要求。所述的编号方式包括:显式编号和隐式编号;显示编号是指通过添加额外信息来记录信源块在信源中的位置信息,隐式编号是指将信源块中某一成分作为编号的依据,不在块中添加新的信息;编号类型包括:使用数字进行编号,或者使用字母进行编号。
步骤2所述对信源块排序方式包括:根据信源的数据特征,信源包括字符型信源和数字型信源,选择按照字典序排序或是按照数值关系排序。或者根据实际生产要求包括对处理速率的要求和对资源占用的要求,选择按照首几位字符字典序排序或按照特定信息字典序排序的排序方式;记录编号的方式包括:对于显式编号的信源,统一将编号进行顺序存储,或者分开将每一块的编号与信源块一起存储;对于隐式编号的信源,不需要对编号进行额外的存储。
步骤3所述对记录的信源块编号进行降位处理包括:根据编号的特征,通过二进制化、减掉数值分布下确界或者编码的手段,降低编码存储所需的位数。
实际生产中,nginx文件格式是一种常用的日志记录格式,其默认格式为:
log_formataccess$remote_addr–$remote_user[$time_local]“$request”$status$body_bytes_sent“$http_referer”“$http_user_agent”$http_x_forwarded_for
其中$request用来记录请求的url与http协议,是一条日志的主体部分。
实际生产中,一般的网页集(cluweb09等)是由若干网页单元构成。每个网页单元分为头部和主体两部分。头部统一地记录了当前网页的一些信息,如网页长度、url等;主体记录了网页的具体内容。
以该思想为基础,本发明提出了通用的基于分块排序思想的压缩预处理方法,在针对nginx格式访问日志数据和网页集数据压缩预处理中的应用。
应用1是对nginx格式访问日志的压缩预处理解决方案中的应用,具体步骤包括:
第1,将整个信源切割为相近大小的组,每次处理一组数据;
第2,以“$request”为界将每一组中的每一条日志记录分割,“$request”之前的成分为第一段,“$request”及其之后的成分为第二段;
第3,将当前处理的组内的所有第一段成分顺序存储zone1,不进行排序处理;
第4,对当前处理的组内的所有第二段成分编号,然后按字典序对所有第二段排序并存储为zone2,同时按排序后的顺序保存它们的编号;
第5,使用lz77系列算法对经过二进制化处理的zone1、编号组、zone2进行压缩;
第6,重复第2步~第5步,直至所有的组都被处理;
其中第1步所述分组为预备操作,是为后续排序操作划定范围;分块思想对应每次处理一行数据即一次访问记录,排序思想对应对每行数据的第二段即zone2进行排序。
应用2是对网页集压缩预处理解决方案中的应用,具体步骤包括:
第1,将整个信源切割为等大小的组,每次处理一组数据;
第2,将每一组内包含的每个网页单元,按照预设大小分块,每次分界取到一行尾部;或按照特定html标签分块规格分块;保证每个块包含的一行数据都是完整的,保证每个块内不包含来自两个网页单元的内容,在网页单元尾部不足预设大小的部分作为一块;
第3,对组内的块编号,然后按字典序排序,同时按排序后的顺序保存块的编号;
第4,使用lz77系列算法对第3步处理后的块集合和编号组进行压缩;
第5,重复第2步~第4步直至所有的组都被处理;
其中第1步所述分组为预备操作,是为后续排序操作划定范围;分块思想对应第2步在网页单元内分块,排序思想对应对每个块进行排序。
本发明的优点和有益效果:本发明可以在原lz77压缩算法的基础上将压缩比再度降低20%~50%,同时仅仅在压缩速率上有微小的损失。
【附图说明】
图1是本发明的基于分块排序的压缩预处理思想的流程模拟图;
图2是本发明的基于分块排序思想的访问日志压缩预处理方案示意图以及数据样例;
图3是本发明的基于分块排序思想的访问日志压缩预处理方案的压缩率对比图;
图4是本发明的基于分块排序思想的网页集压缩预处理方案示意图;
图5是本发明的基于分块排序思想的网页集压缩预处理方案的压缩率对比图。
【具体实施方式】
为便于理解本发明的上述目的、特征和优点,下面结合附图和具体实施方案对本发明作进一步的详细说明。显然,下述实施例仅仅是本发明的一部分实施例,而不是全部的实施例。基于本发明中的算法思想和实施例,本领域的技术人员所获得的其他实施例,都属于本发明的保护范畴。
常用的lz系列数据压缩的手段大致可以概括为:
首先通过一定的手段,找出规定范围内(字典长度)的重复字符串;其次根据一定的规则将重复出现的字符串使用更短的字节流替换;最后将替换结果和替换规则(重复字符串和短字节流的对应关系)共同保存,以便恢复。
而对于某些信源,其相邻的重复字串穿的位置偏移举例可能要大于字典长度,也就是说这样的重复字符串并不能被lz系列算法检测出来,也就不能被短字节流替换。如果能使用一定的方法,将这部分重复字符串聚集起来,无疑能够提高lz系列算法的性能。
本发明就是通过“分块和排序”的手段,达成上述目的。
实施例1
图1是本发明的通用的基于分块排序思想的压缩预处理流程模拟图。如图1所示,该方法包括:
步骤1,按照预设尺寸或规则将信源分块,按“信源块顺序”对块编号;
分块优选的方案为按固定大小将信源切分,原则上要保持每一块内的信息完整性,使得每一块的开始字符串(一块信源的第一个字符开始的若干个字符形成的字符串)能够部分或全部地和块内信息产生关联,使排序操作能够更好地聚集重复或相似字符串。为达成上述目的,可以在预设尺寸分块原则的基础上增加一些附加规则,如块的开始和结束只能在信源的一行开始或结束,块的截取点只能在某些标志性字符附近(可能意味着前面信息的结束和后面信息的开始)等。针对不同信源的特征,可以调整分块尺寸以达成上述目的,比如对于日志一类的信源,适合将一行数据作为一个信源块;对文件集一类的信源,又适合取一个不大于平均文件大小的阈值作为信源块的尺寸。
如图1的分块操作,展示的是按照固定大小截取,并保证每块的截取点位于行尾。
步骤2,每一个信源块视作一个字符串,依照字典序对其排序,记录排序后的块编号,如图中所示,记录编号“34,12,1,91,……”;
排序操作是令相似字符串聚集的核心操作。排序的依据可以是块内任何标志性字符串。如图1中的排序操作,是将一块的开始字符串作为排序依据,这里相信经过分块后的信源,每一块的开始字符串与块内信息是相关的。对于某些信源,分块后的信源块,其与块内信息相关的特征字符串可能存在于块中或块尾,由某些标志性字符标识,这样也可以将块内或块中的特征字符串作为排序依据。
步骤3,处理块的编号集,压缩编号集和块集。
如图1的二进制化操作,首先对块的编号进行二进制化处理(以整数形式存储而不是字符串形式),之后使用lz77系列算法(如gzip算法)压缩;对排序后的块集合,直接使用lz77系列算法(如gzip算法)压缩。此外,由于排序后的信源中,重复或相似信息呈现聚类分布,所以可以对lz77算法进行定制化,如认为缩小窗口长度,人为采用变长编码记录位置偏移信息等。这样做以达到在保证压缩率的前提下进一步提升压缩性能。
步骤4,将压缩结果以二进制形式输出至文件。
如图1输出所示,可以将二进制流输出至任何需要数据的地方。
实施例2、应用1
图2是本发明的基于分块排序思想的访问日志压缩预处理方法示意图及数据样例。如图2(a)所示,该方法包括:
一种基于分块排序思想的访问日志压缩预处理方法,包括:
步骤1,将整个信源切割为若干大小为64mb的组,每次处理一组数据。
这里的分组为预备操作,是为后续排序操作划定范围,不是思想中的分块操作。分块思想对应每次处理一行数据(一次访问记录),排序思想对应“对每行数据的第二块即zone2进行排序”的操作。
如图2(a)所示,我们以64mb为分组阈值截取信源,保证截取点位于行尾。阈值是通过实验统计得出,是适应实验日志数据的较好的值。实际环境中,可以根据日志的特征重新规定阈值。如对于一行日志较长的访问日志集,可以采用较大的阈值,使得一块中有足够多的日志,保证重复或相似数据的聚类效果;而对于一行日志较短的访问日志集,可以酌情采用较小的阈值,以在保证重复或相似数据的聚类效果的同时,降低排序操作的额外代价。
步骤2,以“$request”为界将一条日志记录分割,“$request”之前(不含)的成分一块,“$request”之后(含)的成分为另一块。
如图2(b)中样例所示,我们将‘get’作为标志,因为其后的request信息(“get/so/srp.gif?……http/1.1”)是一行日志的主体,因此排序操作的排序依据也应该是request信息。我们将‘get’前的信息(123.15.118.160.……+0000])切割出来,直接进行压缩、存储,以降低排序的代价,这是一种优选方案。当然也可以不进行切割,直接以request信息作为排序依据进行排序,整体将一行日志进行移动,这也能够达到相似数据聚类的目的。如果某些信源,一行日志中包括多个标志字符,且其后的信息具有一定的独立性(不同标志位后的信息关联性不大),也可以将一行日志多次切割,比如同时将request信息和浏览器信信息(“mozilla”)作为分割点。
步骤2,将一组内的所有第一块成分顺序存储zone1,不进行预处理。
这部分信息本身占总信息的比重较小,且其与request信息不具备很高的关联性,所以如图2(a)所示,直接将其压缩,而不进行排序等操作。
步骤3,对这组内的所有第二块成分编号,然后按字典序对块排序并存储为zone2,同时按块排序后的顺序保存它们的编号。
如图2所示,以request信息为依据对切割后的块排序,并记录编号组。对于多次切割的信源,会得到多个切割出的信息,如果切割出来的信息本身也具有一定的内关联行,则也可以对其进行排序等操作,使相似数据聚类。本方案中仅对以request开头的信息进行排序,排序结果如图2(c)所示。
综合步骤3和步骤4,根据数据特征,可以对一行数据进行一次或多次切割,得到若干切割部分。对于占比小、信息内关联性不高的切割部分,可以直接进行压缩,避免排序等操作的开销;对于信息内关联性较高而切割部分间关联性不高的切割部分,可以进行排序等操作,进一步提高压缩性能。
步骤4,使用lz77系列算法对处理后的zone1、编号组、zone2进行压缩。
如图2所示,优选方案对编号组进行了二进制化处理(将数值型数据的字符表示转换成整型表示,如数字12,字符型存储需要16byte的空间,而短整型存储只需8byte的空间),降低存储开销,这是因为编号组由数字构成,当然也可以使用算术编码的方式达到更好的效果。而切割出来的request信息本身包含极少的数字,所以直接进行了压缩。本方案的可拓展性强,针对不同的信源特征,也可以采用不同的手段降低存储开销。
步骤5,重复步骤2~5直至所有的组都被处理,最终可以达到的平均压缩率为17%。
我们在奇虎360的访问日志数据集上对比了进行和不进行分组排序的gzip算法压缩效果。对引用数据做如下说明:
(1)所用数据来自于用户在2015年3月14日访问msoftdl.360.cn主机的网络请求日志,大小1.5gb,共747.0396万行,每行12条记录,所属记录类型依次是:$host,$remote_ip,$null,$null,$time_local,$request,$status,$page_size,$null,$browser,$response_time和$null,图2(b)展示了一条样例数据。
(2)我们随机截取了若干100mb的片段进行压缩测试样本。
结果表明:如图3所示,使用分块排序策略的lz77算法(gzip)的平均压缩率为16.8%,相比于不使用分块排序策略的lz77算法(gzip)的平均压缩率24.1%,有30%的提升。同时使用分块排序策略的lz77算法(gzip)的平均压缩速率为55mb/s,仅比纯粹的lz77算法(gzip)的60mb/s略低;而二者的解压速率不相上下。
实施例3、应用2
图4是本发明的基于分块排序思想的网页集压缩预处理方案示意图。如图4所示,该方案包括:
步骤1,将整个信源切割为若干大小为1gb的组,每次处理一组数据。
这里所述分组为预备操作,是为后续排序操作划定范围。分块思想对应在网页单元内分块,排序思想对应对每个块进行排序。分块大小由数据集的统计信息得来,取不超过大多数网页尺寸的合适值。
选取1gb作为分组阈值,是根据实验样本特征取得的。实验样本为英文网页数据集,单个网页尺寸相对较小,所以分组阈值选取相对较小。对于一些单个页面尺寸较大的数据,可以人为选取更大的分组阈值。此外,也可以将“选取固定数量的网页为一组”作为备选方案,这样以网页数目而不是固定大小作为分块依据。
实验室用的clueweb09数据集,其内部网页按url的字典序进行排布,也就是说相似的url所指示的网页被置于相邻的位置,且这些网页具有内容相关性。如果现实环境中,网页集中网页不是按照url字典序排布,也可以考虑将整个数据集的网页按照url排序后再进行分组操作。
步骤2,进行分块操作。
如图4所示,一个分组组内包含若干网页单元(一个页面的所有信息作为一个网页单元)。优选方案是:在每个网页单元内部,按照预设大小为1kb分块,每次分界取到一行尾部,即当取够1kb的数据时操作继续,直至取到本行结束(取到‘\0’)停止。一个网页单元的最后一个块如果不够1kb,则将其独立作为一个块,不跨网页单元取数据。保证每个块包含完整的若干行数据,保证每个块内不包含来自两个网页单元的内容。
步骤3,对这组内的块编号,即对块“1,2,……,x+1,x+2,……,y+1,y+2,……v+1,v+2,……”编号,然后按字典序排序,同时按块排序后的顺序保存它们的编号。
如图4所示,一次处理一组内的所有分块,将一个分组作为完整的个体,实施分组排序方案,即分块是在网页单元内部进行的,而排序是对组内所有块进行的。
步骤4,使用lz77系列算法对处理后的块集合和编号组进行压缩,可以达到的平均压缩率为11%。
步骤5,重复步骤2~5直至所有的组都被处理。
我们在数据集clueweb09上对比了进行和不进行分组排序的lz77算法的压缩率效果。对引用数据做如下说明:
(1)所用数据来自于clueweb09,它包含了从2009年1月到2月间收集的大约10亿个网页,包含10种语言。
(2)我们随机截取了若干1gb的片段进行压缩测试样本。
结果表明:如图5所示,使用分块排序策略的lz77算法(gzip)的平均压缩率要比不使用分块排序策略的lz77算法(gzip)的低20%~50%。同时使用分块排序策略的gzip算法的平均压缩速率为38mb/s,仅比纯粹的lz77算法(gzip)的48mb/s稍低;而二者的解压速率不相上下。
通过以上的实施方式的描述,本领域的技术人员可以清楚地根据实际环境中的数据集定制分块排序压缩方案,并以软件的形式呈现。本发明的技术方案本质上或对现有的技术做出贡献的部分是架起了通用压缩算法应用于定制数据压缩的桥梁。
本发明中的各个实施例均按照算法流程描述,各个实施例之间的相同或相似部分可以互相参见,第一个实施例重点描述了整体算法框架,第二、三个实施例侧重于描述与基本框架的不同之处。尤其对于原理实施例(第一实施例)而言,由于很多具体的备选方案与信源特征直接相关,所以描述较为概括,相关之处参见应用实例(第2、3施例)即可。
以上对本发明的基于分块排序的压缩预处理思想及方案进行了详细介绍,本文中应用了具体案例对本发明的原理及实施方式进行阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。