Xây dựng Data Lake Iceberg với Apache Amoro, Trino và MinIO
Bài viết này sẽ hướng dẫn các bước cốt lõi và cấu hình quan trọng để thiết lập một kiến trúc data lake sử dụng Apache Iceberg, kết hợp Apache Amoro, Trino và MinIO.
Vai trò của các thành phần kiến trúc
- MinIO: Cung cấp dịch vụ lưu trữ đối tượng đám mây tuân thủ API S3, đóng vai trò là lớp lưu trữ nền tảng cho các bảng Iceberg.
- Apache Iceberg: Lớp định dạng bảng, chịu trách nhiệm quản lý tệp dữ liệu, hỗ trợ giao dịch ACID và kiểm soát phiên bản siêu dữ liệu.
- Apache Amoro: Hệ thống quản lý hồ chứa dữ liệu, cung cấp khả năng quản lý bảng, tối ưu hóa tự động (như hợp nhất các tệp nhỏ) và điều phối đa công cụ (Trino/Flink/Spark).
- Trino: Công cụ truy vấn SQL phân tán, được sử dụng để phân tích dữ liệu hiệu năng cao.
Lưu ý: Bài viết này không bao gồm quy trình ghi dữ liệu ETL vào Apache Iceberg, quy trình này thường yêu cầu Apache Flink và DolphinScheduler (hệ thống điều phối). Bạn cần tự tìm hiểu thêm về phần này.
Quy trình triển khai
Chúng ta sẽ sử dụng Docker Compose để thiết lập môi trường tích hợp Apache Amoro, MinIO và Trino, phù hợp cho môi trường phát triển hàng ngày.
Đảm bảo bạn đã cài đặt Docker phiên bản 27.0.3 và Docker Compose.
Lưu tệp cấu hình YAML sau vào một tệp có tên docker-compose.yml:
version: "3"
services:
minio:
image: minio/minio
container_name: minio
environment:
- MINIO_ROOT_USER=admin
- MINIO_ROOT_PASSWORD=password
- MINIO_DOMAIN=minio
networks:
amoro_network:
aliases:
- warehouse.minio
ports:
- 9001:9001
- 9000:9000
command: [ "server", "/data", "--console-address", ":9001" ]
amoro:
image: apache/amoro
container_name: amoro
ports:
- 8081:8081
- 1630:1630
- 1260:1260
environment:
- JVM_XMS=1024
networks:
amoro_network:
volumes:
- ./amoro:/tmp/warehouse
command: ["/entrypoint.sh", "ams"]
tty: true
stdin_open: true
trino:
image: trinodb/trino:419
container_name: trino
environment:
- AWS_ACCESS_KEY_ID=admin
- AWS_SECRET_ACCESS_KEY=password
- AWS_REGION=us-east-1
volumes:
- ./example.properties:/etc/trino/catalog/example.properties
networks:
amoro_network:
aliases:
- warehouse.trino
ports:
- 8080:8080
networks:
amoro_network:
driver: bridge
Tiếp theo, tại thư mục chứa tệp docker-compose.yml, tạo một tệp tên là example.properties với nội dung sau:
connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=http://<YOUR_IP_ADDRESS>:1630/api/iceberg/rest
iceberg.rest-catalog.warehouse=<AMORO_CREATED_ICEBERG_CATALOG_NAME>
fs.native-s3.enabled=true
s3.endpoint=http://<YOUR_IP_ADDRESS>:9000
s3.region=us-east-1
s3.aws-access-key=admin
s3.aws-secret-key=password
Thay thế <YOUR_IP_ADDRESS> bằng địa chỉ IP của máy bạn và <AMORO_CREATED_ICEBERG_CATALOG_NAME> bằng tên catalog mà bạn sẽ tạo trong Amoro.
Bước cuối cùng là khởi động các container Docker bằng lệnh sau:
docker-compose up -d
Sau khi khởi động, container Trino có thể gặp lỗi ban đầu. Đừng lo lắng, chúng ta sẽ cấu hình Amoro trước rồi khởi động lại container.
Cấu hình
Tạo Bucket trong MinIO
Truy cập giao diện MinIO tại http://localhost:9000 (hoặc cổng bạn đã cấu hình), đăng nhập bằng admin/password.
Tạo một bucket mới để lưu trữ dữ liệu Iceberg.
Cấu hình Amoro
Tạo Nhóm Optimizer (Optimizer Group)
Truy cập giao diện Amoro tại http://localhost:1630, đăng nhập bằng admin/admin.
Trên thanh điều hướng bên trái, chọn Optimizing, sau đó chọn Optimizer Groups. Nhấn nút Add Group để tạo một nhóm optimizer mới trước khi tạo catalog.
Tạo Catalog
Trên thanh điều hướng bên trái, chọn Catalogs. Nhấn nút + dưới danh sách Catalog để tạo một catalog thử nghiệm. Đặt tên cho nó là demo_catalog.
Để sử dụng định dạng Iceberg, chọn Type là Internal Catalog và chọn Table Format là Iceberg.
Cập nhật tệp example.properties với cấu hình catalog bạn vừa tạo, đảm bảo iceberg.rest-catalog.warehouse khớp với tên catalog trong Amoro.
Thực hiện các lệnh sau để khởi động lại container Trino:
docker stop trino
docker rm trino
docker-compose up trino
Các bước Demo
Khởi tạo Bảng
Trong giao diện Amoro, chọn mục Terminal trên thanh điều hướng bên trái. Bạn có thể tạo các bảng thử nghiệm tại đây bằng SQL. Hiện tại, Terminal hỗ trợ thực thi các câu lệnh Spark SQL.
CREATE DATABASE IF NOT EXISTS db;
CREATE TABLE IF NOT EXISTS db.tb_users (
id INT,
name string,
ts TIMESTAMP
) USING iceberg
PARTITIONED BY (days(ts));
INSERT OVERWRITE db.tb_users VALUES
(1, "eric", timestamp("2022-07-01 12:32:00")),
(2, "frank", timestamp("2022-07-02 09:11:00")),
(3, "lee", timestamp("2022-07-02 10:11:00"));
SELECT * FROM db.tb_users;
Nhấn nút RUN phía trên trình soạn thảo SQL và chờ cho câu lệnh thực thi xong. Sau đó, bạn có thể xem kết quả truy vấn bên dưới trình soạn thảo.
Truy vấn với Trino
Mở một terminal mới và kết nối đến container Trino:
docker exec -it trino trino
Thực thi các lệnh sau trong giao diện Trino:
trino> show catalogs;
Catalog
---------
example
jmx
memory
system
tpcds
tpch
(6 rows)
trino> show schemas in example;
Schema
--------------------
db
information_schema
(2 rows)
trino> show tables in example.db;
Table
----------------
tb_users
(1 row)
trino> select * from example.db.tb_users;
id | name | ts
----+-------+--------------------------------
1 | eric | 2022-07-01 12:32:00.000000 UTC
2 | frank | 2022-07-02 09:11:00.000000 UTC
3 | lee | 2022-07-02 10:11:00.000000 UTC
(3 rows)
Đến đây, kiến trúc của bạn đã được thiết lập thành công.
Lưu ý quan trọng
- Khi khởi động lần đầu, cần cấu hình kết nối lưu trữ MinIO trong Amoro.
- Trước khi truy vấn bằng Trino, cần tạo bảng và đồng bộ siêu dữ liệu trong Amoro.
- Đối với môi trường sản xuất, nên cấu hình Persistent Volumes và phân tách mạng.
Truy cập Trino bằng DBeaver
Bạn có thể sử dụng các công cụ như DBeaver để kết nối tới Trino và thực hiện các truy vấn SQL.
Thông tin kết nối:
- Host:
localhost - Port:
8080 - User: (Để trống hoặc theo cấu hình của bạn)
- Password: (Để trống hoặc theo cấu hình của bạn)
Driver: Chọn driver Trino.