1、在HDFS之上將數據壓縮好後,再存儲到HDFS
2、在HDFS內部支持數據壓縮,這裏又可以分爲幾種方法:
2.1、壓縮工作在DataNode上完成,這裏又分兩種方法:
2.1.1、數據接收完後,再壓縮
這個方法對HDFS的改動最小,但效果最低,只需要在block文件close後,調用壓縮工具,將block文件壓縮一下,然後再打開block文件時解壓一下即可,幾行代碼就可以搞定
2.1.2、邊接收數據邊壓縮,使用第三方提供的壓縮庫
效率和複雜度折中方法,Hook住系統的write和read操作,在數據寫入磁盤之前,先壓縮一下,但write和read對外的接口行爲不變,比如:原始大小爲100KB的數據,壓縮後大小爲10KB,當寫入100KB後,仍對調用者返回100KB,而不是10KB
2.2、壓縮工作交給DFSClient做,DataNode只接收和存儲
這個方法效果最高,壓縮分散地推給了HDFS客戶端,但DataNode需要知道什麼時候一個block塊接收完成了。
推薦最終實現採用2.2這個方法,該方法需要修改的HDFS代碼量也不大,但效果最高。
這裏舉一個例子:
先說文件的壓縮有兩大好處:1、可以減少存儲文件所需要的磁盤空間;2、可以加速數據在網絡和磁盤上的傳輸。尤其是在處理大數據時,這兩大好處是相當重要的。
下面是一個使用gzip工具壓縮文件的例子。將文件/user/hadoop/aa.txt進行壓縮,壓縮後爲/user/hadoop/text.gz
- package com.hdfs;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.URI;
- import org.apache.hadoop.conf.Configuration;
- import org.apache.hadoop.fs.FSDataInputStream;
- import org.apache.hadoop.fs.FSDataOutputStream;
- import org.apache.hadoop.fs.FileSystem;
- import org.apache.hadoop.fs.Path;
- import org.apache.hadoop.io.IOUtils;
- import org.apache.hadoop.io.compress.CompressionCodec;
- import org.apache.hadoop.io.compress.CompressionCodecFactory;
- import org.apache.hadoop.io.compress.CompressionInputStream;
- import org.apache.hadoop.io.compress.CompressionOutputStream;
- import org.apache.hadoop.util.ReflectionUtils;
- public class CodecTest {
- //壓縮文件
- public static void compress(String codecClassName) throws Exception{
- Class<?> codecClass = Class.forName(codecClassName);
- Configuration conf = new Configuration();
- FileSystem fs = FileSystem.get(conf);
- CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);
- //指定壓縮文件路徑
- FSDataOutputStream outputStream = fs.create(new Path("/user/hadoop/text.gz"));
- //指定要被壓縮的文件路徑
- FSDataInputStream in = fs.open(new Path("/user/hadoop/aa.txt"));
- //創建壓縮輸出流
- CompressionOutputStream out = codec.createOutputStream(outputStream);
- IOUtils.copyBytes(in, out, conf);
- IOUtils.closeStream(in);
- IOUtils.closeStream(out);
- }
-
- //解壓縮
- public static void uncompress(String fileName) throws Exception{
- Class<?> codecClass = Class.forName("org.apache.hadoop.io.compress.GzipCodec");
- Configuration conf = new Configuration();
- FileSystem fs = FileSystem.get(conf);
- CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);
- FSDataInputStream inputStream = fs.open(new Path("/user/hadoop/text.gz"));
- //把text文件裏到數據解壓,然後輸出到控制檯
- InputStream in = codec.createInputStream(inputStream);
- IOUtils.copyBytes(in, System.out, conf);
- IOUtils.closeStream(in);
- }
-
- //使用文件擴展名來推斷二來的codec來對文件進行解壓縮
- public static void uncompress1(String uri) throws IOException{
- Configuration conf = new Configuration();
- FileSystem fs = FileSystem.get(URI.create(uri), conf);
-
- Path inputPath = new Path(uri);
- CompressionCodecFactory factory = new CompressionCodecFactory(conf);
- CompressionCodec codec = factory.getCodec(inputPath);
- if(codec == null){
- System.out.println("no codec found for " + uri);
- System.exit(1);
- }
- String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
- InputStream in = null;
- OutputStream out = null;
- try {
- in = codec.createInputStream(fs.open(inputPath));
- out = fs.create(new Path(outputUri));
- IOUtils.copyBytes(in, out, conf);
- } finally{
- IOUtils.closeStream(out);
- IOUtils.closeStream(in);
- }
- }
-
- public static void main(String[] args) throws Exception {
- //compress("org.apache.hadoop.io.compress.GzipCodec");
- //uncompress("text");
- uncompress1("hdfs://master:9000/user/hadoop/text.gz");
- }
- }
進行文件壓縮後,在執行命令./hadoop fs -ls /user/hadoop/查看文件信息,如下:
- [hadoop@master bin]$ ./hadoop fs -ls /user/hadoop/
- Found 7 items
- -rw-r--r-- 3 hadoop supergroup 76805248 2013-06-17 23:55 /user/hadoop/aa.mp4
- -rw-r--r-- 3 hadoop supergroup 520 2013-06-17 22:29 /user/hadoop/aa.txt
- drwxr-xr-x - hadoop supergroup 0 2013-06-16 17:19 /user/hadoop/input
- drwxr-xr-x - hadoop supergroup 0 2013-06-16 19:32 /user/hadoop/output
- drwxr-xr-x - hadoop supergroup 0 2013-06-18 17:08 /user/hadoop/test
- drwxr-xr-x - hadoop supergroup 0 2013-06-18 19:45 /user/hadoop/test1
- -rw-r--r-- 3 hadoop supergroup 46 2013-06-19 20:09 /user/hadoop/text.gz