Ⅰ 澶ф暟鎹涓甯歌佹暟鎹瀛桦偍镙煎纺涓庡帇缂╂牸寮
鍦ㄥぇ鏁版嵁镄勪笘鐣岄噷锛屾暟鎹瀛桦偍鍜屽帇缂╂妧宸ф槸镊冲叧閲嶈佺殑涓鐜銆傚畠浠涓崭粎鍏充箮绌洪棿鏁堢巼锛屾洿鐩存帴褰卞搷镌鏁版嵁澶勭悊镄勯熷害鍜屾ц兘銆傝╂垜浠娣卞叆鎺㈣ㄥ嚑绉嶅父瑙佺殑鏁版嵁瀛桦偍镙煎纺浠ュ强铡嬬缉鎶链锛屼互婊¤冻澶氭牱鍖栫殑镆ヨ㈤渶姹傚拰浼桦寲璧勬簮鍒╃敤銆棣栧厛锛岃╂垜浠鐪嬬湅鏁版嵁瀛桦偍镄勪笁绉崭富瑕佹ā寮忥细
涓轰简鍏奸【涓嶅悓镆ヨ㈡ц兘锛屾垜浠杩桦紩鍏ヤ简娣峰悎瀛桦偍锛屽阀濡栾瀺钖堜简涓よ呯殑浼桦娍锛屼互阃傚簲钖勭嶆煡璇㈤渶姹伞
Ⅱ Hadoop 压缩从理论到实战
在大数据领域,无论上层计算引擎采用的是什么,在存储过程中,压缩都是一个避不开的问题。合适的压缩选择可以降低存储成本、减少网络传输I/O。而错误的压缩选择则可能让 cpu 负荷达到瓶颈、降低并发度等等,所以是否选择压缩、选择什么压缩格式在大数据存储环节中都是一个至关重要的问题。
点评:压缩时间和压缩率之间的取舍本质上是 cpu 资源和存储资源的取舍。是否需册猛要支持分片也不是绝对的,如果单个文件大小均小于 splitSize,则没必要支持分片。
点评:一阶段考虑尽可能支持分片(单个文件大于 splitSize 时)。二阶段考虑尽可能快的压悄姿基缩速度。三阶段根据是作为长期归档(几乎不用)or 作为下一作业输入,考虑尽可能高的压缩能力 or 支持分片。
点评:有两点需要注意,第一点:这里的速度和压缩率没有具体测试数据,而是给出了一个模糊的表达。因为即使具体测试了速度和压缩率,也会因数据不同而结果有很大的差异。后面会给出测试的脚本,大家可以结合自己的表数据自行测试。第二点:有些压缩格式性能参数很相似,为什么 Hadoop 中要搞这么多种?较为直观的一个原因是:不同存储格式支持的压缩是不一样的,比如 orc 存储格式只支持 zlib 和 snappy 两种压缩 [8] ,parquet 虽然支持很多压缩格式,但是不支持 bzip2 [7]
以下摘自《Hadoop The Definitive Guide》
重点阅读文中加粗片段。大致意思是:因为 gzip 压缩格式使用的 DEFLATE 压缩算法没办法做到随机任意读取,必须同步顺序读取。也就意味着没办法为每一个 block 创建一个分片(split),然后为该分片启一个 mapper 去读取数据。所以即使 gzip 文件有很多 block,MR 程序也只会启动一个 Mapper 去读取所有的 block。也即 gzip 这种压缩格式不支持分片。相反的,如果压缩格式使用的算法支持随机任意读取,那么就可以为每一个 block 创建一个分片,同时启动一个 mapper 去读取数据,这样有多少个 block 就有多少个分片,就有多少个 mapper ,这些 mapper 并行读取数据,效率大大提升。上述涉及到几个小概念,接下来分别进行详述。
一句话总结: zlib、gzip 在大数据语境中都是一种 压缩格式 ,他们使用相同的 压缩算法: DEFLATE,DefaultCodec 是 zlib 使用的 编解码器 ,Gzip 使用的编解码器是 GzipCodec
我们知道,Hadoop 在任务切分时,是按照文件的粒度进行的。即一个文件一个文件启谨进行切分。而每一个文件切分成几块,取决于 splitSize 的大小。比如两个文件,第一个文件 300M,第二个文件150M。分片大小是128M,那么对于第一个文件将会切分成3片(128M,128M,44M),第二个文件会切分成2片(128M,22M)。共计5片。所以分片数量除了由文件数决定,另一个决定因素就是 splitSize 即分片大小。
splitSize 如何计算?
几个前提:
影响参数:
接下来进行实际验证:
经过了 2.4.2 中的一系列实验,验证了一个结论:当一个输入格式支持分片时,mapper 数量是无限制的,反之 mapper 数量小于等于文件的数量。所以我们可以通过设置参数来试图调小分片大小来增加 mapper 数量看其上限是否等于文件数量即可。假如输入的文件个数只有一个,那么当 mapper 数量大于1的时候,说明该输入格式是支持分片的。
大家可以根据自己数据集和想测试的压缩和存储格式自行修改脚本。通过以上脚本跑出来的结果如下:
由 2.1 中评价压缩的三项指标可知,压缩率、压缩/解压速度、是否支持分片是衡量压缩最重要的三项指标。3.1.1小节中只对压缩率进行了测试。压缩/解压速度可以通过跑一些查询语句进一步测试。这里就不展开测试了。业界中常用的存储格式一般是 parquet, orc,所以上面测试除了纯文本只测试了这两种存储格式。
我们可以通过 hive> set io.compression.codecs; 来查看当前Hadoop集群支持的压缩,在公司的集群中查询得到的结果是:
可以看到 lzo 有两种编解码器: LzoCodec 和 LzopCodec。他们之间有什么区别呢?
如果你阅读过关于 Hadoop 压缩的文章,应该可以看到,绝大多数文章中对于 snappy 是否支持分片都是直接给出的否定的答案。 CDH 的文档中也指出来 snappy 是不支持分片的。
看文中加粗片段,虽然 snappy 本身是不支持分片的,但是如果 snappy 存储在一些特定的存储格式比如 SequenceFile 或者 Avro 中,那么是可以支持分片的。也就是说 snappy 是否支持分片是分情况讨论的。不能说使用了 snappy 压缩就一定不支持分片。前面提到了,业界中常用的存储格式一般是 parquet 或者 orc,而上面 CDH 的文章中恰恰没有提到 parquet 和 orc 是否支持,接下来以 parquet 为例,进行测试。测试内容即为 parquet + snappy 组合,是否支持分片。
首先准备数据,因为之前做压缩率测试,已经有了 parquet + snappy 文件了,这里直接拿来用。
一共3个输入文件,启了6个mapper,说明输入文件是可以分片的。即 parquet + snappy 的组合是支持分片的。在《Hadoop The Definitive Guide》中也对 parquet 是否支持分片有说明:
以 maprece.output.fileoutputformat.compress.codec 为例,这个参数可以在三个地方配置:
那么当三者都设置时,以哪个为准呢?按照经验来看,一定是粒度小的优先级大于粒度大的优先级。经过测试也验证了这种猜测。即:表级别 > hive > hadoop
初学者往往容易混淆存储格式和压缩格式之间的关系,其实二者是完全独立的。如果完整的阅读了该篇文章,应该已经消除了这一块理解对误区。这里总结一下:比如 parquet, orc,他们都是常见的 存储格式 。是否使用压缩,使用何种压缩都是可以设置的。而 zlib、gzip、lzo、lz4、snappy 等等这些都是常见的 压缩格式 ,他们既可以依附于某些 存储格式 ,比如之前提到的 parquet + snappy,orc + zlib 等等。也可以脱离特定的 存储格式 ,比如纯文本文件进行压缩,text + parquet, text + bzip2 等等。
Ⅲ “Hive进阶篇”详解存储格式及压缩方式
hive优化除了有hql语句逻辑优化,hql参数调优等等,还有一个不起眼的细节容易被忽视掉, 那便是hive数仓模型表的存储格式和压缩方式 ,hive底层数据是依托在hadoop,以HDFS文件存储在集群上的, hive数仓模型表选择一个合适的存储格式和压缩方式也是hive优化的一点 。
本篇就来聊一聊这块知识点吧。😄
hive主要有textfile、sequencefile、orc、parquet 这四种存储格式,其中sequencefile很少使用,常见的主要就是orc和parquet这两种,往往也搭配着压缩方式合理使用。
建表声明语句是: stored as textfile/orc/parquet
行式存储,这是hive表的默认存储格式,默认不做数据压缩,磁盘开销大,数据解析开销大,数据不支持分片(即代表着会带来无法对数据进行并行操作)
行列式存储,将数据按行分块,每个块按列存储,其中每个块都存储着一个索引,支持none和zlib和snappy这3种压缩方式,默认采用zlib压缩方式,不支持切片,orc存储格式能提高hive表的读取写入和处理的性能。
列式存储,是一个面向列的二进制文件格式(不可直接读取),文件中包含数据和元数据,所以该存储格式是自解析的,在大型查询时效率很快高效,parquet主要用在存储多层嵌套式数据上提供良好的性能支持,默认采用uncompressed不压缩方式。
行存储引擎 :同一条数据的不同字段都在相邻位置,所以当要查找某一条记录所有数据时行存储查询速度比较快
列存储引擎 :以列来聚集数据,相同字段的值聚集在一起,所以当查询某一个指定列的所有数据时,列存储查询速度比较快
hive主要支持gzip、zlib、snappy、lzo 这四种压缩方式。
压缩不会改变元数据的分割性,即压缩后原来的值不变。
建表声明语句是: tblproperties("orc.compress"="SNAPPY")
压缩方式的评判标准主要有以下几点:
针对压缩方式做一个小结对比:
Ⅳ 甯哥敤镄勬暟鎹铡嬬缉绠楁硶链夊摢浜涳纻
鍦ㄦ暟瀛楀寲镞朵唬锛屾暟鎹镄勫瓨鍌ㄥ拰浼犺緭鏁堢巼鏄惧缑灏や负閲嶈併备负浜嗗噺灏忓瓨鍌ㄧ┖闂村拰甯﹀介渶姹傦纴钖勭嶆暟鎹铡嬬缉绠楁硶濡傞洦钖庢槬绗嬭埇娑岀幇銆傝繖浜涚畻娉曚緷鎹涓嶅悓镄勫师鐞嗗拰阃傜敤鍦烘櫙锛屽垎涓哄彲阃嗗拰闱炲彲阃嗕袱绉岖被鍨嬶纴镞ㄥ湪鍦ㄤ缭璇佹暟鎹瀹屾暣镐х殑鍓嶆彁涓嬶纴灏藉彲鑳藉湴铡嬬缉鏁版嵁浣撶Н銆傝╂垜浠娣卞叆鎺㈣ㄤ竴涓嬭繖浜涘父鐢ㄧ殑鏁版嵁铡嬬缉绠楁硶銆
棣栧厛锛屽彲阃嗗帇缂╃畻娉曪纴濡侣uffman缂栫爜锛屼互鍏舵棤鎹熺壒镐ц屽弹鍒伴潚镌愩傚畠阃氲繃瀵规暟鎹镄勯戠巼鍒嗘瀽锛屼负姣忎釜瀛楃﹀垎閰嶆渶鐭镄勭紪镰侊纴浠庤屽疄鐜伴珮鏁堢殑铡嬬缉銆傝繖绉岖紪镰佹柟寮忕‘淇濅简瑙e帇钖庣殑鏁版嵁涓庡师濮嬫暟鎹涓镊达纴阃傜敤浜庡规暟鎹鍑嗙‘镐ц佹眰鏋侀珮镄勫満鏅銆
鎺ョ潃锛岄潪鍙阃嗗帇缂╃畻娉曞侸PEG锛屼互鐗虹壊涓瀹氱殑鏁版嵁绮剧‘搴︽崲鍙栨洿楂樼殑铡嬬缉姣斻傝繖绫荤畻娉曞湪锲惧儚澶勭悊鍜岃嗛戝帇缂╀腑骞挎硾搴旂敤锛屽挨鍏舵槸鍦ㄥ硅呜夎川閲忚佹眰鐩稿硅缉浣庣殑𨱍呭喌涓嬶纴鑳芥樉镢楀噺灏忔暟鎹閲忋
鏁版嵁铡嬬缉镄勭瓥鐣ュ氱嶅氭牱锛屽寘𨰾锘轰簬鍐呭圭殑缂栫爜锛埚傚瓧绗︿覆涓棰戠箒瀛楃︾殑棰戠巼缂栫爜锛夈佽〃绀烘柟娉曪纸濡傞湇澶镟肩紪镰佸规椂搴忔暟鎹镄勯珮鏁埚勭悊锛変互鍙婂规暟鎹娴佽勫緥镐х殑鍒╃敤锛埚傛父绋嬬紪镰佸拰RLE锛岀敤浜庤繛缁閲嶅嶆暟鎹镄勫帇缂╋级銆备緥濡傦纴"this is a example"阃氲繃棰戠巼缂栫爜鑳藉噺灏忓埌54姣旂壒锛屾瘆铡熷136姣旂壒鑺傜渷绾2.5鍊岖殑瀛桦偍绌洪棿銆
Delta鍜娈elta-of-Delta缂栫爜鍒椤湪澶勭悊鏂囦欢铡嗗彶璁板綍鍜屽崟璋冨簭鍒楁椂琛ㄧ幇鍑鸿壊锛岄厤钖圧LE绛夋妧链锛岃兘鏄捐宪闄崭绠鏁版嵁澶у皬銆侱elta阃氲繃阃愪釜鍏幂礌镄勫樊寮傛潵铡嬬缉鏁版嵁锛岃屼簩阒跺樊鍒嗙紪镰佸垯杩涗竴姝ュ垎鏋愬墠钖庝袱涓鍏幂礌镄勫樊寮傦纴涓よ呭湪鐗瑰畾鍦烘櫙涓嬮兘鑳芥彁渚涢珮鏁埚帇缂┿
Zig-zag缂栫爜鐗瑰埆阍埚硅礋鏁帮纴涓嶥elta缁揿悎鑳芥湁鏁埚勭悊灏忔暟锛屽疄鐜伴珮鏁埚瓨鍌ㄣ侴oogle寮婧愮殑Snappy浠ュ叾蹇阃熺殑铡嬬缉阃熷害鍜屽悎鐞嗙殑铡嬬缉鏁堟灉锛屽箍娉涘簲鐢ㄤ簬寮婧愰”鐩锛岃孡Z4鍒欎互鍏跺瓧鑺傜骇镄勫揩阃熻В铡嬫ц兘锛岀壒鍒阃傚悎瀹炴椂鏁版嵁浼犺緭銆
Simple8b绠楁硶绠鍗曢珮鏁堬纴涓扑负灏忔暣鏁拌捐★纴浣嗗帇缂╃巼鍙鑳借缉浣庛侺ZO鍒欎互蹇阃熷帇缂╄侀暱锛屼絾瑙e帇阃熷害鐣ラ娄簬LZ4锛屾洿阃傚悎澶勭悊澶у潡鏁版嵁銆侱EFLATE绠楁硶鏄疴ip鏂囦欢镄勯粯璁ゅ帇缂╂柟寮忥纴瀹幂粨钖堜简LZ77鍜孒uffman缂栫爜锛屾彁渚涗简涓绉嶅钩琛$殑铡嬬缉绛栫暐銆
杩戝勾𨱒ワ纴Zstandard浠ュ叾楂樻晥镄勫帇缂╁拰蹇阃熺殑瑙e帇鑳藉姏宕闇插ご瑙掞纴涓烘湭𨱒ユ暟鎹铡嬬缉鎶链镄勫彂灞曟弿缁树简骞块様鍓嶆櫙銆傝孊it-packing鍒欓氲繃铡婚櫎涓嶅繀瑕佺殑浣嶏纴杩涗竴姝ヨ妭鐪佸瓨鍌ㄧ┖闂达纴浣嗗彲鑳藉奖鍝嶆暟鎹镄勮诲彇阃熷害銆
TDengine鏁版嵁搴挞噰鐢ㄤ简涓阒舵靛帇缂╋纸鍖呮嫭Delta銆丼imple8b銆亃ig-zag鍜孡Z4锛夊拰浜岄桩娈甸氱敤铡嬬缉绛栫暐锛屼互阃傚簲涓嶅悓鍦烘櫙镄勯渶姹伞傞夋嫨铡嬬缉绠楁硶镞讹纴闇瑕佺患钖堣冭槛铡嬬缉鏁堢巼銆佽В铡嬮熷害浠ュ强鏁版嵁镄勫师濮嬬簿搴︼纴浠ユ垒鍒版渶阃傚悎镄勮В鍐虫柟妗堛
鍦ㄦ暟瀛楀寲涓栫晫涓锛屾暟鎹铡嬬缉绠楁硶鏄鎻愬崌瀛桦偍鍜屼紶杈撴晥鐜囩殑鍏抽敭宸ュ叿銆傛疮涓绉岖畻娉曢兘链夊叾镫鐗圭殑浼桦娍鍜岄傜敤锣冨洿锛屼简瑙e苟𨱔垫椿杩愮敤杩欎簺宸ュ叿锛岃兘甯锷╂垜浠镟村ソ鍦扮$悊鏁版嵁锛岄檷浣庡瓨鍌ㄦ垚链锛屾彁楂樻暟鎹澶勭悊阃熷害銆