Tải và cài đặt gói Apache Hudi (Bundle)
Bước đầu tiên là tải xuống bản phân phối Apache Hudi đã được đóng gói sẵn (bundle) bao gồm cả JAR file cần thiết cho Spark.
Tải file bundle từ kho lưu trữ chính thức của Apache, sử dụng phiên bản ổn định nhất (ví dụ: 0.14.0) để đảm bảo tính tương thích với Spark 3.x trên Ubuntu 24.04.
cd /opt/hudi
sudo wget https://archive.apache.org/dist/hudi/0.14.0/apache-hudi-0.14.0-bundle.tgz
Phân tích và giải nén file archive vào thư mục đích. Thao tác này sẽ tạo ra thư mục chứa các thành phần cần thiết của Hudi.
sudo tar -xzf apache-hudi-0.14.0-bundle.tgz
Truy cập vào thư mục `dist` trong bundle vừa giải nén để xác nhận cấu trúc file. Bạn cần thấy thư mục `spark` chứa các JAR file.
ls /opt/hudi/apache-hudi-0.14.0-bundle/dist/spark
Verify kết quả: Bạn sẽ thấy danh sách các file JAR như `hudi-spark3.x-bundle_2.12-0.14.0.jar` và `hudi-spark3.x-bundle_2.12-0.14.0-hadoop3.jar`.
Cấu hình thư mục lưu trữ Hudi trên HDFS
Trước khi chạy bất kỳ thao tác nào của Hudi, cần chuẩn bị nơi lưu trữ dữ liệu trên HDFS. Hudi hoạt động dựa trên cơ chế quản lý metadata và file data trong một thư mục cụ thể gọi là base path.
Tạo thư mục gốc cho Hudi trên HDFS. Thư mục này sẽ chứa các bảng (tables) và metadata của chúng.
hdfs dfs -mkdir -p /user/hudi/data
Thiết lập quyền truy cập (permission) cho thư mục mới tạo để đảm bảo user đang chạy Spark (thường là `spark` hoặc `hadoop`) có thể ghi dữ liệu vào.
hdfs dfs -chmod -R 755 /user/hudi/data
Verify kết quả: Chạy lệnh liệt kê thư mục để xác nhận thư mục đã được tạo và quyền hạn đã được cấp.
hdfs dfs -ls -d /user/hudi/data
Kết quả mong đợi: Dòng output hiển thị quyền `drwxr-xr-x` và owner là user hiện tại.
Cài đặt và cấu hình Hudi với Spark (spark-hudi)
Để Spark có thể đọc và ghi dữ liệu Hudi, cần cấu hình Spark để nhận diện Hudi như một nguồn dữ liệu (data source) và sử dụng đúng JAR file.
Sửa file cấu hình `spark-env.sh` (hoặc `spark-defaults.conf`) để chỉ định đường dẫn đến Hudi Bundle. Đây là cách chuẩn để tích hợp Hudi vào môi trường Spark standalone hoặc cluster.
Đường dẫn file cấu hình: `/etc/spark/conf/spark-env.sh`
Nội dung cần thêm vào file (giả sử đường dẫn bundle là `/opt/hudi/apache-hudi-0.14.0-bundle/dist/spark`):
export HADOOP_CONF_DIR=/etc/hadoop/conf
export SPARK_DIST_CLASSPATH=$(hadoop classpath)
export HUDI_BUNDLE_PATH=/opt/hudi/apache-hudi-0.14.0-bundle/dist/spark/hudi-spark3.x-bundle_2.12-0.14.0-hadoop3.jar
Cấu hình tham số `spark.sql.extensions` để kích hoạt cú pháp SQL mở rộng của Hudi (như `CREATE TABLE ... USING hudi`).
Đường dẫn file cấu hình: `/etc/spark/conf/spark-defaults.conf`
Nội dung cần thêm vào file:
spark.sql.extensions org.apache.spark.sql.hudi.HudiSqlExtensions
spark.sql.catalog.spark_catalog org.apache.spark.sql.hudi.catalog.HoodieCatalog
spark.serializer org.apache.spark.serializer.KryoSerializer
spark.kryo.registrator org.apache.hudi.common.table.timeline.HoodieInstantSerde
Verify kết quả: Sau khi chỉnh sửa, chạy lệnh `spark-shell` và nhập lệnh `spark` để kiểm tra xem các class của Hudi đã được load vào classpath chưa.
spark-shell --help | grep hudi
Kết quả mong đợi: Không có lỗi về missing class, và bạn có thể khởi động shell thành công.
Khởi tạo và kiểm tra phiên bản hoạt động của Hudi
Để xác nhận Hudi đã được tích hợp đúng cách vào Spark, cần chạy một script kiểm tra phiên bản và khả năng nhận diện catalog.
Khởi động Spark Shell với tham số `--packages` để tải Hudi trực tiếp từ Maven nếu chưa cấu hình static, hoặc sử dụng cấu hình đã làm ở phần trên. Ở đây ta dùng cách cấu hình tĩnh để đảm bảo tính ổn định.
spark-shell
Trong môi trường Spark Shell, thực thi lệnh Scala để in ra phiên bản Hudi hiện tại đang được sử dụng.
import org.apache.hudi.common.table.HoodieTableMetaClient
val version = org.apache.hudi.HoodieTableMetaClient.VERSION
println(s"Hudi Version: $version")
Verify kết quả: Dòng output hiển thị phiên bản Hudi (ví dụ: `0.14.0`). Nếu không in ra được, có thể do JAR chưa được load đúng.
Xác thực kết nối giữa Hudi, Spark và HDFS
Bước cuối cùng là tạo một bảng thử nghiệm để xác nhận luồng dữ liệu: Spark (SQL Engine) -> Hudi (Storage Format) -> HDFS (File System).
Thực thi lệnh SQL để tạo một bảng Hudi mới trong catalog Spark, chỉ định path lưu trữ trên HDFS và định dạng lưu trữ là `COPY_ON_WRITE` (COW) hoặc `MERGE_ON_READ` (MOR).
spark.sql("CREATE TABLE hudi_test_table (id INT, name STRING, ts TIMESTAMP) USING hudi OPTIONS (hoodie.table.type='COPY_ON_WRITE', path='/user/hudi/data/hudi_test_table')")
Thực hiện thao tác chèn dữ liệu mẫu vào bảng vừa tạo để kích hoạt cơ chế ghi của Hudi lên HDFS.
spark.sql("INSERT INTO hudi_test_table VALUES (1, 'Alice', current_timestamp()), (2, 'Bob', current_timestamp())")
Duyệt qua thư mục trên HDFS để xác nhận Hudi đã tạo ra các file metadata (`.hoodie` folder) và file data (`.parquet`).
hdfs dfs -ls /user/hudi/data/hudi_test_table
Verify kết quả: Bạn sẽ thấy thư mục `.hoodie` chứa file `hoodie.properties` và các file `.parquet` chứa dữ liệu thực tế. Đây là dấu hiệu xác nhận Hudi đã ghi dữ liệu thành công vào HDFS thông qua Spark.
Truy vấn lại dữ liệu từ bảng Hudi để đảm bảo tính nhất quán của dữ liệu sau khi ghi.
spark.sql("SELECT * FROM hudi_test_table").show()
Kết quả mong đợi: Hiển thị 2 dòng dữ liệu đã chèn (Alice và Bob) với timestamp chính xác.
Điều hướng series:
Mục lục: Series: Triển khai Database Lakehouse với Apache Hudi và Ubuntu 24.04
« Phần 1: Chuẩn bị môi trường Ubuntu 24.04 và các công cụ nền tảng
Phần 3: Khởi tạo kho dữ liệu Hudi: Tạo bảng và nhập dữ liệu ban đầu »