Giới thiệu dự án

Sự bùng nổ của kỷ nguyên số hóa đã tạo ra sự gia tăng chóng mặt về khối lượng thông tin toàn cầu. Theo các nghiên cứu thống kê công nghệ, khối lượng dữ liệu kỹ thuật số có tốc độ tăng trưởng gấp đôi sau mỗi 3 năm; nếu như vào năm 2000 có tới 75% thông tin được lưu trữ trên các phương tiện tương tự (analog) như giấy tờ, phim ảnh thì hiện nay dưới 2% dữ liệu tồn tại ở dạng analog. Đáng chú ý, hơn 80% tổng lượng dữ liệu mới sinh ra là dữ liệu phi cấu trúc (unstructured data) bao gồm văn bản, tài liệu, nhật ký hệ thống (log files), hình ảnh, video và luồng dữ liệu cảm biến từ các thiết bị thông minh.

Hệ thống cơ sở dữ liệu quan hệ truyền thống (RDBMS) vốn dựa trên nguyên tắc chuẩn hóa dữ liệu nghiêm ngặt và tính toàn vẹn giao dịch ACID (Atomicity, Consistency, Isolation, Durability) đã bộc lộ những giới hạn nghiêm trọng. Khi đối mặt với quy mô dữ liệu chạm ngưỡng Terabyte (TB) đến Petabyte (PB) cùng tốc độ ghi nhận yêu cầu phản hồi tức thì (tính bằng mili-giây), mô hình mở rộng theo chiều dọc (Vertical Scaling - nâng cấp phần cứng máy chủ đơn lẻ) của RDBMS trở nên vô cùng tốn kém và tạo ra điểm thắt nút cổ chai I/O. Hơn nữa, RDBMS không thể lưu trữ và liên kết hiệu quả các kiểu dữ liệu phi cấu trúc đa dạng.

Đề tài "Áp dụng các kỹ thuật trong Big Data vào lưu trữ dữ liệu" do sinh viên Nguyễn Chí Thanh thực hiện dưới sự hướng dẫn của ThS. Nguyễn Trịnh Đông tại Trường Đại học Dân lập Hải Phòng (2016) tập trung giải quyết bài toán trên thông qua các mục tiêu cụ thể:

  1. Nghiên cứu tổng quan hệ sinh thái công nghệ Big Data, các mô hình điện toán đám mây (IaaS, PaaS, SaaS, DaaS) và cơ chế ảo hóa hạ tầng tính toán phân tán.
  2. Phân tích các mô hình cơ sở dữ liệu phi quan hệ (NoSQL) lưu trữ dữ liệu dạng cặp Khóa - Giá trị (Key-Value Pair - KVP) và cơ sở dữ liệu hướng tài liệu (Document Store) như MongoDB, CouchDB.
  3. Làm chủ nguyên lý vận hành của hệ thống tệp phân tán Hadoop Distributed File System (HDFS) và mô hình xử lý tính toán song song MapReduce.
  4. Thiết kế, cấu hình và triển khai thực nghiệm một cụm Hadoop Cluster hoàn chỉnh trên nền tảng Linux (Ubuntu), thực hiện nạp tệp và xử lý tập dữ liệu văn bản phi cấu trúc quy mô lớn.

Giải pháp tập trung tận dụng kiến trúc mở rộng theo chiều ngang (Horizontal Scalability) trên các cụm phần cứng thông dụng (Commodity Hardware), phân chia dữ liệu thành các khối (blocks) và nhân bản phân tán nhằm đạt được năng lực lưu trữ dung lượng cao, khả năng chịu lỗi (Fault Tolerance) và tối ưu hóa chi phí đầu tư hạ tầng cho doanh nghiệp.

Phạm vi nghiên cứu tập trung vào việc quản lý hạ tầng lưu trữ HDFS và mô hình thực thi MapReduce v1 (với JobTrackerTaskTracker), kết hợp kỹ thuật khai phá và xử lý dữ liệu văn bản. Đề tài chưa bao gồm các hệ thống xử lý luồng thời gian thực dạng Streaming (như Apache Spark Streaming hay Apache Flink).


Phân tích và thiết kế giải pháp

Phân tích hiện trạng

Trước khi xây dựng hệ thống phân tán, việc đánh giá các công nghệ lưu trữ hiện hữu là bắt buộc nhằm xác định đúng khoảng trống công nghệ và lựa chọn kiến trúc phù hợp với dữ liệu lớn:

