Định cấu hình tùy chọn hạt nhân Linux để tối ưu hóa PostgreSQL

Định cấu hình tùy chọn hạt nhân Linux để tối ưu hóa PostgreSQL Hiệu suất PostgreSQL tối ưu phụ thuộc vào các tham số hệ điều hành được xác định chính xác. Cài đặt nhân hệ điều hành được cấu hình kém có thể dẫn đến hiệu suất máy chủ cơ sở dữ liệu kém. Do đó, điều bắt buộc là các cài đặt này phải được cấu hình theo máy chủ cơ sở dữ liệu và khối lượng công việc của nó. Trong bài đăng này, chúng tôi sẽ thảo luận về một số tham số nhân Linux quan trọng có thể ảnh hưởng đến hiệu suất của máy chủ cơ sở dữ liệu và cách định cấu hình chúng.

SHMMAX / NHỎ

SHMMAX là tham số kernel được sử dụng để xác định kích thước tối đa của một phân đoạn bộ nhớ dùng chung mà quy trình Linux có thể phân bổ. Trước phiên bản 9.2, PostgreSQL đã sử dụng System V (SysV), hệ thống này yêu cầu cài đặt SHMMAX. Sau phiên bản 9.2, PostgreSQL chuyển sang bộ nhớ dùng chung POSIX. Vì vậy, bây giờ cần ít byte bộ nhớ dùng chung của System V hơn.

Trước phiên bản 9.3, SHMMAX là tham số kernel quan trọng nhất. Giá trị SHMMAX được chỉ định theo byte.

Tương tự NHỎ là một tham số kernel khác được sử dụng để xác định
khối lượng trang bộ nhớ dùng chung trên toàn hệ thống. Để xem các giá trị SHMMAX, SHMALL hoặc SHMMIN hiện tại, hãy sử dụng lệnh i cái.

Chi tiết SHM* - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

Chi tiết SHM* - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

Sử dụng PostgreSQL Hệ thống V IPC để phân bổ bộ nhớ dùng chung. Tham số này là một trong những tham số kernel quan trọng nhất. Bất cứ khi nào bạn nhận được thông báo lỗi sau, điều đó có nghĩa là bạn có phiên bản PostgreSQL cũ hơn và giá trị SHMMAX của bạn rất thấp. Người dùng dự kiến ​​sẽ điều chỉnh và tăng giá trị tùy theo bộ nhớ dùng chung mà họ định sử dụng.

Có thể xảy ra lỗi cấu hình sai

Nếu SHMMAX không được cấu hình đúng, bạn có thể gặp lỗi khi cố gắng khởi tạo cụm PostgreSQL bằng lệnh initdb.

lỗi initdb
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

Tương tự, bạn có thể gặp lỗi khi khởi động máy chủ PostgreSQL bằng lệnh pg_ctl.

pg_ctl Thất bại
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

Hiểu sự khác biệt trong định nghĩa

Việc xác định các tham số SHMMAX/SHMALL hơi khác một chút trên Linux và MacOS X:

  • Linux: kernel.shmmax, kernel.shmall
  • MacOS X: kern.sysv.shmmax, kern.sysv.shmall

Đội hệ thống có thể được sử dụng để tạm thời thay đổi giá trị. Để đặt giá trị không đổi, hãy thêm một mục vào /etc/sysctl.conf. Chi tiết ở bên dưới.

Thay đổi cài đặt kernel trên MacOS X

# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kern.sysv.shmall 
kern.sysv.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216

Thay đổi tham số hạt nhân trên Linux

# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216

Làm thế nào để làm gì đó: Để thực hiện các thay đổi vĩnh viễn, hãy thêm các giá trị này vào /etc/sysctl.conf

Trang lớn

Linux sử dụng các trang bộ nhớ 4 KB theo mặc định, BSD sử dụng các trang bộ nhớ XNUMX KB. Siêu trangvà trên Windows - Trang lớn. Một trang là một phần RAM được phân bổ cho một tiến trình. Một tiến trình có thể có nhiều trang tùy thuộc vào yêu cầu bộ nhớ. Quá trình càng yêu cầu nhiều bộ nhớ thì càng được phân bổ nhiều trang. HĐH duy trì bảng phân bổ trang cho các tiến trình. Kích thước trang càng nhỏ, bảng càng lớn thì thời gian tìm một trang trong bảng trang đó càng lâu. Do đó, các trang lớn cho phép sử dụng lượng lớn bộ nhớ với chi phí thấp hơn; ít lượt xem trang hơn, ít lỗi trang hơn, thao tác đọc/ghi nhanh hơn trên bộ đệm lớn hơn. Kết quả là hiệu suất được cải thiện.

PostgreSQL chỉ hỗ trợ các trang lớn trên Linux. Theo mặc định, Linux sử dụng các trang bộ nhớ 4 KB nên trong trường hợp có quá nhiều thao tác bộ nhớ thì cần thiết lập các trang lớn hơn. Hiệu suất tăng được quan sát thấy khi sử dụng các trang lớn từ 2 MB đến 1 GB. Kích thước trang lớn có thể được đặt khi khởi động. Bạn có thể dễ dàng kiểm tra các tham số trang lớn và cách sử dụng chúng trên máy Linux của mình bằng lệnh mèo /proc/meminfo | grep -i rất lớn.

Nhận thông tin về các trang lớn (chỉ dành cho Linux)

Note: This is only for Linux, for other OS this operation is ignored$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Trong ví dụ này, mặc dù kích thước trang lớn được đặt thành 2048 (2 MB), tổng số trang lớn được đặt thành 0. Điều này có nghĩa là các trang lớn bị vô hiệu hóa.

Tập lệnh xác định số lượng trang lớn

Tập lệnh đơn giản này trả về số lượng trang lớn cần thiết. Chạy tập lệnh trên máy chủ Linux của bạn trong khi PostgreSQL đang chạy. Hãy chắc chắn rằng đối với biến môi trường $PGDATA Thư mục dữ liệu PostgreSQL được chỉ định.

Lấy số lượng trang lớn cần thiết

#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid:            $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak:            $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize:   $hps kB"
hp=$((peak/hps))
echo Set Huge Pages:     $hp

Đầu ra tập lệnh trông như thế này:

Đầu ra tập lệnh

Pid:            12737
VmPeak:         180932 kB
Hugepagesize:   2048 kB
Set Huge Pages: 88

Giá trị được đề xuất cho các trang lớn là 88, vì vậy bạn nên đặt nó thành 88.

Cài đặt trang lớn

sysctl -w vm.nr_hugepages=88

Kiểm tra các trang lớn ngay bây giờ, bạn sẽ thấy các trang lớn không được sử dụng (HugePages_Free = HugePages_Total).

