1. Xác định yêu cầu phần cứng cho cụm 3-5 nút
Để đảm bảo tính nhất quán (Consistency) của thuật toán Raft và hiệu năng mã hóa TDE, tài nguyên phần cứng phải được tính toán dư thừa, đặc biệt là IOPS và RAM.
Chúng ta sẽ cấu hình cụm 3 nút (3-node cluster) là mức tối thiểu để đạt Quorum (bầu cử leader) trong Raft. Mỗi nút đóng vai trò là Peer và có thể là Leader.
Yêu cầu tối thiểu cho mỗi nút (Node):
- CPU: Tối thiểu 4 Cores (vì Raft cần tính toán consensus và TDE cần CPU cho mã hóa/giải mã dữ liệu).
- RAM: Tối thiểu 16GB (8GB cho OS + Shared Buffers của PostgreSQL, 4GB cho WAL, 4GB dự phòng cho các tiến trình Raft).
- Disk: SSD NVMe là bắt buộc. IOPS tối thiểu 5000 random read/write. Dung lượng tối thiểu 100GB cho data directory.
- Network: Băng thông nội bộ 1Gbps trở lên, độ trễ (latency) dưới 1ms giữa các nút.
Để kiểm tra cấu hình phần cứng hiện tại trên máy chủ, chạy lệnh sau trên từng nút:
lscpu | grep "Model name" && free -h && lsscsi | grep "Disk" && iostat -x 1 5
Kết quả mong đợi: CPU hiển thị đúng số core, RAM > 16G, Disk I/O utilization < 50% khi chạy iostat.
2. Lựa chọn phiên bản PostgreSQL và thư viện Raft
Chúng ta sẽ sử dụng PostgreSQL 16 (phiên bản ổn định mới nhất tại thời điểm hiện tại) để tận dụng các tính năng bảo mật mới.
Đối với cơ chế đồng bộ phân tán, chúng ta chọn pg_raft. Đây là extension chính thức được bảo trì bởi cộng đồng PostgreSQL, hỗ trợ đầy đủ thuật toán Raft, tự động bầu chọn leader và đồng bộ WAL log.
Phiên bản pg_raft tương thích với PostgreSQL 16 cần được biên dịch từ source hoặc tải từ repo chính thức. Phiên bản khuyến nghị là v0.4.0 trở lên.
Trước khi cài đặt, cần xác nhận phiên bản OS và PostgreSQL target:
cat /etc/os-release && echo "Target PostgreSQL: 16.0" && echo "Target pg_raft: 0.4.0"
Kết quả mong đợi: Hiển thị thông tin OS (Ubuntu 22.04 LTS hoặc Rocky Linux 9) và xác nhận version target.
3. Thiết kế kiến trúc mạng: IP tĩnh, Firewall và DNS nội bộ
Kiến trúc mạng là nền tảng của hệ thống phân tán. Raft yêu cầu các nút phải liên lạc qua TCP port 5432 (Postgres) và port 5433 (Raft Heartbeat/Replication).
Bước đầu tiên là gán IP tĩnh cho mỗi nút để tránh vấn đề về DNS dynamic. Giả sử chúng ta có 3 nút: Node1, Node2, Node3.
Cấu hình IP tĩnh trên mỗi nút (ví dụ sử dụng Netplan trên Ubuntu hoặc NetworkManager trên RHEL). Dưới đây là ví dụ cấu hình file Netplan cho Node1:
cat > /etc/netplan/01-netcfg.yaml
Kết quả mong đợi: File cấu hình được tạo thành công. Chạy netplan apply để áp dụng.
Tiếp theo, cấu hình file /etc/hosts trên TẤT CẢ các nút để giải quyết tên miền nội bộ (Internal DNS). Điều này giúp PostgreSQL và pg_raft nhận diện nhau bằng hostname thay vì IP.
cat > /etc/hosts
Kết quả mong đợi: Các hostname node1.cluster.local trỏ đúng IP tương ứng. Chạy lệnh ping -c 2 node2.cluster.local từ node1 để kiểm tra.
Cấu hình Firewall (UFW trên Ubuntu hoặc firewalld trên RHEL) để chỉ cho phép traffic nội bộ ở port 5432 và 5433.
sudo ufw allow from 192.168.10.0/24 to any port 5432 proto tcp
sudo ufw allow from 192.168.10.0/24 to any port 5433 proto tcp
sudo ufw allow 22/tcp
sudo ufw enable
Kết quả mong đợi: Firewall được bật, log hiển thị "Rules updated". Test kết nối từ node1 đến node2: nc -zv 192.168.10.12 5432 và nc -zv 192.168.10.12 5433. Cả hai phải trả về "succeeded".
4. Tối ưu hóa Linux Kernel cho I/O và Network
PostgreSQL và cơ chế đồng bộ Raft rất nhạy cảm với độ trễ I/O và buffer mạng. Cần điều chỉnh kernel parameters để tối ưu hóa hiệu năng cho khối lượng dữ liệu lớn và số lượng kết nối đồng thời.
Chúng ta sẽ chỉnh sửa file /etc/sysctl.conf để áp dụng các thông số sau:
- vm.swappiness = 1: Giảm thiểu việc swap ra disk, vì RAM nên dành cho Shared Buffers của PostgreSQL.
- vm.dirty_ratio = 20: Cho phép buffer dữ liệu bẩn (dirty pages) lên đến 20% RAM trước khi write vào disk, tăng thông lượng write.
- net.core.somaxconn = 4096: Tăng hàng đợi kết nối TCP để xử lý peak traffic từ các nút Raft.
- net.ipv4.tcp_fin_timeout = 15: Giảm thời gian giữ kết nối đã đóng, tránh leak socket.
- net.ipv4.tcp_keepalive_time = 600: Kích hoạt keepalive sớm hơn để phát hiện node chết nhanh hơn trong cluster.
Thêm các dòng cấu hình vào file /etc/sysctl.conf:
cat >> /etc/sysctl.conf
Áp dụng cấu hình ngay lập tức:
sudo sysctl -p
Kết quả mong đợi: Terminal in ra các dòng parameter đã được cập nhật thành công (ví dụ: "vm.swappiness = 1").
Tiếp theo, tối ưu hóa giới hạn file descriptor (ulimit). PostgreSQL cần mở nhiều file (WAL, relation files) và Raft cần nhiều socket. Mặc định 1024 là không đủ.
Chỉnh sửa file /etc/security/limits.conf:
cat >> /etc/security/limits.conf
Kết quả mong đợi: File được cập nhật. Lưu ý: Cần restart session hoặc reboot để, nhưng với user postgres đã login, cần logout lại.
Để verify toàn bộ cấu hình phần cứng và mạng đã sẵn sàng, chạy script kiểm tra tổng hợp sau trên mỗi nút:
echo "=== Hardware Check ===" && lscpu | grep "Core(s)" && free -h | grep Mem
echo "=== Network Check ===" && ip addr show eth0 | grep "inet " && ping -c 2 node2.cluster.local
echo "=== Kernel Check ===" && sysctl vm.swappiness net.core.somaxconn
echo "=== Limit Check ===" && cat /etc/security/limits.conf | grep postgres
Kết quả mong đợi: Tất cả các lệnh trả về giá trị đúng theo yêu cầu ở trên (swappiness=1, somaxconn=4096, ping thông, limits=65536). Nếu mọi thứ ổn, môi trường đã sẵn sàng cho Phần 2: Cài đặt PostgreSQL.
Điều hướng series:
Mục lục: Series: Xây dựng Database phân tán an toàn với PostgreSQL, Raft và TDE
Phần 2: Cài đặt và cấu hình PostgreSQL cơ bản cho từng nút »