Tìm hiểu Apache MPM

I. Giới thiệu và so sánh sự khác nhau giữa 3 mode chính (Prefork, Worker, Event)

Apache MPM là các module muti-processing quyết định cách thức mà apache sẽ tiếp nhận và xử lý các request từ client. MPM là module của apache nên có thể enable hay disable trong file config của apache. Apache từ version 2.4 trở đi hỗ trợ 3 modules multi-processing : worker, prefork và event (lưu ý : chỉ sử dụng được 1 trong 3 modules này).

   1. MPM Perfork
Sử dụng nhiều tiến trình con (chill process) trong apache và mỗi chill process đó chỉ có 1 luồng (thread) để xử lý một request tại cùng một thời điểm.

Ưu điểm: Các process được xử lý hoàn toàn một cách độc lập không liên quan gì đến nhau, cho nên nếu một process chết thì các process còn lại vẫn hoạt động và vẫn hoàn thành công việc của nó. Đây là module mặc định và là module ổn định nhất, tương thích với các phần mềm cũ hơn.

Nhược điểm: do xử lý không phân luồng nên tạo ra quá nhiều process sẽ chiếm dụng lượng tài nguyên server lớn.

Thông số cần lưu ý:

StartServers : số process được tạo ra lúc apache start
MinspareServer : số process tối thiểu được chuẩn bị sẵn.
MaxSpareServer : số process tối đa được chuẩn bị sẵn
ServerLimit : Giá trị lớn nhất của Maxclient trong thời gian chạy apache
MaxClient : số process lớn nhất được chạy
MaxRequestsPerChild : số lượng request tối đa mà một process có thể phục vụ
MaxRequestWorkers : xác định số lượng tiến trình con tối đa có thể tồn tại cùng một lúc.

 2. MPM Worker
Sử dụng nhiều tiến trình con (chill process) trong apache và mỗi chill process sẽ có nhiều luồng (thread) và mỗi luồng sẽ xứ lý một request tại một thời điểm.

Ưu điểm: có thể xử lý nhiều tiến trình cùng 1 lúc. Nhanh hơn prefork và có thể xử lý nhiều khách truy cập hơn.

Nhược điểm: do xử lý nhiều nên tính ổn định sẽ không cao so với prefork.
Thông số cần lưu ý:
StartServers : số process được tạo ra lúc apache start
MaxClient : tổng số connections đồng thời sẽ được xử lý
MinSpareThread : số Thread tối thiểu được chuẩn bị sẵn
MaxSpareServer : Số Thread tối đa được chuẩn bị sẵn
ThreadsPerChild : số thread có trong một process
MaxrequestsPerchild : tổng số connections đồng thời được process xử lý.
MaxRequestWorkers : trong Worker xác định tổng số luồng tối đa có thể hoạt động đồng thời.

   3. MPM Event
Event MPM dựa trên mô hình Worker MPM để hoạt động. Event MPM sử dụng các tiến trình parent ( tiến trình cha ) chịu trách nhiệm chạy các chill process, mỗi chill process sẽ tạo ra nhiều thread để xứ lý các request.

 Ưu điểm : là cải tiến từ mpm worker với mục tiểu chỉ sử dụng các luồng cho các kết nối có xử lý tích cực và là module nhanh nhất, sử dụng ít tài nguyên nhất.

Nhược điểm : Do xử lý phức tạp và xử lý nhiều tiến trình hơn cho với 2 module trên nên tính ổn định kém nhất.

II. Kiểm tra module MPM đang chạy trên server

Centos: httpd -V | grep -i mpm
Ubuntu: apachectl -V | grep -i mpm

III. Thiết lập và tính toán các thông số để tối ưu phù hợp

– Cài đặt python ps_mem.py
wget https://raw.githubusercontent.com/pixelb/ps_mem/master/ps_mem.py
chmod a+x ps_mem.py
python ps_mem.py

Như ví dụ trong bài viết này đang có 3 process size apache (httpd) tiêu thụ 4.6MB, vì vậy mỗi apache process đang sử dụng khoảng 1.5MB RAM và mỗi PHP process size sẽ sử dụng khoảng 4.5MB

– Công thức tính MaxrequestWorkers và ServerLimit:
MaxRequestWorkers = (Total RAM – Memory used for Linux, DB, etc.) / process sizeMaxRequestWorkers = (3770 – 925) / 1.5 = 1896

– Công Thức tính php-fpm max-children
Max-children = (Tổng RAM – Bộ nhớ được sử dụng cho Linux, DB, v.v.) / PHP process zise
Max-children = (3770 – 925) / 4.5 = 632

IV. Chỉnh sửa cấu hình MPM trong apache

Vào file cấu hình của module MPM đang chạy để chỉnh sửa ví dụ trong bài viết đang chạy MPM Event thì ta vào đường dẫn ” /etc/apache2/mods-enabled/mpm_event.conf ”

Lưu ý rằng cài đặt mặc định không chứa “server limit “, vì vậy thêm nó vào đây còn các thông số khác thì để mặc định.
Cấu hình thông số php-fpm (8.1 là version trong bài  viết này sử dụng), vào file config của php-fpm “/etc/php/8.1/fpm/pool.d/www.conf”

pm = dynamic

pm.max_children =  640

pm.start_servers = (cpu cores * 4)

pm.min_spare_servers =  (cpu cores * 2)

pm.max_spare_servers =  (cpu cores * 4)

pm.max_requests = 1000