Các nhà phát triển thường phải chứng kiến ứng dụng vừa mới ra mắt của mình bị đình trệ ngay khi có vài nghìn người dùng nhấn "bắt đầu", và sự chậm trễ này hiếm khi là do lỗi mã nguồn – đó là do CPU và RAM của máy chủ đang phải tranh giành tài nguyên. Nút thắt cổ chai này biểu hiện qua việc tải trang lâu hơn, hết thời gian chờ (time-out) hoặc sập hoàn toàn, gây ảnh hưởng đến trải nghiệm người dùng, doanh thu và niềm tin vào thương hiệu.
Tại sao một máy chủ chạy tốt trong phòng thí nghiệm có thể bị đình trệ khi chạy thực tế
Trong quá trình phát triển, một lập trình viên duy nhất chỉ gửi một vài yêu cầu, vì vậy tài nguyên máy chủ hầu như luôn ở trạng thái rảnh rỗi. Khi ứng dụng chính thức hoạt động, mỗi khách truy cập sẽ tạo ra một yêu cầu cần đến hai thành phần cốt lõi:
- CPU (central processing unit) – bộ vi xử lý chạy mọi vòng lặp, hàm và phép tính. Hãy coi nó như một đầu bếp chỉ có thể chuẩn bị một số lượng món ăn nhất định cùng một lúc. Một đơn hàng được phục vụ ngay lập tức; nhưng một trăm đơn hàng có nghĩa là đầu bếp vẫn làm việc với tốc độ đó, nhưng thực khách sẽ phải chờ lâu hơn.
- RAM (random-access memory) – bộ nhớ tạm thời cho dữ liệu mà CPU cần khi xử lý một yêu cầu. Nó giống như một chiếc bàn nơi đầu bếp để các nguyên liệu cho mỗi món ăn. Nếu bàn đã đầy, đầu bếp phải ngừng nhận đơn hàng mới cho đến khi có chỗ trống.
Khi hàng nghìn người dùng đăng nhập cùng lúc, mỗi yêu cầu sẽ chiếm một phần thời gian CPU và một phần RAM riêng. Nguồn tài nguyên hữu hạn của máy chủ bị chia nhỏ cho các yêu cầu, và hàng đợi sẽ dài dần ra. Bản thân máy chủ không hề chậm đi; chỉ là thời gian chờ cho mỗi yêu cầu đã tăng lên.
Sự cám dỗ của việc "chỉ cần mua một chiếc máy lớn hơn"
Phản ứng đầu tiên phổ biến là nâng cấp máy móc – một phương pháp được gọi là mở rộng theo chiều dọc (vertical scaling). Việc thêm nhiều lõi CPU hơn hoặc nhiều RAM hơn sẽ cải thiện dung lượng: chuyển từ 4 lõi lên 16 lõi, hoặc từ 8 GB lên 64 GB có thể hấp thụ lượng truy cập tăng đột biến lớn hơn mà không cần thay đổi bất kỳ dòng mã nào.
Tuy nhiên, mở rộng theo chiều dọc sẽ chạm tới một giới hạn cứng:
- Giới hạn vật lý – mỗi bo mạch chủ chỉ có thể chứa một số lượng lõi nhất định và một lượng bộ nhớ hữu hạn.
- Hiệu suất giảm dần – mỗi lõi hoặc mỗi gigabyte tăng thêm đều có giá đắt hơn phần trước đó, trong khi mức tăng hiệu suất lại giảm dần.
- Điểm lỗi duy nhất (Single point of failure) – nếu máy chủ khổng lồ đó gặp sự cố, toàn bộ dịch vụ sẽ biến mất.
Vì những hạn chế này, các ông lớn trong ngành – các nền tảng phát trực tuyến, công cụ tìm kiếm, các trang thương mại điện tử – đã dần từ bỏ việc sử dụng một cỗ máy khổng lồ duy nhất.
Giải pháp thay thế: phân tán tải trọng trên nhiều máy nhỏ hơn
Thay vì xây dựng một tòa tháp cao hơn, các nhà vận hành sẽ thêm nhiều máy chủ có kích thước vừa phải và để chúng chia sẻ lưu lượng truy cập. Cách tiếp cận mở rộng theo chiều ngang (horizontal scaling) này giữ cho mỗi máy nằm trong phạm vi hiệu suất thoải mái và tránh được đường cong chi phí tăng theo cấp số nhân của việc nâng cấp theo chiều dọc.
Việc điều phối nhiều máy đòi hỏi một bộ cân bằng tải (load balancer) – một phần mềm hoặc phần cứng tiếp nhận mọi yêu cầu đến và chuyển tiếp nó đến máy chủ có dung lượng trống lớn nhất. Bộ cân bằng tải che giấu sự phức tạp đối với phía máy khách; từ góc nhìn của người dùng, trang web vẫn trông như một điểm cuối (endpoint) duy nhất.
Mở rộng theo chiều ngang cũng mang lại khả năng phục hồi. Nếu một nút (node) bị sập, bộ cân bằng tải sẽ đơn giản là chuyển hướng lưu lượng truy cập sang các nút khỏe mạnh còn lại, giúp dịch vụ luôn duy trì hoạt động.
Những điều cần lưu ý khi bạn bắt đầu thêm máy chủ
- Thiết kế không lưu trạng thái (Stateless design) – các yêu cầu không nên phụ thuộc vào dữ liệu chỉ được lưu trữ trong bộ nhớ của một máy chủ cụ thể; nếu không, người dùng có thể bị chuyển sang một nút thiếu ngữ cảnh cần thiết. Sử dụng bộ nhớ đệm (cache) dùng chung hoặc cơ sở dữ liệu sẽ giải quyết vấn đề này.
- Kiểm tra sức khỏe (Health checks) – bộ cân bằng tải phải có khả năng phát hiện nhanh chóng một máy chủ đang gặp lỗi và ngừng gửi lưu lượng truy cập đến đó.
- Chính sách tự động mở rộng (Auto-scaling policies) – nhiều nền tảng đám mây cho phép bạn xác định các ngưỡng (mức sử dụng CPU, độ trễ yêu cầu) để tự động khởi tạo hoặc tắt các instance, giúp chi phí luôn bám sát nhu cầu thực tế.
Quan điểm ngược lại: mở rộng theo chiều dọc không hề lỗi thời
Đối với các nhóm nhỏ hoặc các ứng dụng có lưu lượng truy cập thấp, một máy chủ duy nhất được nâng cấp mạnh mẽ có thể là giải pháp đơn giản và rẻ nhất. Nếu sự tăng đột biến về lưu lượng có thể dự đoán được (ví dụ: một đợt ra mắt sản phẩm theo kế hoạch), việc nâng cấp theo chiều dọc tạm thời có thể thực tế hơn là việc thiết lập cả một đội ngũ các instance mới.
Chìa khóa là phải nhận ra khi nào mẹo "chiếc máy lớn hơn" không còn mang lại giá trị tương xứng và bắt đầu lập kế hoạch cho việc phân tán.
Bài học rút ra
Tình trạng máy chủ bị chậm sau khi ra mắt thường là vấn đề tranh chấp tài nguyên, chứ không phải lỗi mã nguồn. Chu kỳ CPU và dung lượng RAM là hữu hạn, và khi có nhiều yêu cầu cùng đến một lúc, chúng sẽ phải xếp hàng chờ, làm kéo dài thời gian phản hồi. Mở rộng theo chiều dọc (Vertical scaling) giúp bạn có thêm một chút dư địa nhưng sẽ sớm chạm tới các giới hạn về vật lý và kinh tế. Mở rộng theo chiều ngang (Horizontal scaling) — thêm các máy chủ cấu hình vừa phải phía sau một bộ cân bằng tải (load balancer) — mang lại một lộ trình rẻ hơn và linh hoạt hơn khi lưu lượng truy cập tăng lên. Ngay khi bạn nhận thấy hàng đợi đang dài dần ra, đó là lúc cần đánh giá xem liệu việc thêm một vài lõi (core) nữa có đủ hay bạn nên bắt đầu phân tán tải trọng trên nhiều máy khác nhau.
Nguồn: bài viết trên dev.to “Why Servers Slow Down – CPU, RAM and the hidden cost of every request.”