Các trang lớn được xem lại (Chỉ dành cho Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       88
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Bây giờ hãy đặt tham số Huge_pages thành "bật" trong $PGDATA/postgresql.conf và khởi động lại máy chủ.

Một lần nữa, thông tin về các trang lớn (chỉ dành cho Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       81
HugePages_Rsvd:       64
HugePages_Surp:        0
Hugepagesize:       2048 kB

Bây giờ bạn có thể thấy rằng rất ít trang lớn đang được sử dụng. Bây giờ chúng ta hãy thử thêm một số dữ liệu vào cơ sở dữ liệu.

Một số thao tác cơ sở dữ liệu để tái chế các trang lớn

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

Hãy xem liệu bây giờ chúng ta có đang sử dụng nhiều trang lớn hơn trước không.

Thông tin thêm trên các trang lớn (chỉ dành cho Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       18
HugePages_Rsvd:        1
HugePages_Surp:        0
Hugepagesize:       2048 kB

Bây giờ bạn có thể thấy rằng hầu hết các trang lớn đang được sử dụng.

Lưu ý: Giá trị ước tính cho HugePages được sử dụng ở đây rất thấp, đây không phải là giá trị bình thường đối với máy chạy môi trường sản phẩm. Vui lòng ước tính số lượng trang cần thiết cho hệ thống của bạn và đặt chúng phù hợp dựa trên tải và tài nguyên.

vm.swappiness

vm.swappiness là một tham số kernel khác có thể ảnh hưởng đến hiệu suất cơ sở dữ liệu. Tùy chọn này được sử dụng để kiểm soát hành vi hoán đổi (hoán đổi các trang vào và ra khỏi bộ nhớ) trong Linux. Giá trị nằm trong khoảng từ 0 đến 100. Nó xác định dung lượng bộ nhớ sẽ được phân trang hoặc phân trang. Số 100 có nghĩa là không trao đổi và XNUMX có nghĩa là trao đổi tích cực.

Bạn có thể có được hiệu suất tốt bằng cách đặt giá trị thấp hơn.

Đặt giá trị này thành 0 trên các hạt nhân mới hơn có thể khiến OOM Killer (quy trình dọn dẹp bộ nhớ của Linux) giết chết quy trình. Vì vậy, sẽ an toàn khi đặt thành 1 nếu bạn muốn giảm thiểu việc hoán đổi. Giá trị mặc định trong Linux là 60. Giá trị cao hơn khiến MMU (đơn vị quản lý bộ nhớ) sử dụng nhiều không gian trao đổi hơn RAM, trong khi giá trị thấp hơn sẽ giữ nhiều dữ liệu/mã hơn trong bộ nhớ.

Giá trị thấp hơn là một lựa chọn tốt để cải thiện hiệu suất trong PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Các ứng dụng thu thập bộ nhớ và giải phóng nó khi không còn cần thiết. Nhưng trong một số trường hợp, ứng dụng chiếm quá nhiều bộ nhớ và không giải phóng được. Điều này có thể gây ra kẻ giết người OOM. Dưới đây là các giá trị tham số có thể vm.overcommit_memory với một mô tả cho mỗi:

  1. Heuristic overcommit (mặc định); heuristic dựa trên kernel
  2. Vẫn cho phép vượt mức
  3. Đừng lạm dụng nó, đừng vượt quá tỷ lệ vượt quá.

Tham khảo: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio - phần trăm RAM có sẵn cho tình trạng quá tải. Giá trị 50% trên hệ thống có RAM 2 GB có thể phân bổ tối đa 3 GB RAM.

Giá trị 2 cho vm.overcommit_memory mang lại hiệu suất tốt hơn cho PostgreSQL. Giá trị này tối đa hóa việc sử dụng RAM của quy trình máy chủ mà không có bất kỳ nguy cơ đáng kể nào bị giết bởi quy trình sát thủ OOM. Ứng dụng sẽ có thể tải lại, nhưng chỉ trong giới hạn vượt mức, điều này giúp giảm nguy cơ kẻ sát nhân OOM giết chết quá trình. Do đó, giá trị 2 cho hiệu suất tốt hơn giá trị mặc định là 0. Tuy nhiên, độ tin cậy có thể được cải thiện bằng cách đảm bảo rằng bộ nhớ ngoài phạm vi không bị quá tải. Điều này giúp loại bỏ nguy cơ quá trình bị giết bởi kẻ giết người OOM.

Trên các hệ thống không có trao đổi, có thể xảy ra sự cố với vm.overcommit_memory bằng 2.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_ratio / vm.dirty_background_bytes

vm.dirty_background_ratio là phần trăm bộ nhớ chứa đầy các trang bẩn cần được ghi vào đĩa. Việc xả vào đĩa xảy ra ở chế độ nền. Giá trị của tham số này nằm trong khoảng từ 0 đến 100; tuy nhiên, giá trị dưới 5 có thể không hiệu quả và một số hạt nhân không hỗ trợ giá trị đó. 10 là mặc định trên hầu hết các hệ thống Linux. Bạn có thể cải thiện hiệu suất cho các hoạt động ghi nhiều bằng hệ số nhỏ hơn, điều này có nghĩa là Linux sẽ xóa các trang bẩn trong nền.

Bạn cần đặt giá trị vm.dirty_background_bytes tùy thuộc vào tốc độ ổ đĩa của bạn.

Không có giá trị "tốt" cho hai tham số này vì cả hai đều phụ thuộc vào phần cứng. Tuy nhiên, việc đặt vm.dirty_background_ratio thành 5 và vm.dirty_background_bytes thành 25% tốc độ ổ đĩa sẽ cải thiện hiệu suất lên ~25% trong hầu hết các trường hợp.

vm.dirty_ratio/dirty_bytes

Điều này cũng giống như vm.dirty_background_ratio/dirty_background_bytes, ngoại trừ việc thiết lập lại được thực hiện trong phiên làm việc, chặn ứng dụng. Vì vậy vm.dirty_ratio phải cao hơn vm.dirty_background_ratio. Điều này đảm bảo rằng các tiến trình nền sẽ bắt đầu sớm hơn để tránh chặn ứng dụng nhiều nhất có thể. Bạn có thể điều chỉnh sự khác biệt giữa hai tỷ lệ này tùy thuộc vào tải I/O của đĩa.

Tổng

Bạn có thể điều chỉnh các cài đặt khác để cải thiện hiệu suất, nhưng những cải tiến sẽ rất ít và bạn sẽ không thấy nhiều lợi ích. Chúng ta phải nhớ rằng không phải tất cả các tùy chọn đều áp dụng cho tất cả các loại ứng dụng. Một số ứng dụng hoạt động tốt hơn khi chúng tôi điều chỉnh một số cài đặt, còn một số thì không. Bạn phải tìm sự cân bằng phù hợp giữa việc định cấu hình các cài đặt này cho khối lượng công việc dự kiến ​​và loại ứng dụng của mình, đồng thời bạn cũng phải xem xét hành vi của hệ điều hành khi điều chỉnh. Việc cấu hình các tham số kernel không dễ như cấu hình các tham số cơ sở dữ liệu; việc đưa ra khuyến nghị còn khó khăn hơn.

Nguồn: www.habr.com

Thêm một lời nhận xét