0

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:

  1. 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).

  2. Dung lượng ổ cứng trống: Khoảng 10GB.

  3. Tham số Shared Memory (shm_size): Mặc định Docker giới hạn /dev/shm củ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 file docker-compose.yml bên dưới, chúng ta bắt buộc phải cấu hình shm_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 gpinitsystem trê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 = -1 chính là Master Node lắng nghe ở cổng 5432.

  • content = 0 và content = 1 là 2 Primary Segments chạy ở hai cổng riêng biệt (40000 và 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):

  1. 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).

  2. Partial Aggregate: Mỗi Segment tự đếm nháp số dòng của riêng mình.

  3. 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).

  4. 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ặc 127.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_id có 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 EXPLAIN trong 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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí