Blog

File swap bị thiếu đã làm đứng các máy chủ của chúng tôi

Ngày 24 tháng 9, một trong các máy chủ production của chúng tôi ngừng phản hồi. Load balancer đánh dấu nó không khỏe mạnh và công cụ chạy lệnh từ xa của chúng tôi không thể kết nối được — nhưng không có gì crash và không có tiến trình nào bị kill vì dùng quá nhiều bộ nhớ. Máy chủ bị thrashing: không có không gian swap và các container được phép dùng nhiều bộ nhớ hơn máy có, nên Linux dành thời gian để loại bỏ và đọc lại các file nó cần để chạy, và gần như không tiến triển được. Thêm một file swap 2 GB trên mọi máy chủ đã khắc phục. Bài học thú vị hơn là về health check.

“Treo” trông như thế nào

  • Health check của load balancer hết thời gian chờ trên máy chủ đó.
  • Các lệnh gửi qua AWS Systems Manager nằm ở trạng thái “Pending” và không bao giờ chạy.
  • Không có lỗi hết bộ nhớ trong nhật ký. Không có tiến trình nào chết.

Một tuần trước đó, chúng tôi đã chuyển production sang các máy chủ ARM nhỏ hơn với 2 GB RAM mỗi máy. Máy chủ staging của chúng tôi — còn nhỏ hơn nữa — đã đứng theo cách tương tự khi giải nén một image container trong lúc triển khai.

Vì sao không có lỗi bộ nhớ?

Linux chỉ kill một tiến trình khi nó thực sự hết bộ nhớ có thể thu hồi. Trước điểm đó, nó thu hồi bộ nhớ từ page cache — các bản sao của file mà nó giữ trong RAM, bao gồm mã của mọi chương trình đang chạy.

Trên máy chủ của chúng tôi, tổng giới hạn bộ nhớ của các container cộng lại khoảng 3,3 GB trên một máy có khoảng 1,8 GB dùng được. Thông thường chúng không dùng hết giới hạn cùng lúc. Khi chúng làm vậy, kernel liên tục loại mã chương trình khỏi cache để lấy chỗ, rồi phải đọc lại từ đĩa ngay khi đoạn mã đó chạy trở lại. Vòng lặp đó — thrashing — có thể làm một máy gần như hoàn toàn không phản hồi mà về mặt kỹ thuật không bao giờ hết bộ nhớ. Vì vậy không có gì bị kill, và không có gì phục hồi.

Không có swap, kernel không có chỗ để đặt bộ nhớ đã được cấp phát nhưng ít khi dùng, nên nó phải lấy từ cache.

Cách sửa

Script bootstrap của máy chủ giờ tạo một file swap 2 GB với swappiness thấp (10) mỗi khi máy chủ khởi động hoặc được sửa chữa. Swappiness thấp nghĩa là kernel vẫn ưu tiên giữ bộ nhớ làm việc trong RAM, nhưng các trang ít được chạm tới có thể chuyển sang đĩa thay vì buộc mã chương trình ra khỏi cache. Chúng tôi áp dụng trực tiếp cho cả hai máy production và staging, và quy trình triển khai công bố lại script bootstrap trên mỗi lần triển khai production để một máy chủ được thay thế cũng nhận được nó.

Điều khiến chúng tôi lo hơn: máy chủ không khỏe vẫn còn đó

Nhóm máy chủ của chúng tôi dùng health check của EC2 — “máy có đang chạy không?” — chứ không phải health check của load balancer — “nó có đang trả lời yêu cầu không?”. Vì vậy một máy chủ mà load balancer đã bỏ cuộc vẫn được nhóm coi là khỏe mạnh. Nó sẽ không bao giờ được thay thế. Production sẽ âm thầm chạy trên một máy chủ cho đến khi ai đó nhận ra và khởi động lại cái kia.

Chuyển nhóm sang health check của load balancer nghe có vẻ là cách sửa hiển nhiên, nhưng với chúng tôi nó không đơn giản: trong lúc triển khai, máy chủ cố ý trả về lỗi trên endpoint health để balancer rút chúng khỏi luồng (xem cách chúng tôi đưa triển khai về không có 502). Một nhóm thay thế máy chủ theo tín hiệu đó sẽ thay thế chúng ngay giữa mỗi lần triển khai.

Vì vậy hiện tại chúng tôi thêm một bước vào danh sách kiểm tra triển khai: sau mỗi lần triển khai, kiểm tra tình trạng của từng mục tiêu trên load balancer, không chỉ xem tác vụ triển khai có qua hay không. Nếu lệnh gửi đến một máy chủ nằm ở “Pending”, máy đó đang thrashing — khởi động lại nó; nó đã nằm ngoài luồng rồi.

Chúng tôi rút ra gì

  • “Không crash” không có nghĩa là “khỏe mạnh”. Thrashing không tạo ra lỗi nào, chỉ có sự chậm chạp cực độ đến mức máy ngừng phản hồi.
  • Máy chủ nhỏ cần swap. Ngay cả một chút, với swappiness thấp, cũng cho kernel một chỗ để đặt bộ nhớ nguội.
  • Các giới hạn bộ nhớ cộng lại nhiều hơn máy có là một canh bạc. Đôi khi bạn thua. Hãy biết lúc nào bạn đang đặt cược.
  • Biết health check nào mà autoscaling của bạn tin tưởng. Một health check chỉ hỏi “VM có bật không?” sẽ không thay thế một máy chủ đã ngừng hoạt động.

Mythex · Pricing · Xây dựng mọi thứ với AI · Mẫu website và ứng dụng · So sánh Mythex · Thuật ngữ xây dựng ứng dụng bằng AI · Công cụ miễn phí để xây dựng ứng dụng bằng AI · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو 简体中文 繁體中文(香港) 繁體中文(台灣)