1. 程式人生 > >hadoop2.4 支持snappy

hadoop2.4 支持snappy

back war .com 適合 存儲空間 問題 borde pyc 道理

我們hadoop2,4集群默認不支持snappy壓縮,可是近期有業務方說他們的部分數據是snappy壓縮的(這部分數據由另外一個集群提供給他們時就是snappy壓縮格式的)想遷移到到我們集群上面來進行計算。可是直接執行時報錯:

Failed with exception java.io.IOException:java.lang.RuntimeException: 
native snappy library not available: this version of libhadoop was built without snappy support
依據報錯信息顯示snappy本地庫不可用,同一時候似乎在編譯libhadoop的時候須要特別指定以支持snappy,這一點不同於hadoop1.0。hadoop1.0僅僅須要將snappy的本地庫文件往指定文件夾一拷貝即可,不須要又一次編譯libhadoop本地庫文件。

因為snappy壓縮算法壓縮比不是非常高,盡管在解壓縮效率上又一點優勢,所以我們集群默認沒有支持snappy,我們集群的數據要求是RCFile+Gzip,下面是幾種壓縮格式在hadoop中的優缺點對照:

參考地址:http://www.linuxidc.com/Linux/2014-05/101230.htm

眼下在Hadoop中用得比較多的有lzo,gzip。snappy。bzip2這4種壓縮格式。筆者依據實踐經驗介紹一下這4種壓縮格式的優缺點和應用場景,以便大家在實踐中依據實際情況選擇不同的壓縮格式。

1、gzip壓縮

長處:壓縮率比較高。並且壓縮/解壓速度也比較快;hadoop本身支持,在應用中處理gzip格式的文件就和直接處理文本一樣;有hadoop native庫。大部分linux系統都自帶gzip命令,使用方便。

缺點:不支持split。

應用場景:當每一個文件壓縮之後在130M以內的(1個塊大小內),都能夠考慮用gzip壓縮格式。譬如說一天或者一個小時的日誌壓縮成一個gzip文件,執行mapreduce程序的時候通過多個gzip文件達到並發。hive程序,streaming程序,和java寫的mapreduce程序全然和文本處理一樣,壓縮之後原來的程序不須要做不論什麽改動。

2、lzo壓縮

長處:壓縮/解壓速度也比較快,合理的壓縮率;支持split,是hadoop中最流行的壓縮格式。支持hadoop native庫;能夠在linux系統下安裝lzop命令。使用方便。

缺點:壓縮率比gzip要低一些;hadoop本身不支持。須要安裝;在應用中對lzo格式的文件須要做一些特殊處理(為了支持split須要建索引,還須要指定inputformat為lzo格式)。

應用場景:一個非常大的文本文件,壓縮之後還大於200M以上的能夠考慮,並且單個文件越大,lzo長處越越明顯。

3、snappy壓縮

長處:快速壓縮速度和合理的壓縮率;支持hadoop native庫。

缺點:不支持split;壓縮率比gzip要低;hadoop本身不支持,須要安裝。linux系統下沒有相應的命令。

應用場景:當mapreduce作業的map輸出的數據比較大的時候。作為map到reduce的中間數據的壓縮格式;或者作為一個mapreduce作業的輸出和另外一個mapreduce作業的輸入。

4、bzip2壓縮

長處:支持split;具有非常高的壓縮率。比gzip壓縮率都高;hadoop本身支持,但不支持native;在linux系統下自帶bzip2命令,使用方便。

缺點:壓縮/解壓速度慢。不支持native。

應用場景:適合對速度要求不高,但須要較高的壓縮率的時候。能夠作為mapreduce作業的輸出格式。或者輸出之後的數據比較大,處理之後的數據須要壓縮存檔降低磁盤空間並且以後數據用得比較少的情況;或者對單個非常大的文本文件想壓縮降低存儲空間,同一時候又須要支持split,並且兼容之前的應用程序(即應用程序不須要改動)的情況。

最後用一個表格比較上述4種壓縮格式的特征(優缺點):

4種壓縮格式的特征的比較
壓縮格式 split native 壓縮率 速度 是否hadoop自帶 linux命令 換成壓縮格式後,原來的應用程序是否要改動
gzip 非常高 比較快 是,直接使用 和文本處理一樣。不須要改動
lzo 比較高 非常快 否,須要安裝 須要建索引,還須要指定輸入格式
snappy 比較高 非常快 否。須要安裝 沒有 和文本處理一樣。不須要改動
bzip2 最高 是。直接使用 和文本處理一樣。不須要改動

註意:以上幾種壓縮算法都是在壓縮普通文本的前提下來說的是否支持split,假設是RCFile、Sequence Files等,本身就支持split,經過壓縮之後一樣是支持split的。

綜上,我們hadoop2.4集群要求RCFile+gzip是有一定道理的,首先RCFile格式的文件支持按列存儲。同一時候支持split,而gzip的壓縮率比較高,並且壓縮/解壓速度也比較快,所以RCFile格式的文件經過gzip壓縮後既能保證文件能split,還能保證非常高壓縮/解壓速度和壓縮比。

