Hướng dẫn Chi tiết Chuyển đổi Cơ chế Lưu trữ Transaction trong Seata 1.6.1
Trong các hệ thống phân tán hiện đại, việc quản lý giao dịch là một thách thức không nhỏ. Khi hệ thống gặp sự cố, khả năng khôi phục trạng thái giao dịch một cách chính xác quyết định đến tính toàn vẹn dữ liệu. Bài viết này sẽ hướng dẫn bạn cách cấu hình Seata 1.6.1 để sử dụng database thay vì file cho việc lưu trữ nhật ký giao dịch.
1. Tại sao Nên Chuyển từ File sang Database?
Seata cung cấp hai phương thức lưu trữ chính: file và database. Mặc định, hệ thống sử dụng file storage, nhưng cách này có nhiều hạn chế nghiêm trọng trong môi trường production.
Những vấn đề của file storage:
- Dữ liệu được lưu trữ cục bộ trên một máy chủ duy nhất
- Khi server gặp sự cố, toàn bộ transaction log biến mất
- Không thể mở rộng theo chiều ngang
- Khó khăn trong việc theo dõi và giám sát trạng thái giao dịch
Lợi ích khi sử dụng database:
- Dữ liệu được đảm bảo an toàn nhờ cơ chế durability của database
- Hỗ trợ clustering và high availability
- Có thể truy vấn trực tiếp trạng thái giao dịch qua SQL
- Dễ dàng tích hợp với hệ thống monitoring hiện có
Minh họa thực tế: Một hệ thống thương mại điện tử lớn từng gặp tình trạng mất dữ liệu giao dịch do sử dụng file storage. Sau khi chuyển sang database, tỷ lệ khôi phục giao dịch thành công tăng từ 75% lên 99.95%
2. Chuẩn bị Database và Cấu hình
2.1 Tạo Bảng Dữ liệu
Trước khi cấu hình Seata, bạn cần tạo các bảng cần thiết trong database. Dưới đây là script cho MySQL:
-- Bảng lưu trữ thông tin global transaction
CREATE TABLE IF NOT EXISTS `undo_log` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`xid` VARCHAR(100) NOT NULL,
`branch_id` BIGINT NOT NULL,
`context` VARCHAR(128) NOT NULL,
`rollback_info` LONGTEXT NOT NULL,
`log_status` INT NOT NULL,
`log_created` DATETIME NOT NULL,
`log_modified` DATETIME NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
);
-- Bảng global transaction
CREATE TABLE IF NOT EXISTS `txn_global_table` (
`xid` VARCHAR(128) NOT NULL,
`transaction_id` BIGINT,
`status` TINYINT NOT NULL,
`application_id` VARCHAR(32),
`transaction_service_group` VARCHAR(32),
`transaction_name` VARCHAR(128),
`timeout` INT,
`begin_time` BIGINT,
`application_data` VARCHAR(2000),
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`xid`),
KEY `idx_gmt_modified_status` (`gmt_modified`, `status`)
);
-- Bảng branch transaction
CREATE TABLE IF NOT EXISTS `txn_branch_table` (
`branch_id` BIGINT NOT NULL,
`xid` VARCHAR(128) NOT NULL,
`transaction_id` BIGINT,
`resource_group_id` VARCHAR(32),
`resource_id` VARCHAR(256),
`branch_type` VARCHAR(8),
`status` TINYINT,
`client_id` VARCHAR(64),
`application_data` VARCHAR(2000),
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
);
-- Bảng lock
CREATE TABLE IF NOT EXISTS `txn_lock_table` (
`row_key` VARCHAR(128) NOT NULL,
`xid` VARCHAR(96),
`transaction_id` BIGINT,
`branch_id` BIGINT,
`resource_id` VARCHAR(256),
`table_name` VARCHAR(32),
`pk` VARCHAR(36),
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`row_key`)
);
2.2 Cấu hình Connection Pool
Seata hỗ trợ nhiều loại connection pool. Dưới đây là cấu hình sử dụng HikariCP với các tham số được tối ưu:
| Tham số | Giá trị đề xuất | Mô tả |
|---|---|---|
| minimum-idle | 10 | Số connection tối thiểu luôn duy trì |
| maximum-pool-size | 50 | Số connection tối đa trong pool |
| connection-timeout | 30000 | Thời gian chờ tối đa để lấy connection (ms) |
| idle-timeout | 600000 | Thời gian idle tối đa trước khi đóng connection (ms) |
| max-lifetime | 1800000 | Thời gian sống tối đa của một connection (ms) |
# Cấu hình trong file registry.conf
store {
mode = "db"
db {
datasource = "hikari"
db-type = "mysql"
driver-class-name = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/seata_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Ho_Chi_Minh"
user = "seata_admin"
password = "mat_khau_bi_mat_123"
min-conn = 10
max-conn = 50
global.table = "txn_global_table"
branch.table = "txn_branch_table"
lock-table = "txn_lock_table"
query-limit = 500
}
}
3. Tối ưu hóa Hiệu suất
3.1 Cấu hình Database
Để đạt hiệu suất tối ưu, cần điều chỉnh một số tham số của MySQL:
-- Tăng kích thước buffer pool
SET GLOBAL innodb_buffer_pool_size = 4294967296; -- 4GB
-- Cấu hình redo log
SET GLOBAL innodb_log_file_size = 1073741824; -- 1GB
SET GLOBAL innodb_flush_log_at_trx_commit = 1;
-- Tăng max connections
SET GLOBAL max_connections = 500;
-- Cấu hình isolation level phù hợp với Seata
SET GLOBAL transaction_isolation = 'READ-COMMITTED';
3.2 Cấu hình Seata Server
Trong phần cấu hình server, các tham số sau ảnh hưởng lớn đến hiệu suất:
- Cấu hình thread pool:
server {
reactor {
boss-thread-count = 2
worker-thread-count = 32
}
}
- Timeout cho transaction:
server {
max-commit-retry-timeout = -1
max-rollback-retry-time = -1
timeout-retry-period = 10000
}
- Cấu hình session:
server {
session {
branch-session-attrs = "trans_session_attrs"
max-branch-session-size = 16384
}
}
4. Quy trình Chuyển đổi và Kiểm tra
4.1 Các bước chuyển đổi từ File sang Database
- Giai đoạn chuẩn bị:
- Sao lưu file cấu hình hiện tại
- Tạo các bảng database theo mẫu trên
- Cấp quyền truy cập cho user database
- Thực hiện chuyển đổi:
# Dừng Seata server
./bin/seata-server.sh -p 8091
# Cập nhật cấu hình
# Sửa file.conf: thay đổi mode từ "file" sang "db"
# Cập nhật thông tin kết nối database
# Khởi động lại Seata
./bin/seata-server.sh -p 8091 -h 127.0.0.1
- Xác minh hoạt động:
- Chạy các test case giao dịch phân tán
- Kiểm tra dữ liệu trong các bảng database
- Thực hiện test failover
4.2 Theo dõi và Bảo trì
Các metrics quan trọng cần theo dõi:
- Tỷ lệ sử dụng database connection pool
- Số lượng giao dịch được commit/rollback thành công
- Thời gian xử lý trung bình của mỗi giao dịch
- Thời gian chờ lock
Lịch bảo trì định kỳ:
- Xóa các record của giao dịch đã hoàn thành (thường sau 7 ngày)
- Theo dõi dung lượng tablespace
- Thực hiện backup database hàng ngày
Trong một hệ thống xử lý đơn hàng thực tế, sau khi chuyển sang sử dụng database storage, thời gian khôi phục giao dịch sau sự cố giảm từ 20 phút xuống còn khoảng 45 giây, giúp cải thiện đáng kể SLA của hệ thống.