Greenplum Database - Bài học 6: Triển khai cụm Greenplum nhanh với Docker Compose: Dựng môi trường Lab đa Node trong 10 phút
Qua 5 bài học đầu tiên, chúng ta đã nắm trọn vẹn kiến trúc cốt lõi của Greenplum: từ Master Node (Coordinator), Primary/Mirror Segments cho đến tầng mạng Interconnect. Tuy nhiên, lý thuyết sẽ chỉ nằm trên giấy nếu bạn không trực tiếp gõ lệnh, xem cách dữ liệu tự động băm nhỏ ra các Node và đọc từng dòng kế hoạch thực thi (EXPLAIN).
Thông thường, việc cài đặt một cụm Greenplum chuẩn từ con số 0 đòi hỏi tối thiểu 3–4 máy chủ Linux, cấu hình SSH không mật khẩu (Passwordless SSH) chéo nhau và tinh chỉnh hàng chục tham số Kernel — mất cả buổi sáng của một kỹ sư hệ thống. Trong bài học này, chúng ta sẽ sử dụng Docker & Docker Compose để dựng ngay một môi trường Lab Greenplum thực thụ trên máy cá nhân chỉ trong 10 phút, phục vụ xuyên suốt cho tất cả các bài thực hành từ Bài 7 đến Bài 50.
1. Thiết kế kiến trúc cụm Lab Greenplum trên Docker
Để sát với thực tế vận hành nhưng vẫn chạy mượt mà trên một chiếc Laptop hoặc PC cá nhân (tối thiểu 8GB RAM, khuyến nghị 16GB RAM), chúng ta sẽ thiết kế 2 phương án triển khai bằng Docker Compose:
-
Phương án 1 (All-in-One Sandbox — Khuyên dùng cho máy 8GB RAM): 1 Container đóng vai trò máy chủ, bên trong chạy đầy đủ 1 Master Instance + 2 Primary Segments (cổng
5432,6000,6001). Cực kỳ nhẹ, khởi động trong 30 giây. -
Phương án 2 (Multi-Container Cluster — Khuyên dùng cho máy 16GB+ RAM): Mô phỏng đúng mạng vật lý gồm 3 Containers riêng biệt:
mdw(Master Host),sdw1(Segment Host 1) vàsdw2(Segment Host 2) nối với nhau qua mạng nội bộ Docker Bridge.
[ Máy tính cá nhân (Host OS: DBeaver / Navicat / psql) ]
│
(Map Port 5432:5432)
▼
┌────────────────────────────────────────────────────────────────────────┐
│ DOCKER NETWORK (gpdb-interconnect) │
│ │
│ ┌───────────────────────────┐ │
│ │ Container 1: mdw │ │
│ │ Master Node (Port 5432) │ │
│ └─────────────┬─────────────┘ │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ ▼ ▼ │
│ ┌───────────────────────────┐ ┌───────────────────────────┐ │
│ │ Container 2: sdw1 │ │ Container 3: sdw2 │ │
│ │ • Primary Seg 0 (Port 6000)│ │ • Primary Seg 1 (Port 6000)│ │
│ │ • Mirror Seg 1 (Port 7000)│ │ • Mirror Seg 0 (Port 7000)│ │
│ └───────────────────────────┘ └───────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────┘
2. Chuẩn bị môi trường trước khi chạy (Prerequisites)
Vì mỗi Segment của Greenplum thực chất là một cơ sở dữ liệu PostgreSQL độc lập sử dụng bộ nhớ chia sẻ (Shared Memory), bạn cần đảm bảo Docker được cấp đủ tài nguyên:
-
Dung lượng RAM cho Docker: Tối thiểu 4GB RAM (với phương án 1) hoặc 6GB–8GB RAM (với phương án 2).
-
Dung lượng ổ cứng trống: Khoảng 10GB.
-
Tham số Shared Memory (
shm_size): Mặc định Docker giới hạn/dev/shmcủa mỗi Container chỉ có64MB. Con số này sẽ khiến Greenplum báo lỗi không thể cấp phát bộ nhớ ngay khi khởi tạo nhiều Segments. Trong filedocker-compose.ymlbên dưới, chúng ta bắt buộc phải cấu hìnhshm_size: 2gb.
3. Thực hành: Dựng cụm Greenplum với Docker Compose
Tạo một thư mục mới tên là greenplum-lab trên máy tính của bạn:
Bash
mkdir greenplum-lab && cd greenplum-lab
Cách 1: Dựng nhanh cụm Greenplum 1 Master + 2 Segments (Khởi chạy tự động)
Tạo file docker-compose.yml với nội dung sau. Cấu hình này sử dụng Image chính thức từ cộng đồng Greenplum/Cloudberry, tự động thiết lập SSH và khởi tạo cụm ngay khi bật Container:
YAML
version: '3.8'
services:
greenplum:
image: datagrip/greenplum:6.8
container_name: gpdb_lab
hostname: mdw
shm_size: '2gb'
ports:
- "5432:5432"
environment:
- GP_USER=gpadmin
- GP_PASSWORD=gpadmin
ulimits:
nproc: 131072
nofile:
soft: 65536
hard: 65536
volumes:
- gpdata:/data
restart: unless-stopped
volumes:
gpdata:
Mẹo cho người muốn dùng cụm Đa Node (Multi-Host) tự cấu hình từ đầu: Nếu bạn muốn tự tay chạy lệnh
gpinitsystemtrên 3 Containers độc lập (mdw,sdw1,sdw2), hãy xem phần Phụ lục nâng cao ở mục 5 bên dưới!
Khởi chạy cụm bằng 1 lệnh duy nhất:
Bash
docker compose up -d
Theo dõi quá trình cụm tự động khởi tạo Master và 2 Primary Segments:
Bash
docker logs -f gpdb_lab
Khi thấy dòng thông báo Greenplum Database instance successfully started, cụm MPP của bạn đã sẵn sàng hoạt động!
4. Kiểm chứng sức mạnh MPP ngay trên cụm vừa dựng
Hãy truy cập vào bên trong Container dưới quyền quản trị viên gpadmin và mở trình giao diện dòng lệnh psql:
Bash
docker exec -it -u gpadmin gpdb_lab bash
psql -d postgres
Bây giờ, chúng ta sẽ chạy 4 bài kiểm tra thực tế để tận mắt chứng kiến những lý thuyết đã học ở Bài 1 đến Bài 5:
Bài test 1: Kiểm tra phiên bản và bản đồ cụm (gp_segment_configuration)
Chạy câu lệnh truy vấn bảng hệ thống mà chúng ta đã học ở Bài 3:
SQL
SELECT dbid, content, role, preferred_role, mode, status, port, hostname, datadir
FROM gp_segment_configuration
ORDER BY content;
Kết quả hiển thị:
Plaintext
dbid | content | role | preferred_role | mode | status | port | hostname | datadir
------+---------+------+----------------+------+--------+-------+----------+----------------------------
1 | -1 | p | p | s | u | 5432 | mdw | /data/master/gpseg-1
2 | 0 | p | p | s | u | 40000 | mdw | /data/primary/gpseg0
3 | 1 | p | p | s | u | 40001 | mdw | /data/primary/gpseg1
Bạn có thể thấy rõ:
-
content = -1chính là Master Node lắng nghe ở cổng5432. -
content = 0vàcontent = 1là 2 Primary Segments chạy ở hai cổng riêng biệt (40000và40001) với hai thư mục dữ liệu độc lập hoàn toàn!
Bài test 2: Tạo bảng và xem dữ liệu tự động băm nhỏ ra các Segments
Hãy tạo một bảng users_demo gồm 100.000 dòng dữ liệu giả lập, sử dụng cột id làm khóa phân phối (DISTRIBUTED BY (id)):
SQL
-- 1. Tạo bảng phân tán theo cột id
CREATE TABLE users_demo (
id INT,
username TEXT,
created_at TIMESTAMP
) DISTRIBUTED BY (id);
-- 2. Bơm nhanh 100.000 dòng dữ liệu vào bảng
INSERT INTO users_demo
SELECT g, 'user_' || g, NOW()
FROM generate_series(1, 100000) AS g;
Làm sao để biết 100.000 dòng này đang nằm ở Segment nào? Trong Greenplum, mọi bảng đều có một cột ẩn đặc biệt tên là gp_segment_id cho biết dòng dữ liệu đó đang cư trú tại Segment số mấy:
SQL
SELECT gp_segment_id, COUNT(*) AS so_dong_du_lieu
FROM users_demo
GROUP BY gp_segment_id
ORDER BY gp_segment_id;
Kết quả đáng kinh ngạc:
Plaintext
gp_segment_id | so_dong_du_lieu
---------------+-----------------
0 | 49962
1 | 50038
(2 rows)
Nhận xét: Bạn chỉ gõ 1 lệnh INSERT vào Master, nhưng Greenplum đã âm thầm băm (Hash) 100.000 dòng và chia cực kỳ đồng đều: Segment 0 giữ ~49,96% và Segment 1 giữ ~50,04% dữ liệu! Master (content = -1) hoàn toàn không giữ dòng nào.
Bài test 3: Xem kế hoạch thực thi song song (EXPLAIN)
Hãy chạy lệnh EXPLAIN để xem bộ tối ưu hóa GPORCA điều phối các Segments và tầng Interconnect (Bài 5) như thế nào:
SQL
EXPLAIN SELECT COUNT(*) FROM users_demo;
Kết quả trả về:
Plaintext
QUERY PLAN
--------------------------------------------------------------------------------------
Finalize Aggregate (cost=0.00..431.00 rows=1 width=8)
-> Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..431.00 rows=1 width=8)
-> Partial Aggregate (cost=0.00..431.00 rows=1 width=8)
-> Seq Scan on users_demo (cost=0.00..431.00 rows=50000 width=1)
Optimizer: Pivotal Optimizer (GPORCA)
Đọc từ dưới lên trên (đúng như kịch bản ở Bài 2 và Bài 5):
-
Seq Scan on users_demo: Cả 2 Segments cùng quét song song (mỗi bên chỉ quét ~50.000 dòng). -
Partial Aggregate: Mỗi Segment tự đếm nháp số dòng của riêng mình. -
Gather Motion 2:1 (slice1; segments: 2): Toán tử dịch chuyển dữ liệu qua Interconnect gom kết quả từ 2 Segments về 1 Master (2:1). -
Finalize Aggregate: Master cộng 2 con số nháp lại (49962 + 50038 = 100000) và trả về cho bạn!
Bài test 4: Kết nối từ bên ngoài bằng DBeaver / Navicat / Code Backend
Vì chúng ta đã mở cổng 5432:5432 ra ngoài máy thật, bạn có thể mở ngay DBeaver, Navicat hoặc kết nối từ code Go/Node.js/Python bằng Driver PostgreSQL chuẩn với thông số:
-
Host:
localhost(hoặc127.0.0.1) -
Port:
5432 -
Database:
postgres -
Username / Password:
gpadmin/gpadmin
5. Phụ lục Nâng cao: File docker-compose.yml cho cụm Multi-Host (3 Containers riêng biệt)
Nếu máy tính của bạn có từ 16GB RAM trở lên và bạn muốn mô phỏng mạng vật lý gồm 3 máy chủ riêng biệt (mdw, sdw1, sdw2) để thực hành các bài quản trị cụm nâng cao (như đánh sập 1 Container xem Mirror tự cứu hộ thế nào), bạn có thể dùng cấu hình mạng tĩnh sau:
YAML
version: '3.8'
services:
mdw:
image: rockylinux:8
container_name: gpdb_mdw
hostname: mdw
shm_size: '1gb'
ports:
- "5432:5432"
networks:
gpnet:
ipv4_address: 172.28.0.10
tty: true
sdw1:
image: rockylinux:8
container_name: gpdb_sdw1
hostname: sdw1
shm_size: '2gb'
networks:
gpnet:
ipv4_address: 172.28.0.11
tty: true
sdw2:
image: rockylinux:8
container_name: gpdb_sdw2
hostname: sdw2
shm_size: '2gb'
networks:
gpnet:
ipv4_address: 172.28.0.12
tty: true
networks:
gpnet:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
(Chính trên cụm 3 Containers trắng chạy RockyLinux 8 này, ở Bài học 7 tiếp theo, chúng ta sẽ học cách cài đặt từng bước từ cấu hình OS, trao đổi SSH Key cho tới lệnh khởi tạo cụm chuẩn Production!)
Tóm tắt Bài học 6
-
Sử dụng Docker Compose giúp dựng nhanh môi trường Lab Greenplum đầy đủ Master và các Segments chỉ trong vài phút mà không cần nhiều máy chủ vật lý.
-
Khi chạy Greenplum trên Docker, bắt buộc phải cấu hình
shm_size(Shared Memory) vàulimits(nofile,nproc) đủ lớn vì mỗi Segment là một tiến trình PostgreSQL độc lập. -
Cột ẩn hệ thống
gp_segment_idcó mặt trên mọi bảng trong Greenplum, giúp kiểm tra chính xác từng bản ghi đang nằm ở Segment nào và phát hiện nhanh hiện tượng lệch dữ liệu (Data Skew). -
Lệnh
EXPLAINtrong Greenplum hiển thị rõ bộ tối ưu hóa GPORCA và các toán tử mạng nhưGather Motion N:1.
Ở bài học tiếp theo (Bài học 7), chúng ta sẽ bước vào thế giới của các kỹ sư Hệ thống / DBA thực thụ: Cài đặt Greenplum Cluster chuẩn Production trên Linux: Tinh chỉnh Kernel, OS parameters và SSH Keys.
All rights reserved