Giới thiệu về nén dữ liệu

Nén dữ liệu là gì?

Nén dữ liệu là quá trình mã hóa lại thông tin ban đầu bằng các thuật toán và kỹ thuật đặc biệt để giảm kích thước lưu trữ hoặc băng thông truyền tải, trong khi vẫn giữ nguyên hoặc mất ít thông tin nhất có thể. Mục tiêu chính của việc nén dữ liệu là tăng hiệu quả trong lưu trữ, truyền tải và xử lý dữ liệu, đồng thời đảm bảo tính khả dụng và chất lượng cần thiết.

Có hai loại phương pháp nén chính: nén không mất dữ liệunén mất dữ liệu. Nén không mất dữ liệu đảm bảo rằng dữ liệu sau khi giải nén hoàn toàn giống với dữ liệu gốc, thường được sử dụng cho các trường hợp yêu cầu độ chính xác cao như văn bản hoặc mã nguồn. Ngược lại, nén mất dữ liệu sẽ hy sinh một phần chất lượng để đạt được tỷ lệ nén cao hơn, phù hợp với dữ liệu đa phương tiện như hình ảnh, âm thanh hoặc video.

Ưu điểm và nhược điểm của việc nén dữ liệu

  • Ưu điểm: Giảm I/O đĩa, tiết kiệm không gian lưu trữ.
  • Nhược điểm: Tăng chi phí CPU.

Khi áp dụng nén dữ liệu, cần xem xét các yếu tố sau:

  1. Với các công việc tính toán nặng (compute-intensive), nên hạn chế nén dữ liệu.
  2. Với các công việc phụ thuộc vào I/O (I/O-intensive), nên ưu tiên sử dụng nén dữ liệu.

Các thuật toán nén trong MapReduce

MapReduce hỗ trợ nhiều thuật toán nén khác nhau. Dưới đây là so sánh giữa các thuật toán phổ biến:

Tên thuật toán Ưu điểm Nhược điểm
Gzip Tỷ lệ nén cao Không hỗ trợ chia nhỏ; tốc độ nén/giải nén trung bình
Bzip2 Tỷ lệ nén cao; hỗ trợ chia nhỏ Tốc độ nén/giải nén chậm
LZO Tốc độ nén/giải nén nhanh; hỗ trợ chia nhỏ Tỷ lệ nén trung bình; cần tạo chỉ mục bổ sung để hỗ trợ chia nhỏ
Snappy Tốc độ nén/giải nén rất nhanh Không hỗ trợ chia nhỏ; tỷ lệ nén trung bình

Vị trí nén dữ liệu trong MapReduce

Trong khungワーク MapReduce, có ba vị trí có thể áp dụng nén dữ liệu:

  1. Trước khi đưa vào Map: Hadoop tự động kiểm tra phần mở rộng tên tệp. Nếu phù hợp, nó sẽ áp dụng codec thích hợp để nén/giải nén tệp. Nếu dữ liệu nhỏ hơn kích thước khối (128MB), hãy ưu tiên các thuật toán nén/giải nén nhanh như LZO hoặc Snappy. Nếu cần chia nhỏ, hãy chọn Bzip2 hoặc LZO.
  2. Đầu ra của Mapper: Để giảm I/O mạng giữa MapTask và ReduceTask, hãy chọn các thuật toán nén/giải nén nhanh như LZO hoặc Snappy.
  3. Đầu ra của Reducer: Nếu dữ liệu cần được lưu trữ lâu dài, hãy chọn các thuật toán có tỷ lệ nén cao như Bzip2 hoặc Gzip. Nếu dữ liệu sẽ được sử dụng làm đầu vào cho MapReduce tiếp theo, hãy cân nhắc cả kích thước dữ liệu và khả năng chia nhỏ.

Cấu hình tham số nén

Hadoop cung cấp các codec để hỗ trợ nhiều thuật toán nén/giải nén khác nhau. Để bật nén trong Hadoop, bạn có thể cấu hình các tham số sau:

Ví dụ thực hành 1: Nén ở đầu ra của Map

Chúng ta có thể áp dụng nén cho kết quả trung gian của MapTask để cải thiện hiệu suất. Điều này giúp giảm I/O đĩa và mạng. Dưới đây là ví dụ về cách cấu hình:


package vn.example.mapreduce.compress;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.BZip2Codec;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountDriver {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        
        // Kích hoạt nén ở đầu ra của Map
        conf.setBoolean("mapreduce.map.output.compress", true);
        
        // Thiết lập codec nén cho đầu ra của Map
        conf.setClass("mapreduce.map.output.compress.codec", BZip2Codec.class, CompressionCodec.class);

        Job job = Job.getInstance(conf);
        job.setJarByClass(WordCountDriver.class);
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        boolean result = job.waitForCompletion(true);

        System.exit(result ? 0 : 1);
    }
}

Ví dụ thực hành 2: Nén ở đầu ra của Reduce

Để áp dụng nén cho đầu ra của Reducer, chúng ta chỉ cần thêm hai dòng mã sau vào driver:


package vn.example.mapreduce.compress;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.BZip2Codec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCountDriver {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();

        Job job = Job.getInstance(conf);
        job.setJarByClass(WordCountDriver.class);

        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // Kích hoạt nén ở đầu ra của Reduce
        FileOutputFormat.setCompressOutput(job, true);

        // Chọn codec nén
        FileOutputFormat.setOutputCompressorClass(job, BZip2Codec.class);

        boolean result = job.waitForCompletion(true);
        System.exit(result ? 0 : 1);
    }
}

Thẻ: hadoop MapReduce data-compression bzip2 lzo

Đăng vào ngày 16 tháng 6 lúc 19:12