以上說了半天題外話,下面來進入主題來說一下如何在不替換集群本地庫文件,不重新啟動hadoop進程,也即在hadoop的client就能解決支持snappy壓縮的問題的方法:

1、編譯snappy本地庫,編譯之後snappy本地庫文件地址:/data0/liangjun/snappy/

參考地址:http://www.tuicool.com/articles/yiiiY3R

2、又一次編譯libhadoop.so文件,編譯時通過-Dsnappy.prefix指定snappy本地庫文件地址編譯:

mvn clean package -Pdist -Dtar -Pnative -Dsnappy.prefix=/data0/liangjun/snappy/ -DskipTests

註:我測試了一下,通過-Drequire.snappy編譯的libhadoop.so也是可行的:

mvn clean package -Pdist,native -DskipTests -Drequire.snappy
3、運行完上面兩步之後,終於僅僅須要拿到libhadoop.so和libsnappy.so.1兩個文件(僅僅須要這兩個文件。其它得經過我測試都過濾掉了)。下面是MapReduce和hive的使用snappy壓縮的樣例:

(1)、MapReduce。將編譯好的本地庫加到DistributedCache中就能夠:

在測試環境的clientmapred-site.xml文件加入下面兩個配置項以支持map端數據的時候按snappy壓縮:

<property>
    <name>mapreduce.map.output.compress</name>
    <value>true</value>
    <final>true</final>
  </property>
  <property>
    <name>mapreduce.map.output.compress.codec</name>
    <value>org.apache.hadoop.io.compress.SnappyCodec</value>
    <final>true</final>
  </property>

上傳libhadoop.so和libhadoop.so到指定hdfs文件夾/test/snappy/下。通過-files指定文件:

hadoop jar hadoop-mapreduce-examples-2.4.0.jar wordcount -files hdfs://ns1/test/snappy/libhadoop.so,hdfs://ns1/test/snappy/libsnappy.so.1  /test/missdisk/ /test/wordcount

(2)、hive,通過add file指定文件:

hive >add file libhadoop.so;
hive >add file libsnappy.so.1;
hive >select count(*) from ct_tmp_objrec;
表ct_tmp_objrec的數據是文本文件經過snappy壓縮的數據。ct_tmp_objrec存儲格式是普通的文本格式。

執行hql之後。發現snappy格式的數據可以正常處理計算了,可是200+M的文件僅僅能由一個map任務處理,既不支持split。

==========================================================

下面部分是就RCFile+snappy的數據是否支持split的測試:

1、創建測試表snappy_test,該表和前面的ct_tmp_objrec列全然同樣,僅僅是hive表存儲格式換成了RCFile:

CREATE EXTERNAL TABLE `snappy_test`(
  `from_id` string,
  `to_id` string,
  `mention_type` bigint,
  `repost_flag` bigint,
  `weight` double,
  `confidence` double,
  `from_uid` string,
  `to_object_label` string,
  `count` bigint,
  `last_modified` string,
  `time` string,
  `mblog_spam` bigint,
  `mblog_simhash` string,
  `mblog_dupnum` bigint,
  `mblog_attribute` bigint,
  `user_quality` bigint,
  `user_type` bigint,
  `old_weight` double,
  `obj_pos` bigint,
  `quality` bigint)
ROW FORMAT SERDE
  ‘org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe‘
STORED AS INPUTFORMAT
  ‘org.apache.hadoop.hive.ql.io.RCFileInputFormat‘
OUTPUTFORMAT
  ‘org.apache.hadoop.hive.ql.io.RCFileOutputFormat‘
LOCATION
  ‘hdfs://ns1/user/liangjun/warehouse/tables/snappy_test‘

2、將ct_tmp_objrec中plain text+snappy壓縮的數據轉成snappy_test中RCFile+gzip壓縮的數據:

hive >add file libhadoop.so;
hive >add file libsnappy.so.1;
hive >set hive.exec.compress.output=true;
hive >set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
hive >INSERT OVERWRITE table snappy_test select from_id,to_id,mention_type,repost_flag,weight,confidence,from_uid,to_object_label,count,last_modified,time,mblog_spam,mblog_simhash,mblog_dupnum,mblog_attribute,user_quality,user_type,old_weight,obj_pos,quality from ct_tmp_objrec;

3、查詢snappy_test中的RCFile+snappy數據看能否split

hive >add file libhadoop.so;
hive >add file libsnappy.so.1;
hive >select count(*) from snappy_test;
執行hql之後,發現RCFile+snappy的數據可以正常處理計算,同一時候200+M的文件split成兩個map任務處理。測試完畢。

參考地址:

http://blog.cloudera.com/blog/2011/09/snappy-and-hadoop/

http://blog.csdn.net/czw698/article/details/38387657

http://www.linuxidc.com/Linux/2014-05/101230.htm

http://book.2cto.com/201305/21922.html

http://blog.csdn.net/czw698/article/details/38387657

http://blog.csdn.net/czw698/article/details/38398399

http://www.tuicool.com/articles/yiiiY3R








hadoop2.4 支持snappy