Tiêu chí Cơ sở dữ liệu quan hệ (RDBMS - PostgreSQL) CSDL Tài liệu NoSQL (MongoDB / CouchDB) Hệ thống phân tán Hadoop (HDFS & MapReduce)
Mô hình dữ liệu Bảng có cấu trúc, lược đồ cố định (Schema-on-write) Lược đồ linh hoạt (BSON/JSON), Document Hệ thống tệp phân tán (Schema-on-read), tệp phẳng
Khả năng mở rộng Chiều dọc (Scale-up), mở rộng ngang rất phức tạp Mở rộng ngang tốt qua cơ chế Sharding Mở rộng ngang không giới hạn trên Commodity Hardware
Mức độ toàn vẹn Đảm bảo tuyệt đối chuẩn ACID Tuân theo BASE / Eventual Consistency Nhất quán mức tệp tin, mô hình WORM (Write Once, Read Many)
Kiểu dữ liệu tối ưu Dữ liệu giao dịch có cấu trúc (OLTP) Dữ liệu bán cấu trúc, ứng dụng Web/Mobile Dữ liệu lớn đa cấu trúc, phân tích hàng loạt (Batch Processing)
Khả năng chịu lỗi Dựa trên Master-Slave Replication đắt đỏ Tự động cân bằng và sao chép theo Replica Set Tự động nhân bản Block (mặc định hệ số nhân bản $R=3$)

Dựa trên yêu cầu nghiệp vụ quản trị kho dữ liệu văn bản, các tính năng kỹ thuật được phân loại theo mô hình ưu tiên MoSCoW:

  • Must-have (Bắt buộc): Hệ thống lưu trữ tệp phân tán HDFS tự động phân mảnh và nhân bản dữ liệu; mô hình tính toán song song MapReduce gồm hai pha Map và Reduce độc lập; quản lý phân quyền người dùng chuyên biệt (hduser).
  • Should-have (Nên có): Giao diện Web UI giám sát trạng thái NameNode (Port 50070) và JobTracker (Port 50030); hỗ trợ định dạng dữ liệu linh hoạt (JSON, BSON, Plain Text).
  • Could-have (Có thể có): Tích hợp GridFS để lưu trữ các tệp nhị phân vượt ngưỡng dung lượng BSON; cơ chế nén dữ liệu nhằm tiết kiệm không gian đĩa.
  • Won't-have (Chưa triển khai): Xử lý truy vấn SQL tương tác trực tiếp qua Apache Hive hoặc thời gian thực qua Apache Impala.

Thách thức kỹ thuật lớn nhất là hiện tượng thắt nút cổ chai băng thông mạng khi di chuyển các khối dữ liệu khổng lồ giữa các máy chủ. Hadoop giải quyết triệt để vấn đề này bằng nguyên lý Data Locality (chuyển logic tính toán đến vị trí máy chủ đang chứa dữ liệu vật lý thay vì kéo dữ liệu về node tính toán).

Thiết kế hệ thống

Hệ thống được thiết kế theo mô hình kiến trúc phân tán Master/Slave kết hợp giữa tầng lưu trữ HDFS và tầng xử lý tính toán MapReduce.

Technology Stack và Thông số phiên bản:

  • Hệ điều hành: Linux Ubuntu 14.04 / 16.04 LTS (64-bit).
  • Môi trường thực thi: Oracle Java Development Kit (JDK) 1.7.0 / 1.8.0.
  • Nền tảng Big Data: Apache Hadoop Core Framework v1.2.1 / v2.6.0.
  • Giao thức bảo mật kết nối: OpenSSH Server & Client (Xác thực không mật khẩu - Passwordless SSH qua cặp khóa RSA).
  • CSDL Bổ trợ: MongoDB Community Server v3.2 (Document Store), PostgreSQL v9.4 (Relational Metadata).

Thiết kế tầng lưu trữ HDFS:

  • Block Size: Mặc định được cấu hình 64MB (hoặc 128MB) giúp tối ưu hóa thời gian tìm kiếm trên đĩa (Disk Seek Time) so với thời gian truyền dữ liệu (Transfer Rate).
  • Replication Factor ($R$): Thiết lập $R = 3$. Một khối dữ liệu được ghi vào DataNode cục bộ, một bản sao được gửi sang node khác cùng Rack và bản sao thứ ba được đặt tại node thuộc Rack khác (Rack Awareness Strategy).
  • Pipeline Data Flow: Quá trình ghi dữ liệu diễn ra theo cơ chế ống dẫn (Client $\rightarrow$ DataNode 1 $\rightarrow$ DataNode 2 $\rightarrow$ DataNode 3), đảm bảo tính toàn vẹn và giải phóng tài nguyên mạng của Client.

Methodology

Phương pháp luận phát triển của đề tài áp dụng mô hình thực nghiệm lặp có kiểm soát (Iterative Experimental Methodology), kết hợp chặt chẽ giữa nghiên cứu lý thuyết và triển khai hệ thống:

[Nghiên cứu kiến trúc & Chuẩn bị môi trường]
  • Mốc thời gian triển khai: Từ 03/10/2016 đến 30/12/2016 (Thời lượng: 12 tuần).
  • Kế hoạch quản trị rủi ro:
    • Rủi ro lỗi phân giải mạng giữa các Node: Khắc phục bằng cách cấu hình cố định tệp /etc/hosts và gán địa chỉ IP tĩnh cho toàn bộ các node.
    • Rủi ro tràn bộ nhớ NameNode: Hạn chế tối đa việc lưu trữ các tệp siêu nhỏ (Small Files Problem) bằng cách gộp tệp văn bản trước khi đẩy lên HDFS.
    • Rủi ro mất dữ liệu khi Node sụp đổ: Áp dụng cơ chế Heartbeat (3 giây/lần); nếu sau 10 phút node không phản hồi, NameNode tự động điều phối các DataNode còn lại nhân bản lại các block bị thiếu để khôi phục $R=3$.

