Tới nội dung
Cloudj

Ứng dụng VPS

Cài PostgreSQL trên VPS: chọn cấu hình, tinh chỉnh và sao lưu

Hướng dẫn cài PostgreSQL trên VPS cho môi trường thật: chọn CPU dedicated và RAM, tinh chỉnh bộ nhớ, chỉ mở cổng cho IP ứng dụng và tự động sao lưu ra ngoài.

Cập nhật · 4 phút đọc

Cài PostgreSQL trên VPS thường là bước hạ tầng đầu tiên khi một dự án lớn dần và muốn tách database khỏi nền tảng managed hoặc khỏi chung máy với ứng dụng. Bạn có tài nguyên ổn định, toàn quyền cấu hình và cài extension, và đặt được database ngay cạnh ứng dụng. Đổi lại, bạn tự chịu trách nhiệm tinh chỉnh, bảo mật và sao lưu. Bài này đi qua từng việc theo đúng thứ tự bạn sẽ gặp, kèm lệnh cho Ubuntu để chạy trên một máy chủ mới.

Trước khi thuê VPS: vài câu hỏi cần trả lời

Trả lời mấy câu này trước khi chọn cấu hình. Chúng quyết định nhiều hơn bất kỳ tham số tinh chỉnh nào.

  • Ứng dụng chạy ở đâu? Đặt database cùng thành phố với máy chủ ứng dụng. Mỗi truy vấn đều phải trả giá cho một vòng đi về, và một trang chạy năm mươi truy vấn sẽ nhân con số đó lên năm mươi lần. Hướng dẫn chọn vị trí đặt VPS liệt kê đủ 14 quốc gia và các thành phố của Cloudj.
  • Dữ liệu "nóng" lớn cỡ nào? Phần dữ liệu và index được truy cập thường xuyên nên nằm vừa trong RAM. Database lớn hơn RAM nhiều lần vẫn ổn nếu phần lớn là dữ liệu ít dùng.
  • Tải đều hay theo đợt? Database rất kỵ tranh chấp CPU. Với tải truy vấn đều đặn, hãy chọn máy chủ CPU dedicated, tức có nhân CPU riêng. CPU shared chấp nhận được cho môi trường dev và công cụ nội bộ ít truy cập.
  • Bạn chấp nhận mất bao nhiêu dữ liệu? Nếu câu trả lời là "vài phút", bạn cần lưu trữ WAL liên tục chứ không chỉ một bản dump mỗi đêm.

Điểm khởi đầu hợp lý cho một database production nhỏ là 2 vCPU dedicated và 4 đến 8 GB RAM, ổ đĩa đủ cho dữ liệu, index, WAL và phần tăng trưởng. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa sau trong console, nên không cần mua trước cấu hình của năm sau. Tham khảo các lựa chọn máy chủ cloud để biết các loại CPU, và xem giá hiện hành theo từng vị trí.

Cài PostgreSQL trên VPS Ubuntu

Kho gói của Ubuntu đã có sẵn một phiên bản được hỗ trợ. Nếu muốn bản major mới nhất, hãy dùng kho apt chính thức của PostgreSQL:

sudo apt update
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql

Kiểm tra phiên bản và cluster đã cài:

pg_lsclusters

Kết quả hiển thị số phiên bản và thư mục dữ liệu. Các đường dẫn bên dưới dùng phiên bản 16; hãy thay bằng phiên bản của bạn. Tạo role và database cho ứng dụng:

sudo -u postgres createuser --pwprompt appuser
sudo -u postgres createdb --owner=appuser appdb

Tinh chỉnh bộ nhớ theo cấu hình máy

Giá trị mặc định cố tình để rất dè dặt. Sửa file /etc/postgresql/16/main/postgresql.conf (hoặc thêm file vào thư mục conf.d/). Các giá trị dưới đây giả định máy 8 GB RAM chỉ chạy PostgreSQL:

shared_buffers = 2GB              # khoảng 25% RAM
effective_cache_size = 6GB        # khoảng 75% RAM; chỉ là gợi ý cho planner, không cấp phát thật
work_mem = 16MB                   # cho mỗi thao tác sort/hash trong mỗi truy vấn; để vừa phải
maintenance_work_mem = 512MB      # dùng cho VACUUM và tạo index
random_page_cost = 1.1            # ổ SSD
max_connections = 100

work_mem là tham số hay gây rắc rối nhất: một truy vấn phức tạp có thể dùng nó nhiều lần, và mỗi kết nối đều có thể chạy truy vấn như vậy. Nếu cần hàng trăm kết nối từ client, hãy đặt PgBouncer phía trước thay vì tăng max_connections. Khởi động lại và kiểm tra:

sudo systemctl restart postgresql
sudo -u postgres psql -c "SHOW shared_buffers;"

Bật ghi log truy vấn chậm để tinh chỉnh dựa trên số liệu thật:

log_min_duration_statement = 500ms

Chỉ cho máy chủ ứng dụng kết nối

Đừng bao giờ để cổng 5432 mở ra Internet. Hãy kết hợp ba lớp bảo vệ.

Thứ nhất, chỉ định giao diện mạng mà PostgreSQL lắng nghe. Trong postgresql.conf:

listen_addresses = 'localhost,198.51.100.5'   # IP của chính máy chủ này

Thứ hai, chỉ cho phép đúng các client đã biết trong /etc/postgresql/16/main/pg_hba.conf, dùng mật khẩu SCRAM và TLS:

hostssl  appdb  appuser  203.0.113.10/32  scram-sha-256
hostssl  appdb  appuser  203.0.113.11/32  scram-sha-256

Gói của Ubuntu tự tạo chứng chỉ tự ký và bật ssl = on sẵn; tài liệu PostgreSQL về SSL hướng dẫn cách thay bằng chứng chỉ của bạn.

Thứ ba, lọc ở firewall để chỉ máy chủ ứng dụng chạm được tới cổng:

sudo ufw allow OpenSSH
sudo ufw allow from 203.0.113.10 to any port 5432 proto tcp
sudo ufw allow from 203.0.113.11 to any port 5432 proto tcp
sudo ufw enable
sudo systemctl reload postgresql

Bài cấu hình firewall UFW giải thích thứ tự rule và cách tránh tự khóa mình ở ngoài.

Sao lưu: hai lớp, cả hai đều nằm ngoài máy chủ

Bản sao lưu nằm cùng ổ đĩa với database chỉ là một bản copy, chưa phải bản sao lưu. Hãy chuẩn bị hai lớp.

Dump logic bằng pg_dump

Đơn giản, chuyển được giữa các phiên bản, hợp với database nhỏ hoặc làm thêm một lớp an toàn trước khi migrate:

sudo -u postgres pg_dump -Fc appdb > /var/backups/appdb-$(date +%F).dump

Khôi phục vào một database trống bằng pg_restore -d appdb file.dump. Đặt lịch bằng cron và chép file ra ngoài máy chủ.

Lưu trữ liên tục bằng pgBackRest

Để khôi phục về một thời điểm bất kỳ, pgBackRest tạo bản sao lưu full và incremental, đồng thời đẩy WAL liên tục lên một bucket tương thích S3. Cài bằng sudo apt install -y pgbackrest rồi tạo file /etc/pgbackrest.conf:

[global]
repo1-type=s3
repo1-s3-endpoint=s3.example-storage.com
repo1-s3-bucket=db-backups
repo1-s3-region=eu-central
repo1-s3-key=ACCESS_KEY
repo1-s3-key-secret=SECRET_KEY
repo1-path=/pgbackrest
repo1-retention-full=2

[main]
pg1-path=/var/lib/postgresql/16/main

Bật lưu trữ WAL trong postgresql.conf, khởi động lại rồi tạo bản full đầu tiên:

archive_mode = on
archive_command = 'pgbackrest --stanza=main archive-push %p'
sudo systemctl restart postgresql
sudo -u postgres pgbackrest --stanza=main stanza-create
sudo -u postgres pgbackrest --stanza=main --type=full backup
sudo -u postgres pgbackrest --stanza=main info

Hãy chọn bucket ở vị trí khác với database. Cloudj có trang object storage để bạn tham khảo; cấu hình trên dùng được với mọi dịch vụ tương thích S3.

Thử khôi phục thật

Mỗi tháng một lần, tạo một máy chủ thuê theo giờ, khôi phục bản sao lưu mới nhất, chạy vài truy vấn kiểm tra rồi xóa máy. Máy chủ theo giờ bị tính tiền chừng nào còn tồn tại, nên xóa ngay sau khi thử sẽ giữ chi phí chỉ ở số giờ bạn đã dùng.

Áp dụng vào bài toán thực tế

Hệ thống giao dịch là ví dụ điển hình: một bot ghi lại lệnh khớp và vị thế cần database nằm sát bot, không phải ở bên kia đại dương. Các bài về bot giao dịch crypto ở Singapore, VPS forex ở London và VPS forex ở New York cho thấy vị trí máy chủ đi theo khối lượng công việc thế nào, và database cũng theo đúng logic đó.

Câu hỏi thường gặp

Nên dùng CPU shared hay dedicated cho PostgreSQL?

Dedicated cho production có tải đều, vì độ trễ truy vấn tăng khi phải tranh chấp CPU. Shared ổn cho dev, staging và công cụ nội bộ nhỏ.

Database managed có tốt hơn PostgreSQL tự cài trên VPS không?

Dịch vụ managed lo phần vá lỗi, failover và sao lưu cho bạn. VPS cho bạn toàn quyền với phiên bản, extension và cấu hình, đổi lại bạn tự làm những việc đó. Nếu trong đội không ai nhận trách nhiệm sao lưu và nâng cấp, dịch vụ managed là lựa chọn an toàn hơn.

Nên chạy pg_dump bao lâu một lần?

Mỗi ngày một lần là mức cơ bản phổ biến cho database nhỏ. Nếu không chấp nhận mất dữ liệu cả ngày, hãy thêm lưu trữ WAL liên tục bằng pgBackRest.

Sau này nâng cấu hình máy được không?

Được. Bạn có thể tăng CPU, RAM và mở rộng ổ đĩa trong console. Hãy lên lịch một khoảng bảo trì ngắn cho lần khởi động lại.

Khởi chạy máy chủ database của bạn

Đặt database cạnh ứng dụng, bắt đầu với CPU dedicated và đủ RAM cho dữ liệu nóng, rồi chứng minh bản sao lưu dùng được bằng một lần khôi phục thật. Console Cloudj hiển thị giá chính xác cho từng cấu hình trước khi bạn triển khai, và bạn có thể nạp tiền vào số dư bằng chuyển khoản ngân hàng bằng VND.

Triển khai máy chủ hoặc mua proxy

Chọn vị trí trong console, xem giá trực tiếp và thanh toán từ số dư tài khoản.