Tuning memory trên Redhat/CentOS 7
HUGE PAGE : Memory được quản lý trong các block dưới dạng là page. Mỗi page có kích cỡ chuẩn 4KB. CPU có một đơn vị quản lý bộ nhớ (MMU – Memory Management Unit) bao gồm 1 list các page, mỗi page được trỏ đến thông qua một page table entry. (<– có thể nên nói nhanh gọn về “memory page ...
HUGE PAGE:
Memory được quản lý trong các block dưới dạng là page. Mỗi page có kích cỡ chuẩn 4KB. CPU có một đơn vị quản lý bộ nhớ (MMU – Memory Management Unit) bao gồm 1 list các page, mỗi page được trỏ đến thông qua một page table entry. (<– có thể nên nói nhanh gọn về “memory page swapping”)
Số lượng các huge page được cấu hình một cách liên tục trong hạt nhân lúc khởi động. Giá trị mặc định là 0. Chỉ có thể phân bổ các huge page nếu có đủ free page trong hệ thống. Các trang được bảo lưu bởi tham số này không thể được sử dụng cho các mục đích khác.
Giá trị này có thể được điều chỉnh sau khi khởi động bằng cách thay đổi giá trị của tập tin :
/proc/sys/vm/nr_hugepages
Trong một hệ thống NUMA, các huge page được gán với tham số này được chia đều giữa các node. Bạn có thể gán các huge page cho các node cụ thể trong thời gian chạy bằng cách thay đổi giá trị của tệp tin của các node file.
/sys/devices/system/node/node_id/hugepages/hugepages-1048576kB/nr_hugepages
Để biết thêm thông tin, hãy đọc tài liệu liên quan trong :
/usr/share/doc/kernel-doc-kernel_version/Documentation/vm/hugetlbpage.txt
Hugepagesz Xác định kích thước của các huge page liên tục được cấu hình trong kernel lúc khởi động. Các giá trị hợp lệ là 2 MB và 1 GB. Giá trị mặc định là 2 MB. Default_hugepagesz Xác định kích thước mặc định của các trang khổng lồ liên tục được cấu hình trong hạt nhân lúc khởi động. Các giá trị hợp lệ là 2 MB và 1 GB. Giá trị mặc định là 2 MB.
a. Cấu hình cho các page là 1GB lúc khởi động
Kích thước trang của hệ thống con HugeTLB phụ thuộc vào kiến trúc. Về kiến trúc AMD64 và Intel 64, các huge page 2 MB và 1 GB được hỗ trợ.
Tạo một pool HugeTLB cho page 1 GB bằng cách nối dòng sau vào các tùy chọn dòng lệnh của kernel:
Default_hugepagesz = 1G hugepagesz = 1G
Tạo một tệp có tên /usr/lib/systemd/system/hugetlb-gigantic-pages.service với nội dung sau:
[Unit] Description=HugeTLB Gigantic Pages Reservation DefaultDependencies=no Before=dev-hugepages.mount ConditionPathExists=/sys/devices/system/node ConditionKernelCommandLine=hugepagesz=1G [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/hugetlb-reserve-pages [Install] WantedBy=sysinit.target
Tạo một tập tin tên /usr/lib/systemd/hugetlb-reserve-pages có nội dung sau:
nodes_path=/sys/devices/system/node/ if [ ! -d $nodes_path ]; then echo "ERROR: $nodes_path does not exist" exit 1 fi reserve_pages() { echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages } # This example reserves 2 1G pages on node0 and 1 1G page on node1. You # can modify it to your needs or add more lines to reserve memory in # other nodes. Don't forget to uncomment the lines, otherwise then won't # be executed. # reserve_pages 2 node0 # reserve_pages 1 node1
Sửa đổi /usr/lib/systemd/hugetlb-reserve-pages giống như comment ở file phía trên. Chạy các lệnh sau để kích hoạt tính năng đặt trước khởi động:
# chmod +x /usr/lib/systemd/hugetlb-reserve-pages # systemctl enable hugetlb-gigantic-pages
CHÚ THÍCH Bạn có thể thử đặt thêm 1G trang trong thời gian chạy bằng cách ghi vào nr_hugepages bất kỳ lúc nào. Tuy nhiên, đặt phòng như vậy có thể thất bại do sự phân mảnh bộ nhớ. Cách đáng tin cậy nhất để dự trữ các trang 1G là bằng cách làm nó ngay lúc khởi động.
b. Config huge pages trong thời gian chạy
Sử dụng các thông số sau để ảnh hưởng đến hành vi của trang lớn khi chạy:
/sys/devices/system/node/node_id/hugepages/hugepages-size/nr_hugepages
Xác định số lượng các huge page có được cho nút NUMA(non-uniform memory access) được chỉ định. Việc này được support trên Red Hat Enterprise Linux 7.1. Ví dụ sau di chuyển thêm hai mươi 2048 kB huge pages vào node2.
# numastat -cm | egrep 'Node|Huge' Node 0 Node 1 Node 2 Node 3 Total add AnonHugePages 0 2 0 8 10 HugePages_Total 0 0 0 0 0 HugePages_Free 0 0 0 0 0 HugePages_Surp 0 0 0 0 0 # echo 20 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages # numastat -cm | egrep 'Node|Huge' Node 0 Node 1 Node 2 Node 3 Total AnonHugePages 0 2 0 8 10 HugePages_Total 0 0 40 0 40 HugePages_Free 0 0 40 0 40 HugePages_Surp 0 0 0 0 0
/proc/sys/vm/nr_overcommit_hugepages
Xác định số lượng tối đa các huge page bổ sung có thể được tạo ra và sử dụng bởi hệ thống. Ghi bất kỳ giá trị nào khác không vào tập tin này cho biết hệ thống sẽ nhận được số lượng huge page được nhận từ kernel page pool trong trường hợp huge page pool đã bị cạn kiệt. Khi những huge page không sử dụng, chúng sẽ được trả lại vào pool page của hạt nhân.
Phần này thảo luận về các tham số hạt nhân liên quan đến bộ nhớ có thể hữu ích trong việc cải thiện việc sử dụng bộ nhớ trên hệ thống của bạn. Các tham số này có thể được thiết lập tạm thời cho mục đích kiểm tra bằng cách thay đổi giá trị của tệp tương ứng trong hệ thống tệp tin /proc. Một khi bạn đã xác định các giá trị tạo ra hiệu suất tối ưu cho trường hợp bạn, bạn có thể đặt chúng vĩnh viễn bằng cách sử dụng lệnh sysctl.
Sử dụng bộ nhớ thường được cấu hình bằng cách thiết lập giá trị của một hoặc nhiều tham số kernel. Các thông số này có thể được thiết lập tạm thời bằng cách thay đổi nội dung của các tệp tin trong hệ thống tệp tin /proc hoặc chúng có thể được đặt liên tục với công cụ sysctl, được cung cấp bởi gói procps-ng.
Ví dụ: để đặt thông số overcommit_memory là 1 tạm thời, hãy chạy lệnh sau:
# Echo 1> / proc / sys / vm / overcommit_memory
Để đặt giá trị này liên tục, thêm sysctl vm.overcommit_memory = 1 trong /etc/sysctl.conf sau đó chạy lệnh sau:
# Sysctl -p
Thiết lập một tham số tạm thời rất hữu ích để xác định hiệu ứng tham số có trên hệ thống của bạn. Sau đó, bạn có thể thiết lập các thông số mặc định khi bạn chắc chắn rằng giá trị của tham số có hiệu quả mong muốn.
a. Tham số bộ nhớ ảo
Các tham số được liệt kê trong phần này được đặt trong /proc/sys/vm trừ khi có chỉ định khác. dirty_ratio Giá trị phần trăm. Khi tỷ lệ phần trăm của tổng bộ nhớ hệ thống được sửa đổi, hệ thống bắt đầu viết các sửa đổi đĩa với các hoạt động pdflush. Giá trị mặc định là 20 phần trăm.
dirty_background_ratio
Giá trị phần trăm. Khi tỷ lệ phần trăm này của bộ nhớ hệ thống được sửa đổi, hệ thống bắt đầu viết các sửa đổi vào đĩa trong nền. Giá trị mặc định là 10 phần trăm.
overcommit_memory
Xác định các điều kiện xác định xem một yêu cầu bộ nhớ lớn được chấp nhận hay bị từ chối. Giá trị mặc định là 0. Theo mặc định, hạt nhân thực hiện bộ nhớ heuristic overcommit xử lý bằng cách ước lượng số lượng bộ nhớ có sẵn và yêu cầu không quá lớn. Tuy nhiên, vì bộ nhớ được phân bổ bằng cách sử dụng một heuristic hơn là một thuật toán chính xác, quá tải bộ nhớ là có thể với thiết lập này. Khi tham số này được đặt thành 1, hạt nhân không thực hiện quá trình xử lý vượt quá bộ nhớ. Điều này làm tăng khả năng quá tải bộ nhớ, nhưng cải thiện hiệu suất cho các nhiệm vụ tốn nhiều bộ nhớ. Khi tham số này được đặt là 2, hạt nhân sẽ từ chối yêu cầu bộ nhớ bằng hoặc lớn hơn tổng của tổng không gian trao đổi có sẵn và phần trăm bộ nhớ vật lý được chỉ định trong overcommit_ratio. Điều này làm giảm nguy cơ lãng phí bộ nhớ, nhưng chỉ được khuyến cáo đối với các hệ thống có vùng trao đổi lớn hơn bộ nhớ vật lý của chúng.
overcommit_ratio
Chỉ định phần trăm RAM vật lý được xem xét khi overcommit_memory được đặt thành 2. Giá trị mặc định là 50. max_map_count Xác định số lượng tối đa của các khu vực bản đồ bộ nhớ mà một quá trình có thể sử dụng. Giá trị mặc định (65530) là thích hợp cho hầu hết các trường hợp. Tăng giá trị này nếu ứng dụng của bạn cần phải lập bản đồ nhiều hơn số lượng tệp này.
min_free_kbytes
Chỉ định số lượng kilobyte tối thiểu để giữ nguyên trên toàn hệ thống. Điều này được sử dụng để xác định một giá trị thích hợp cho mỗi vùng bộ nhớ thấp, mỗi trong số đó được gán một số trang miễn phí dành riêng tương ứng với kích thước của chúng.
CẢNH BÁO Giá trị cực đoan có thể làm hỏng hệ thống của bạn. Đặt min_free_kbytes lên một giá trị rất thấp sẽ ngăn không cho hệ thống lấy lại bộ nhớ, có thể dẫn đến treo hệ thống và quá trình giết OOM(out of memory). Tuy nhiên, thiết lập min_free_kbytes quá cao (ví dụ, 5-10% tổng bộ nhớ hệ thống) làm cho hệ thống nhập trạng thái ngoài bộ nhớ ngay lập tức, kết quả là hệ thống dành quá nhiều thời gian để phục hồi bộ nhớ.
oom_adj Trong trường hợp hệ thống hết bộ nhớ và tham số panic_on_oom được đặt thành 0, chức năng oom_killer sẽ giết các tiến trình cho đến khi hệ thống có thể phục hồi, bắt đầu từ quá trình với oom_score cao nhất. Thông số oom_adj giúp xác định oom_score của một tiến trình. Giá trị -17 vô hiệu hoá oom_killer cho quá trình đó. Các giá trị hợp lệ khác là từ -16 đến 15.
CHÚ THÍCH Các process sinh ra quá trình điều chỉnh sẽ kế thừa oom_score của process.
swappiness Giá trị swappiness, dao động từ 0 đến 100, kiểm soát mức độ mà hệ thống ưa thích bộ nhớ ẩn danh hoặc bộ nhớ cache trang. Một giá trị cao cải thiện hiệu suất của hệ thống tập tin trong khi tích cực trao đổi các tiến trình hoạt động ít hơn ra khỏi bộ nhớ RAM. Giá trị thấp tránh được các quá trình trao đổi trong bộ nhớ, thường làm giảm độ trễ ở mức chi phí thực hiện I/O. Giá trị mặc định là 60.
CẢNH BÁO Đặt swappiness == 0 sẽ tránh được trao đổi , làm tăng nguy cơ OOM giết chết dưới bộ nhớ mạnh và áp lực I/O.
b. Tham số hệ thống file
Các tham số được liệt kê trong phần này được đặt trong / proc/sys/fs trừ khi có chỉ dẫn khác. aio-max-nr Xác định số lượng tối đa cho phép các sự kiện trong tất cả các bối cảnh đầu vào / đầu ra không đồng bộ hoạt động. Giá trị mặc định là 65536. Sửa đổi giá trị này không phân bổ trước hoặc thay đổi kích thước bất kỳ cấu trúc dữ liệu hạt nhân nào. file-max Xác định số lượng tối đa tập tin xử lý cho toàn bộ hệ thống. Giá trị mặc định trên Red Hat Enterprise Linux 7 là tối đa là 8192, hoặc một phần mười trong số các trang bộ nhớ miễn phí có sẵn tại thời điểm hạt nhân bắt đầu. Nâng cao giá trị này có thể giải quyết các lỗi do thiếu tập tin xử lý.
c. Các tham số của kernel
Các giá trị mặc định cho các tham số sau, nằm trong thư mục /proc/sys/kernel /, có thể được tính toán bởi hạt nhân khi khởi động tùy thuộc vào các tài nguyên hệ thống có sẵn. msgmax Xác định kích thước cho phép tối đa theo byte của bất kỳ một tin nhắn nào trong hàng đợi tin nhắn. Giá trị này không được vượt quá kích thước của hàng đợi (msgmnb). Để xác định giá trị msgmax hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.msgmax
msgmnb Xác định kích thước tối đa bằng byte của một hàng đợi tin nhắn. Để xác định giá trị msgmnb hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.msgmnb
msgmni Xác định số lượng tối đa của nhận dạng hàng đợi thông điệp, và do đó số lượng hàng đợi tối đa. Để xác định giá trị msgmni hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.msgmni
shmall Xác định tổng số bộ nhớ chia sẻ (in bytes) có thể được sử dụng trên hệ thống tại một thời điểm. Để xác định giá trị shmall hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.shmall
shmmax Xác định kích thước tối đa (byte) của một phân đoạn bộ nhớ chia sẻ duy nhất cho phép bởi hạt nhân. Để xác định giá trị shmmax hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.shmmax
shmmni Xác định số lượng tối đa của phân đoạn bộ nhớ chia sẻ trên toàn hệ thống. Giá trị mặc định là 4096 trên tất cả các hệ thống. threads-max Xác định số luồng tối đa cho cả hệ thống sẵn sàng cho hạt nhân cùng một lúc. Để xác định giá trị hiện tại của chuỗi-hiện tại trên hệ thống của bạn, hãy sử dụng:
# Sysctl kernel.threads-max
Giá trị mặc định là kết quả của:
mempages / (8 * THREAD_SIZE / PAGE SIZE )
Giá trị tối thiểu là 20.