Tối ưu hiệu suất Linux server cho production: Hướng dẫn chi tiết cho người mới bắt đầu

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Giới thiệu vấn đề: Tại sao phải tối ưu hiệu suất server?

Khi mới bắt đầu với Linux server, bạn sẽ sớm nhận ra việc giữ cho hệ thống hoạt động trơn tru, nhanh chóng là cực kỳ quan trọng. Đặc biệt, điều này càng đúng khi lượng người dùng hoặc dữ liệu bắt đầu tăng lên. Một server chậm không chỉ làm giảm trải nghiệm người dùng mà còn gây ra nhiều vấn đề nghiêm trọng: mất khách hàng, gián đoạn dịch vụ, thậm chí là thiệt hại tài chính. Vì vậy, tối ưu hiệu suất không chỉ là một kỹ năng. Đó còn là trách nhiệm của mỗi quản trị viên hệ thống.

Bạn mới làm quen với IT và thấy khái niệm “hiệu suất server” có vẻ phức tạp? Đừng lo lắng! Bài viết này sẽ giúp bạn nắm rõ từng khía cạnh và cung cấp các bước thực hành chi tiết để bạn có thể áp dụng ngay.

Khái niệm cốt lõi: Hiệu suất là gì và các nút thắt cổ chai

Trước khi bắt tay vào tối ưu, chúng ta cần hiểu “hiệu suất” thực sự có nghĩa là gì trong ngữ cảnh server Linux. Hiệu suất của một server được đánh giá qua nhiều yếu tố, nhưng cơ bản nhất là:

  • Throughput (Thông lượng): Khả năng xử lý bao nhiêu yêu cầu hoặc dữ liệu trong một khoảng thời gian nhất định (ví dụ: số giao dịch mỗi giây).
  • Latency (Độ trễ): Thời gian cần thiết để phản hồi một yêu cầu (ví dụ: thời gian tải trang web).
  • Resource Utilization (Sử dụng tài nguyên): Mức độ sử dụng các tài nguyên phần cứng như CPU, RAM, Disk I/O và Network.

Khi hiệu suất server đi xuống, thường là do một hoặc nhiều tài nguyên bị quá tải, tạo thành cái chúng ta gọi là “nút thắt cổ chai” (bottleneck). Nhiệm vụ của chúng ta là tìm ra những nút thắt này và khắc phục chúng. Ví dụ, nếu CPU luôn chạy 100% trong khi RAM còn trống rất nhiều, thì CPU chính là nút thắt.

Thực hành chi tiết: Các bước tối ưu hiệu suất Linux server

1. Theo dõi và Phân tích: Biết địch biết ta

Bước đầu tiên và quan trọng nhất để tối ưu bất kỳ hệ thống nào là theo dõi nó. Bạn không thể cải thiện cái mà bạn không đo lường. Linux cung cấp rất nhiều công cụ mạnh mẽ để theo dõi tài nguyên.

Theo dõi tổng quan tài nguyên

Các lệnh như tophtop (một công cụ phổ biến và nhiều tính năng hơn top) cho bạn cái nhìn tổng quan về CPU, RAM, swap và các tiến trình đang chạy.

htop

Để chỉ xem mức sử dụng RAM và swap:

free -h

Kiểm tra dung lượng ổ đĩa:

df -h

Theo dõi Disk I/O

iostat giúp kiểm tra hiệu suất I/O của ổ đĩa một cách hiệu quả:

iostat -x 1 10

Lệnh này sẽ hiển thị báo cáo I/O chi tiết mỗi giây, lặp lại 10 lần. Bạn hãy chú ý các cột quan trọng như %util (mức độ sử dụng của thiết bị), r/s, w/s (số đọc/ghi mỗi giây), rkB/s, wkB/s (lượng dữ liệu đọc/ghi mỗi giây). Đặc biệt, cột await (thời gian chờ trung bình cho các thao tác I/O) rất đáng quan tâm.

iotop cũng rất hữu ích để xem tiến trình nào đang gây ra nhiều I/O nhất, tương tự như top cho CPU/RAM:

iotop

Theo dõi Network

ss (thay thế hiện đại cho netstat) giúp bạn xem các kết nối mạng đang hoạt động:

ss -tulpn

Lệnh này hiển thị các socket TCP, UDP đang lắng nghe (listening) và các socket đã thiết lập kết nối (established) cùng với tên tiến trình.

Kiểm tra Logs (Nhật ký hệ thống)

Đừng bao giờ bỏ qua các file log! Chúng là kho tàng thông tin giúp bạn hiểu rõ điều gì đang xảy ra trên server. Hồi mới làm sysadmin, mình từng mất cả buổi chiều để debug một server chạy chậm chỉ vì không đọc kỹ log. Hóa ra, một dịch vụ bị lỗi đã liên tục cố gắng khởi động lại, gây tốn tài nguyên CPU và Disk I/O. Nếu chịu khó mở log ra xem sớm hơn, mình đã tiết kiệm được rất nhiều thời gian!

Các log quan trọng cần xem:

  • /var/log/syslog hoặc /var/log/messages (log chung của hệ thống)
  • Log của các ứng dụng cụ thể (Apache, Nginx, database, ứng dụng của bạn…)
  • Sử dụng journalctl cho các hệ thống dùng systemd:
journalctl -xe

Lệnh này sẽ hiển thị các log gần đây nhất, giúp bạn nhanh chóng phát hiện lỗi hoặc cảnh báo.

2. Tối ưu CPU

Nếu top hoặc htop cho thấy CPU của bạn thường xuyên ở mức cao, đây là một số cách tối ưu:

  • Xác định tiến trình gây tốn CPU: Dùng top/htop, sắp xếp theo cột %CPU để tìm ra tiến trình “ngốn” CPU nhiều nhất. Sau đó, bạn cần điều tra xem tiến trình đó có đang hoạt động đúng không hay đang bị lỗi.
  • Điều chỉnh độ ưu tiên tiến trình: Nếu có những tiến trình không quá quan trọng nhưng vẫn cần chạy, bạn có thể giảm độ ưu tiên của chúng bằng nicerenice. Điều này giúp chúng nhường CPU cho các tiến trình quan trọng hơn.
# Chạy một lệnh với độ ưu tiên thấp hơn (ví dụ: my_command sẽ nhận ít tài nguyên CPU hơn)
nice -n 10 my_command

# Thay đổi độ ưu tiên của một tiến trình đang chạy (PID là ID của tiến trình)
renice +10 -p <PID>

Giá trị nice càng cao (ví dụ: +19) thì độ ưu tiên càng thấp. Ngược lại, giá trị càng thấp (ví dụ: -20) thì độ ưu tiên càng cao.

3. Tối ưu RAM và Swap

RAM là tài nguyên cực kỳ quan trọng cho tốc độ server. Nếu RAM thiếu, hệ thống sẽ phải dùng đến swap (một phần của ổ đĩa được dùng làm RAM ảo). Điều này chậm hơn RAM thật đến hàng trăm lần.

Kiểm soát Swappiness

swappiness là một tham số kernel kiểm soát mức độ hệ thống sử dụng swap. Mặc định trên Ubuntu, giá trị này thường là 60, nghĩa là kernel sẽ bắt đầu dùng swap khi RAM còn 40% trống. Trong môi trường production, chúng ta thường muốn server ưu tiên giữ dữ liệu trong RAM. Hạn chế đẩy ra swap quá sớm là rất quan trọng.

# Kiểm tra giá trị swappiness hiện tại
sysctl vm.swappiness

# Thiết lập giá trị swappiness thấp hơn (ví dụ: 10) để ít dùng swap hơn
sudo sysctl vm.swappiness=10

# Để thay đổi này vĩnh viễn, thêm vào /etc/sysctl.conf
sudo echo "vm.swappiness=10" >> /etc/sysctl.conf

Giá trị swappiness phù hợp sẽ tùy thuộc vào ứng dụng của bạn. Với các ứng dụng cần hiệu suất cao và hiếm khi dùng swap, giá trị 10 hoặc thậm chí 1 là lý tưởng. Ngược lại, nếu server có ít RAM và bạn muốn tránh tình trạng hệ thống bị treo do hết bộ nhớ (OOM killer), bạn có thể giữ giá trị mặc định hoặc tăng nhẹ.

Giảm bộ nhớ đệm (Cache) của hệ thống tệp tin

Kernel Linux thường dùng một phần RAM để cache các file hệ thống như page cache, inode cache, dentry cache nhằm tăng tốc độ đọc ghi. Điều này rất tốt, nhưng đôi khi, các cache này có thể chiếm quá nhiều RAM. Hệ quả là gây thiếu hụt bộ nhớ cho các ứng dụng thực sự cần. Tham số vm.vfs_cache_pressure kiểm soát mức độ kernel thu hồi các cache này. Giá trị mặc định là 100.

# Kiểm tra giá trị hiện tại
sysctl vm.vfs_cache_pressure

# Giảm giá trị này (ví dụ: 50) để kernel ít thu hồi các cache hơn, giữ chúng lâu hơn trong RAM
sudo sysctl vm.vfs_cache_pressure=50

# Để thay đổi vĩnh viễn
sudo echo "vm.vfs_cache_pressure=50" >> /etc/sysctl.conf

Việc điều chỉnh vm.vfs_cache_pressure cần cân nhắc kỹ. Nếu giảm quá thấp, hệ thống tệp tin có thể chậm hơn. Đây là một tối ưu nâng cao và thường chỉ thực hiện khi bạn đã hiểu rõ ứng dụng của mình, đồng thời đã kiểm tra các phương án khác.

4. Tối ưu Disk I/O

Disk I/O (Input/Output) là một trong những nút thắt cổ chai phổ biến nhất, đặc biệt với các ứng dụng database hoặc xử lý file lớn.

Mount Options

Khi mount các filesystem, bạn có thể thêm các tùy chọn để cải thiện hiệu suất:

  • noatime: Mặc định, Linux cập nhật thời gian truy cập (atime) mỗi khi một file được đọc. Điều này gây ra một lượng đáng kể các thao tác ghi Disk I/O không cần thiết. Tùy chọn noatime sẽ vô hiệu hóa việc cập nhật này, giúp giảm tải cho ổ đĩa.

Để thêm noatime, bạn chỉnh sửa file /etc/fstab. Tìm dòng mount của phân vùng muốn tối ưu và thêm noatime vào danh sách tùy chọn.

Ví dụ, từ:

UUID=... / ext4 defaults 0 1

Thành:

UUID=... / ext4 defaults,noatime 0 1

Sau khi chỉnh sửa, bạn cần remount phân vùng (hoặc khởi động lại server):

sudo mount -o remount /

Hãy cẩn thận khi chỉnh sửa /etc/fstab, một lỗi nhỏ có thể khiến hệ thống không khởi động được.

I/O Scheduler

I/O scheduler quyết định thứ tự các yêu cầu đọc/ghi sẽ được gửi đến ổ đĩa vật lý. Các scheduler phổ biến là noop, deadlinecfq.

  • noop: Là scheduler đơn giản nhất, thường phù hợp cho SSD hoặc môi trường ảo hóa. Ở đây, việc điều phối I/O đã được xử lý ở lớp phần cứng hoặc hypervisor.
  • deadline: Ưu tiên các yêu cầu đọc và đặt thời hạn cho chúng, đảm bảo không có yêu cầu nào phải chờ quá lâu. Thường tốt cho các ứng dụng database.
  • cfq (Completely Fair Queuing): Cố gắng phân phối băng thông I/O công bằng giữa các tiến trình. Thường tốt cho desktop hoặc server đa mục đích với ổ HDD truyền thống.

