Khái niệm và Phân tách Workload HTAP trong YugabyteDB
YugabyteDB cho phép một cơ sở dữ liệu duy nhất phục vụ cả hai loại tải: OLTP (Giao dịch) và OLAP (Phân tích). OLTP sử dụng giao thức YSQL (PostgreSQL wire protocol) để thực hiện các thao tác INSERT, UPDATE, DELETE với độ trễ thấp. OLAP sử dụng giao thức YCQL (Cassandra Query Language) để thực hiện các truy vấn quét dữ liệu lớn (Scan) mà không làm ảnh hưởng đến hiệu năng OLTP.
Việc phân tách này được thực hiện bằng cách định nghĩa rõ ràng nơi dữ liệu được lưu trữ và cách nó được truy cập. Dữ liệu giao dịch được phân mảnh (sharded) thành các tablet để xử lý nhanh, trong khi dữ liệu phân tích được tổ chức theo các bảng Wide-Table (Wide Column) để tối ưu hóa việc quét hàng loạt.
Cấu hình Replication Factor và Tablet Placement cho HTAP
Định nghĩa Replication Factor
Đối với kiến trúc HTAP, chúng ta cần một Replication Factor (RF) cao hơn mức tối thiểu để đảm bảo tính sẵn sàng cho cả hai workload. Với cụm 3 node, RF=3 là bắt buộc cho tính nhất quán. Tuy nhiên, để tối ưu cho HTAP, chúng ta cần đảm bảo mỗi tablet có một replica nằm trên node OLTP và một replica nằm trên node Read-heavy (OLAP).
Chúng ta sẽ tạo một Tablespaces đặc biệt để gán các bảng HTAP vào, sau đó cấu hình Placement Policy để kiểm soát vị trí của các replica.
Tạo Tablespaces và Policy Placement
Trước tiên, hãy truy cập vào shell ysqlsh của node chính (Master node) để cấu hình metadata.
Chạy lệnh kết nối vào database ysqlsh:
ysqlsh -h -u yugabyte -d yugabyte -p 5433
Kết quả mong đợi: Bạn thấy prompt `yugabyte=#` và có thể thực thi các lệnh SQL.
Thực hiện các bước sau để tạo Tablespaces dành riêng cho HTAP với RF=3:
CREATE TABLESPACE htap_tablespace
WITH (
replication_factor = 3,
tablet_size = '64MB',
tablet_placement_policy = 'spread'
);
Kết quả mong đợi: Lệnh `CREATE TABLESPACE` hoàn thành không lỗi. Tham số `tablet_placement_policy = 'spread'` đảm bảo các replica của tablet được phân tán đều trên các node khác nhau, giúp cân bằng tải cho cả OLTP và OLAP.
Tạo bảng với Chỉ mục (Index) cho OLTP và OLAP
Thiết kế Bảng YSQL cho OLTP
Bảng YSQL được tối ưu cho các truy vấn điểm (Point Query) và cập nhật hàng đơn lẻ. Chúng ta cần chỉ mục B-Tree cho các trường Primary Key và các trường thường dùng trong điều kiện WHERE của giao dịch.
Tạo bảng giao dịch (Orders) sử dụng Tablespaces HTAP đã tạo ở trên:
CREATE TABLE orders_htap (
order_id UUID PRIMARY KEY,
customer_id UUID NOT NULL,
amount NUMERIC(10, 2) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
) TABLESPACE htap_tablespace;
Kết quả mong đợi: Bảng được tạo thành công với Primary Key là `order_id`.
Tạo chỉ mục phụ trợ cho truy vấn OLTP theo `customer_id` và `status`:
CREATE INDEX idx_orders_customer ON orders_htap (customer_id);
CREATE INDEX idx_orders_status ON orders_htap (status);
Kết quả mong đợi: Các chỉ mục được tạo, giúp các lệnh `SELECT * FROM orders_htap WHERE customer_id = '...'` chạy nhanh.
Thiết kế Bảng YCQL cho OLAP
Để hỗ trợ truy vấn phân tích (OLAP), chúng ta cần tạo một bảng tương ứng trong YCQL. Bảng YCQL sử dụng Primary Key dạng composite (Partition Key + Clustering Key) để dữ liệu được lưu trữ liên tục trên đĩa, tối ưu cho việc quét (Scan).
Chuyển sang shell ycqlsh để tạo bảng phân tích:
ycqlsh -h -u yugabyte -d yugabyte -p 9042
Kết quả mong đợi: Bạn thấy prompt `cqlsh>`.
Tạo bảng YCQL tương ứng với dữ liệu Orders. Lưu ý: Partition Key nên là trường phân loại dữ liệu lớn (ví dụ: ngày tháng hoặc customer_id nếu dữ liệu không quá lớn per key), Clustering Key là thứ tự thời gian hoặc ID.
CREATE KEYSPACE IF NOT EXISTS analytics_ks WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': 3};
USE analytics_ks;
CREATE TABLE orders_analytics (
customer_id UUID,
order_date TEXT,
order_id UUID,
amount DOUBLE,
status TEXT,
PRIMARY KEY ((customer_id, order_date), order_id)
) WITH CLUSTERING ORDER BY (order_id DESC)
AND gc_grace_seconds = 864000;
Kết quả mong đợi: Keyspace và Table được tạo thành công. Cấu trúc này cho phép truy vấn nhanh tất cả đơn hàng của một khách hàng trong một khoảng thời gian cụ thể mà không cần quét toàn bộ bảng.
Cấu hình Node chuyên biệt cho Workload Phân tích (Read-heavy)
Khái niệm Node Read-heavy
Trong kiến trúc HTAP, thay vì để tất cả các node xử lý đều đều, chúng ta có thể chỉ định một số node chuyên biệt chỉ nhận các yêu cầu đọc (Read-only) cho các truy vấn OLAP nặng. Điều này bảo vệ các node OLTP khỏi bị quá tải do các truy vấn quét lớn.
Trên Ubuntu 24.04 với YugabyteDB v2.11, chúng ta sử dụng cơ chế `Node Placement` thông qua biến môi trường hoặc cấu hình trong `yugabyte.conf` (hoặc `yb-masters`/`yb-tserver` config file) để gán nhãn (label) cho node.
Cấu hình Node OLAP Read-Heavy
Giả sử bạn có 3 node: Node 1, Node 2 (OLTP + OLAP), Node 3 (Dành riêng cho Read-heavy/OLAP). Chúng ta sẽ cấu hình Node 3.
Chỉnh sửa file cấu hình của tserver trên Node 3. Đường dẫn mặc định là `/home/yugabyte/yb-2.11.0/conf/yb-tserver.conf` (tùy phiên bản, kiểm tra lại đường dẫn thực tế).
Nội dung cần thêm vào file cấu hình:
# /home/yugabyte/yb-2.11.0/conf/yb-tserver.conf
--label=olap_read_node=true
--tablet_placement_policy=spread
--enable_read_heavy_optimizations=true
Kết quả mong đợi: File cấu hình được cập nhật. Tham số `--label` giúp phân biệt node này trong cluster, và `--enable_read_heavy_optimizations` (nếu có trong version cụ thể, hoặc dùng `--max_concurrent_reads` cao hơn) sẽ ưu tiên tài nguyên cho đọc.
Khởi động lại tserver trên Node 3 để áp dụng cấu hình:
sudo systemctl restart yb-tserver
Kết quả mong đợi: Dịch vụ yb-tserver chạy lại thành công và node tham gia lại vào cụm.
Định hướng truy vấn YCQL đến Node Read-heavy
Để đảm bảo các truy vấn YCQL (OLAP) chỉ đi đến các node được đánh dấu, chúng ta có thể sử dụng cơ chế Hint trong truy vấn hoặc cấu hình tại client. Tuy nhiên, cách tốt nhất trong YugabyteDB là sử dụng `Tablet Placement` để đảm bảo các replica của bảng phân tích có một copy nằm trên node Read-heavy.
Chúng ta sẽ gán bảng `orders_analytics` vào một Tablespaces có policy ưu tiên node có label `olap_read_node`.
Quay lại ysqlsh để tạo Tablespaces cho YCQL (dùng trong ngữ cảnh metadata chung):
CREATE TABLESPACE olap_tablespace
WITH (
replication_factor = 3,
tablet_size = '128MB',
tablet_placement_policy = 'spread',
tablet_placement_label = 'olap_read_node=true'
);
Kết quả mong đợi: Tablespaces được tạo với chính sách đặt tablet ưu tiên node có label `olap_read_node`.
Sử dụng YCQL để truy vấn dữ liệu chiều dọc và ngang
Truy vấn chiều dọc (Vertical Partitioning - Column selection)
YCQL cho phép chọn chỉ những cột cần thiết (Sparse reads), giảm lượng dữ liệu truyền tải qua mạng. Đây là lợi thế lớn so với YSQL khi làm OLAP trên bảng rộng.
Chạy lệnh ycqlsh để thực hiện truy vấn chọn cột:
USE analytics_ks;
SELECT customer_id, amount, status FROM orders_analytics WHERE customer_id = '123e4567-e89b-12d3-a456-426614174000' AND order_date = '2023-10';
Kết quả mong đợi: Trả về kết quả chỉ gồm 3 cột, tốc độ nhanh hơn so với `SELECT *` do giảm I/O.
Truy vấn chiều ngang (Horizontal Partitioning - Wide Scans)
Truy vấn chiều ngang là quét qua nhiều phân vùng (Partition Key) hoặc nhiều hàng (Clustering Key). YCQL tối ưu hóa điều này bằng cách phân tán scan trên nhiều node.
Thực hiện truy vấn tổng hợp (Aggregation) trên toàn bộ dữ liệu của một khoảng thời gian:
SELECT SUM(amount) as total_revenue, COUNT(*) as total_orders
FROM orders_analytics
WHERE order_date >= '2023-01' AND order_date
Kết quả mong đợi: YugabyteDB sẽ phân tán lệnh này đến các node có chứa dữ liệu cho các tháng 2023, tính toán cục bộ và tổng hợp lại. Thời gian thực hiện nên ngắn hơn nhiều so với việc quét toàn bộ bảng trong YSQL.
Verify kết quả cấu hình HTAP
Verify Replication và Placement
Để kiểm tra xem các tablet của bảng HTAP đã được phân tán đúng chính sách chưa, sử dụng lệnh `yb-admin`.
yb-admin --master_addresses=:7100 --command=tablet_list --table_name=orders_htap
Kết quả mong đợi: Danh sách các tablet hiển thị với trạng thái `RUNNING` và số lượng replica (3) được phân bổ trên các node khác nhau (Node 1, Node 2, Node 3).
Verify hiệu năng phân tách
Thực hiện một test đơn giản: Chạy một truy vấn OLTP nặng (INSERT/UPDATE) đồng thời với một truy vấn OLAP nặng (SELECT * từ bảng lớn) trên cùng một thời điểm.
Trên Node OLTP (Node 1), chạy load test YSQL:
ysqbench --host= --port=5433 --user=yugabyte --database=yugabyte --table=orders_htap --scale=10000 --report-interval=5s &
Trên Node Read-heavy (Node 3), chạy load test YCQL:
ycqbench --host= --port=9042 --keyspace=analytics_ks --table=orders_analytics --read-only --scale=10000 &
Kết quả mong đợi: Thời gian phản hồi (latency) của YSQL (OLTP) không tăng đột biến khi YCQL (OLAP) đang chạy, chứng tỏ việc phân tách workload và cấu hình Read-heavy node đã thành công.
Điều hướng series:
Mục lục: Series: Triển khai Database HTAP với YugabyteDB và Linux Kernel Tuning trên Ubuntu 24.04
« Phần 4: Triển khai cụm YugabyteDB v2.11 trên Ubuntu 24.04
Phần 6: Tối ưu hóa hiệu năng với YSQL và YCQL trong môi trường thực tế »