Implementation và kết quả

Development process

Quá trình xây dựng cụm phân tán và ứng dụng xử lý dữ liệu được tiến hành theo 4 giai đoạn cụ thể:

  1. Chuẩn bị môi trường hệ thống: Tạo nhóm người dùng hadoop và tài khoản chuyên trách hduser trên hệ điều hành Linux Ubuntu. Cấu hình cơ chế xác thực SSH Passwordless giữa Master và Slaves:

    # Tạo cặp khóa RSA và phân phối khóa công khai
    sudo addgroup hadoop
    sudo adduser --ingroup hadoop hduser
    su - hduser
    ssh-keygen -t rsa -P ""
    cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
    ssh localhost
    
  2. Cấu hình các tham số phân tán của Hadoop: Hệ thống yêu cầu hiệu chỉnh các tệp XML cấu hình trong thư mục conf/:

    Cấu hình hệ thống tệp trung tâm (conf/core-site.xml):

    <configuration>
      <property>
        <name>hadoop.tmp.dir</name>
        <value>/app/hadoop/tmp</value>
        <description>Thư mục tạm lưu trữ trạng thái HDFS</description>
      </property>
      <property>
        <name>fs.default.name</name>
        <value>hdfs://master:54310</value>
        <description>URI NameNode tiếp nhận yêu cầu</description>
      </property>
    </configuration>
    

    Cấu hình nhân bản dữ liệu (conf/hdfs-site.xml):

    <configuration>
      <property>
        <name>dfs.replication</name>
        <value>3</value>
        <description>Hệ số nhân bản khối dữ liệu</description>
      </property>
      <property>
        <name>dfs.block.size</name>
        <value>67108864</value> <!-- 64MB -->
        <description>Kích thước một Block dữ liệu HDFS</description>
      </property>
    </configuration>
    

    Cấu hình công cụ điều phối xử lý (conf/mapred-site.xml):

    <configuration>
      <property>
        <name>mapred.job.tracker</name>
        <value>master:54311</value>
        <description>Địa chỉ và cổng tiếp nhận tác vụ MapReduce</description>
      </property>
    </configuration>
    
  3. Cài đặt thuật toán xử lý dữ liệu văn bản MapReduce: Chương trình đếm tần suất xuất hiện của từ ngữ và thống kê văn bản phân tán được xây dựng bằng ngôn ngữ Java:

    package org.myorg;
    
    import java.io.IOException;
    import java.util.*;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.*;
    import org.apache.hadoop.mapred.*;
    
    public class TextMiningWordCount {
    
      // Lớp Mapper: Tách văn bản thành các cặp Key-Value (từ khóa, 1)
      public static class Map extends MapReduceBase 
          implements Mapper<LongWritable, Text, Text, IntWritable> {
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();
    
        public void map(LongWritable key, Text value, 
                         OutputCollector<Text, IntWritable> output, 
                         Reporter reporter) throws IOException {
          String line = value.toString();
          StringTokenizer tokenizer = new StringTokenizer(line);
          while (tokenizer.hasMoreTokens()) {
            word.set(tokenizer.nextToken().toLowerCase().replaceAll("[^a-zA-Z0-9]", ""));
            if (word.getLength() > 0) {
              output.collect(word, one);
            }
          }
        }
      }
    
      // Lớp Reducer: Tổng hợp giá trị đếm theo từng Key duy nhất
      public static class Reduce extends MapReduceBase 
          implements Reducer<Text, IntWritable, Text, IntWritable> {
        public void reduce(Text key, Iterator<IntWritable> values, 
                           OutputCollector<Text, IntWritable> output, 
                           Reporter reporter) throws IOException {
          int sum = 0;
          while (values.hasNext()) {
            sum += values.next().get();
          }
          output.collect(key, new IntWritable(sum));
        }
      }
    
      // Điều phối thực thi Job
      public static void main(String[] args) throws Exception {
        JobConf conf = new JobConf(TextMiningWordCount.class);
        conf.setJobName("TextMining-WordCount-Hadoop");
    
        conf.setOutputKeyClass(Text.class);
        conf.setOutputValueClass(IntWritable.class);
    
        conf.setMapperClass(Map.class);
        conf.setCombinerClass(Reduce.class); // Tối ưu hóa băng thông tại local node
        conf.setReducerClass(Reduce.class);
    
        conf.setInputFormat(TextInputFormat.class);
        conf.setOutputFormat(TextOutputFormat.class);
    
        FileInputFormat.setInputPaths(conf