PostgreSQL, NUMA và điện toán đám mây: những lưu ý khi chạy trong VM và container
Đây là phần 4, phần cuối trong loạt bài về chạy PostgreSQL trên các hệ thống lớn nhiều bộ xử lý theo kiến trúc NUMA. Bài giả định người đọc đã nắm kiến thức cơ bản về NUMA và cách nó ảnh hưởng tới PostgreSQL theo từng phiên bản. Trọng tâm lần này là Docker, Kubernetes và các công nghệ container hóa — những môi trường đặt ra thách thức riêng, đặc biệt trên các nhà cung cấp đám mây công cộng.
Nhắc lại nhanh về NUMA
Trong kiến trúc NUMA, các lõi CPU được chia thành các "NUMA node", thường gắn với từng bộ điều khiển bộ nhớ. Mỗi bộ điều khiển quản lý một phần bộ nhớ hệ thống. Khi lõi truy cập bộ nhớ trong node cục bộ, yêu cầu đi qua bộ điều khiển cục bộ; khi truy cập ra ngoài node, bộ điều khiển phải chuyển tiếp yêu cầu sang node thứ cấp.
Trên Linux, cấp phát bộ nhớ nội bộ mặc định có kích thước 4k và được kernel quản lý riêng lẻ; huge page mặc định là 2MB. Vì shared buffer của PostgreSQL dùng trang 8kb (trừ khi biên dịch với tùy chọn khác), một trang shared buffer bị tách qua hai trang hệ điều hành. Nếu các cấp phát bị xen kẽ, mỗi trang shared buffer sẽ nằm trên hai NUMA node khác nhau. Bộ lập lịch Linux có thể di chuyển tiến trình hoặc luồng tới gần vùng nhớ hay dùng, hoặc di chuyển vùng nhớ tới node của tiến trình. PostgreSQL 18 có nhiều tối ưu cho NUMA nhưng phải đi kèm huge page mới đạt hiệu năng tối ưu.
Máy ảo và hypervisor
Hypervisor như KVM cung cấp cho kernel khách một góc nhìn phần cứng logic, được ánh xạ động xuống phần cứng thật. Hypervisor có thể tạo cấu hình NUMA tùy ý cho máy ảo, nên topology NUMA bên trong máy ảo không nhất thiết khớp với phần cứng bên dưới.
Phần lớn nhà cung cấp đám mây để lộ kiến trúc NUMA trên các máy ảo lớn, giúp ứng dụng tối ưu theo NUMA. Máy ảo nhỏ có thể chỉ thấy một NUMA node, nhưng bộ lập lịch bên dưới vẫn có thể di chuyển cả vùng nhớ lẫn tiến trình, khiến truy cập cục bộ không được đảm bảo. Trong môi trường đám mây, hai hình thức ảo hóa thường chạy chồng lên nhau: máy ảo Linux chạy container bên trong.
Container và bảo mật
Container Linux chia sẻ kernel đang chạy, tạo ra thách thức bảo mật quan trọng: người dùng root theo truyền thống có thể thay đổi kernel lúc chạy, và nếu container làm được điều đó thì có thể thoát khỏi cách ly, ảnh hưởng container khác hoặc cài rootkit lên máy chủ. Vì vậy hệ thống điều phối container thường không cho phép quyền root đầy đủ bên trong container.
Từ kernel Linux 2.2, root không còn là trường hợp đặc biệt; thay vào đó là hệ thống "capabilities" theo chuẩn POSIX để quản lý quyền hệ thống đặc biệt. Root mặc định được cấp toàn bộ capability, nhưng có thể gỡ bớt hoặc cấp thêm cho người dùng khác. Cơ chế này giải quyết vấn đề thoát container qua tài khoản root. Capability quan trọng để thiết lập chính sách NUMA là CAP_SYS_NICE, cho phép đặt CPU affinity, chính sách cấp phát NUMA và các chức năng quản lý bộ nhớ liên quan. Trên Illumos hay SmartOS, khái niệm tương ứng được gọi là "privileges".
Khuyến nghị thực hành
Ở cấp máy ảo:
- Luôn dùng huge page khi chạy trên đám mây hoặc trong VM, vì hypervisor khó đảm bảo tính cục bộ bộ nhớ; dùng huge_pages trong PostgreSQL thường mang lại cải thiện hiệu năng đáng kể.
- Kiểm tra xem NUMA có được để lộ trên VM không. Máy ảo lớn thường hiển thị nhiều NUMA node; khi đó hãy đối xử với VM như một hệ thống NUMA bình thường, vì chúng thường được ghim vào node cụ thể và ánh xạ trực tiếp xuống phần cứng.
Ở cấp container:
- Cân nhắc ghim vào NUMA node nếu chạy nhiều cơ sở dữ liệu trong VM qua Kubernetes hay Docker và VM có để lộ NUMA node; điều này đảm bảo hiệu năng tốt nhất khi bộ nhớ và tiến trình vừa một node.
- Cân nhắc bật CAP_SYS_NICE để quản lý chính sách lập lịch, độ ưu tiên, CPU affinity và vị trí trang bộ nhớ. Về lý thuyết khá an toàn nhờ namespace ngăn container thấy tiến trình bên ngoài, nhưng đây vẫn là một điểm tấn công tiềm tàng nếu có lỗ hổng khác. Trên Docker, bật bằng cờ --cap-add khi chạy lệnh docker run hoặc thêm vào danh sách cap_add trong file docker compose; trên Kubernetes, khai báo trong manifest.
Nguồn: Planet PostgreSQL
Trích nguồn từ: Planet PostgreSQL
Tags:
Bài viết liên quan
Nâng cấp PostgreSQL tại chỗ không downtime trên cụm phân tán
Ahsan Hadi hướng dẫn nâng cấp tại chỗ từng node PostgreSQL từ 17.10 lên 18.6 trên cụm Spock đa master, giữ ứng dụng luôn có endpoint ghi trong khi mỗi node tạm ngừng vài phút.
Đọc thêm
UUIDv4 và UUIDv7 trên Postgres: cái giá của khóa chính ngẫu nhiên
So sánh ba loại khóa chính trên Postgres 18 cho thấy UUIDv4 chèn chậm hơn khóa có thứ tự và ghi WAL nhiều hơn đáng kể ở mức 100 triệu dòng.
Đọc thêm
Ilya Kosmodemiansky bàn về file cấu hình postgresql.conf "mặc định"
Bài đầu tiên trong loạt bốn phần của Ilya Kosmodemiansky (Data Egret) về cách PostgreSQL đọc cấu hình và nhóm thiết lập kết nối, dựa trên bản PostgreSQL 18.
Đọc thêmChris van Eijk: Lỗi 'server closed the connection unexpectedly' trong PostgreSQL
Phân tích lỗi PostgreSQL đóng kết nối bất ngờ khi có sáu client, cách đọc log máy chủ theo từng nguyên nhân, nơi lưu lý do và các COMMIT bị mất.
Đọc thêmChristophe Pettus: Hiểu đúng về row_security trong PostgreSQL
Chuyên gia tư vấn PostgreSQL Christophe Pettus giải thích rằng đặt row_security = off không tắt bảo mật cấp dòng mà sẽ gây lỗi khi có chính sách được áp dụng.
Đọc thêm
Mô hình Data Warehouse: Sơ đồ ngôi sao
Trình bày về mô hình ngôi sao (star schema) khi xây dựng một dat a warehouse phục vụ mục đích báo cáo và phân tích cho doanh nghiệp.
Đọc thêm
Sự khác nhau giữa hệ thống OLAP và OLTP?
Có 2 loại ứng dụng cơ sở dữ liệu trong việc phát triển ứng dụng mà chúng ta cần biết. Bài viết này sẽ nói cho bạn biết sự giống và khác nhau giữa 2 loại hệ thống này.
Đọc thêm