Với các ổ SSD hiện đại, noop hoặc deadline thường cho hiệu suất tốt hơn.

# Kiểm tra scheduler hiện tại cho ổ đĩa sda
cat /sys/block/sda/queue/scheduler

# Đặt scheduler thành noop
sudo echo noop > /sys/block/sda/queue/scheduler

Để thay đổi này vĩnh viễn, bạn cần chỉnh sửa file cấu hình GRUB hoặc dùng udev rules.

5. Tối ưu Network

Mặc dù một số cấu hình mạng nâng cao đã được đề cập ở các bài viết khác, bạn vẫn có thể áp dụng vài tối ưu cơ bản cho tầng TCP/IP của Linux kernel để cải thiện hiệu suất mạng tổng thể.

TCP/IP Tuning

Chỉnh sửa file /etc/sysctl.conf để thêm hoặc thay đổi các tham số kernel sau:

# Tăng số lượng kết nối tối đa có thể giữ ở trạng thái TIME_WAIT
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_tw_buckets = 500000

# Tăng hàng đợi cho các kết nối đến chưa được chấp nhận
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535

# Tăng giới hạn bộ đệm mạng (receive buffer và send buffer)
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304

# Cho phép Fast Open (giảm độ trễ thiết lập kết nối TCP)
net.ipv4.tcp_fastopen = 3

Sau khi chỉnh sửa, áp dụng các thay đổi:

sudo sysctl -p

Các tham số này giúp server xử lý tốt hơn các kết nối đến và đi, giảm khả năng nghẽn mạng do thiếu tài nguyên socket, đặc biệt khi tải cao.

Tăng giới hạn File Descriptors (ulimit)

Mỗi kết nối mạng hay mỗi file mở đều sử dụng một file descriptor. Các ứng dụng như web server hay database có thể cần mở hàng ngàn, thậm chí hàng chục ngàn file descriptor cùng lúc. Nếu giới hạn này quá thấp, ứng dụng sẽ gặp lỗi và không thể hoạt động hiệu quả.

Kiểm tra giới hạn hiện tại cho tiến trình shell của bạn:

ulimit -n

Để tăng giới hạn này cho toàn hệ thống, bạn cần chỉnh sửa file /etc/security/limits.conf:

# Thêm hai dòng này vào cuối file để đặt giới hạn mềm và cứng
* soft nofile 65535
* hard nofile 65535

Và đảm bảo rằng PAM module được kích hoạt trong /etc/pam.d/common-session hoặc /etc/pam.d/login (thường đã được kích hoạt mặc định):

session required pam_limits.so

Sau khi thay đổi, bạn cần đăng xuất và đăng nhập lại hoặc khởi động lại server để các thay đổi có hiệu lực.

Kết luận

Tối ưu hiệu suất Linux server là một quá trình liên tục, đòi hỏi bạn phải theo dõi, phân tích và điều chỉnh. Không có một công thức chung nào phù hợp cho mọi trường hợp, vì mỗi ứng dụng và môi trường lại có những yêu cầu riêng biệt. Điều quan trọng là bạn phải hiểu rõ cách server của mình đang hoạt động, tài nguyên nào đang là nút thắt cổ chai, và từ đó áp dụng các biện pháp tối ưu phù hợp.

Hãy nhớ, việc tối ưu không chỉ dừng lại ở một lần cấu hình ban đầu. Bạn cần luôn theo dõi hệ thống, đọc log, và sẵn sàng điều chỉnh khi tải làm việc thay đổi. Với những kiến thức và công cụ trong bài viết này, mình tin rằng bạn đã có đủ hành trang để bắt đầu hành trình biến server của mình trở nên nhanh hơn, mạnh mẽ hơn.

Share: