Hosting Minecraft 10 phút đọc

Tăng trưởng nóng: Khi nào VPS không đủ và cần Dedicated hay Hybrid Cloud?

Tăng trưởng nóng: Khi nào VPS không đủ và cần Dedicated hay Hybrid Cloud?

Hồi mình mới tập tọe vận hành server game Minecraft. Hồi đó cũng chỉ thuê cái VPS cùi bắp thôi. Ấy vậy mà, tự nhiên có một dạo, server game đông khách bất thường. Thằng bạn mình rủ rê thêm nhiều người vào chơi chế độ mới. Ban đầu thì vui lắm, server có sức sống hẳn, nhưng rồi... đến giờ cao điểm, server bắt đầu lag kinh khủng. Thậm chí nhiều lúc, mình còn không vào được game, rồi hiện cái lỗi khó chịu:

504 Gateway Time-out

Mình hoảng hồn, cứ nghĩ là do VPS quá yếu. Lúc đó mình chỉ biết mỗi cách là nâng gói VPS lên cao hơn. Nhưng không phải lúc nào giải pháp này cũng hiệu quả đâu. Sau này mình mới biết, "tăng trưởng nóng" không chỉ là chuyện mua thêm cấu hình, mà nó còn cả một hành trình tối ưu và thay đổi kiến trúc hạ tầng.

Một số lỗi không vào được VPS và cách khắc phục

Khi nào VPS "đuối"? Dấu hiệu không thể bỏ qua

Một ngày đẹp trời, bạn thấy server mình tự nhiên chậm rì. Người dùng bắt đầu kêu ca. Có thể là website load mãi không xong, hoặc game server lag đến mức không chơi được. Đó là lúc bạn cần nhìn vào các chỉ số. Đừng có đợi đến khi người dùng than phiền mới tá hỏa đi tìm nguyên nhân.

CPU bị MariaDB/MySQL chiếm dụng cao ngất

Đây là dấu hiệu rõ ràng nhất mình từng gặp. Hồi server game của mình bị 504, mình tá hỏa đăng nhập vào SSH, gõ lệnh top để kiểm tra. Kết quả là:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
...    
mysql     20   0 13.5g 1.1g 1.2g R 397.0   7.1  1328:45 mariadbd

Quá bất ngờ, MariaDB/MySQL chiếm tới gần 400% CPU! (Mình đọc trên forum Virtualmin cũng có một bạn mới dùng VPS gặp y chang tình trạng này). VPS của mình có 8 core CPU, tức là một tiến trình mà đã chiếm gần hết sức mạnh của 4 core rồi. Lúc này, dù VPS có 8 core, nhưng nếu MySQL "ăn" hết như vậy thì các tiến trình khác lấy đâu ra mà chạy nữa?

Mình đọc thêm một case study trên The Cloud Standard về một ứng dụng SaaS phân tích B2B, họ cũng gặp tình trạng tương tự: CPU của database duy trì 85-95% trong giờ làm việc. Đây là dấu hiệu rõ ràng cho thấy database đang là nút thắt cổ chai.

Thời gian phản hồi truy vấn (Query Response Time) vọt

Cũng từ case study đó, họ ghi nhận thời gian phản hồi truy vấn database tăng từ mức nền 45-120ms lên đến 1,200-3,500ms. Nghĩa là mỗi lần ứng dụng hỏi database, nó phải chờ 1-3 giây rưỡi mới có câu trả lời. Thử tưởng tượng một người dùng phải chờ từng đó thời gian cho mỗi cú click chuột thì họ bỏ đi là phải.

Tắc nghẽn kết nối và deadlocks

Khi quá nhiều yêu cầu đổ về cùng lúc, database không kịp xử lý, nó sẽ dẫn đến tắc nghẽn connection pool (15-40 sự kiện/ngày) và thậm chí là deadlock (3-8 sự kiện/tuần). Connection pool giống như số ghế trong một nhà hàng vậy, hết ghế thì khách phải đứng chờ. Còn deadlock thì tệ hơn, nó giống như hai khách giành nhau một món ăn, chẳng ai ăn được gì cả.

Đừng vội đổ lỗi cho phần cứng: Tối ưu phần mềm trước đã

Nói thật: nhiều anh em mới làm vận hành hay bị tâm lý "mua cái mới là xong". Đừng! Đừng có phức tạp hóa. Việc nâng cấu hình chỉ là giải pháp tình thế, hoặc tệ hơn là lãng phí tiền bạc nếu nguyên nhân gốc rễ nằm ở phần mềm.

Web server và caching

Hồi đó mình chỉ dùng mỗi Apache, không tối ưu gì cả. Nhưng sau này, mình đọc trên forumweb.hosting một anh có VPS 8 core, 16GB RAM vẫn gặp 504. Các cao thủ khuyên anh ấy nên chuyển từ Apache sang Nginx hoặc LiteSpeed. Hai thằng này nhẹ hơn, xử lý static content nhanh hơn rất nhiều.

Rồi còn caching nữa. Đừng chỉ dựa vào Cloudflare. Đó là CDN cho người dùng cuối. Bạn phải có cache ở phía server (server-side caching) nữa. Ví dụ như dùng Redis để cache những dữ liệu hay được truy cập. Cái này thực sự cứu cánh cho server game của mình, giảm tải cho database rất nhiều.

Khoan sâu: Tối ưu MariaDB/MySQL – "Trái tim" của server

Nếu CPU của MariaDB/MySQL lên cao "bất thường" như 397% CPU mà mình đã thấy, thì đây chính là nơi bạn cần "phẫu thuật" để cứu vãn tình hình. Mình sẽ chia sẻ 1-2 điểm mà dân vận hành lâu năm hay dùng, không phải định nghĩa sách vở mà là cách bạn tự tay kiểm tra và điều chỉnh.

Giải mã MariaDB - Giải pháp quản lý dữ liệu hiệu quả hàng đầu

Kích thước buffer pool (innodb_buffer_pool_size)

Cái này giống như bộ nhớ đệm cho database vậy. Dữ liệu hay được truy cập sẽ nằm trong RAM thay vì phải đọc từ ổ đĩa chậm hơn. Mình đọc được một bài rất hay trên mydbops.com, họ nói rằng trên một dedicated MySQL server, innodb_buffer_pool_size nên được đặt khoảng 70-80% tổng RAM. Nếu bạn có 16GB RAM cho database, hãy thử đặt khoảng 11-12GB cho cái này. Để kiểm tra hiệu quả, bạn có thể chạy lệnh SQL này:

SELECT (1 - ((SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_reads') / (SELECT variable_value FROM performance_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_read_requests'))) * 100 AS hit_rate_pct;

Nếu hit_rate_pct mà dưới 95%, thì buffer pool của bạn có thể đang quá nhỏ đấy.

Kiểm soát ghi dữ liệu (innodb_flush_log_at_trx_commit)

Tham số này quyết định tần suất MySQL ghi dữ liệu từ bộ nhớ xuống ổ đĩa. Nó ảnh hưởng trực tiếp đến hiệu suất ghi và độ an toàn của dữ liệu:

  • 1: Ghi và đồng bộ xuống ổ đĩa ngay lập tức sau mỗi commit. Siêu an toàn (chuẩn ACID), nhưng rất chậm, đặc biệt với ổ đĩa cũ hoặc nhiều giao dịch ghi. Phù hợp cho ngân hàng, thương mại điện tử cần độ chính xác tuyệt đối.
  • 2: Ghi vào cache của hệ điều hành sau mỗi commit, và đồng bộ xuống ổ đĩa mỗi giây một lần. Nhanh hơn nhiều, nhưng nếu server bị sập nguồn/OS crash trong 1 giây đó thì có thể mất tối đa 1 giây dữ liệu. Mình đọc được là việc chuyển từ 1 sang 2 có thể giúp tăng hiệu suất ghi 2-5 lần trên các hệ thống dùng ổ HDD hoặc SSD cũ.
  • 0: Ghi vào cache của OS và đồng bộ xuống ổ đĩa mỗi giây một lần. Tương tự 2 nhưng có thể mất dữ liệu nếu MySQL crash. Rất nhanh, nhưng chỉ dùng cho dev/staging hoặc các hệ thống không quá quan trọng dữ liệu.

Bạn phải hiểu rõ ứng dụng của mình để chọn giá trị phù hợp. Đôi khi, chấp nhận rủi ro mất 1 giây dữ liệu đổi lấy hiệu suất vượt trội lại là điều đáng giá cho các ứng dụng không quá khắt khe về ACID.

Tìm query "ác mộng" với slow query log và EXPLAIN

Một cái nhiều bạn hay quên... là bật slow_query_log. Khi bật cái này (và set long_query_time = 0.1 để log những query chạy quá 100ms), bạn sẽ thấy được những câu query nào đang "hành" database của mình. Sau đó, dùng EXPLAIN FORMAT=JSON để xem database nó chạy query đó như thế nào. Nếu thấy type: ALL trên một bảng lớn (hàng ngàn, hàng vạn dòng), thì đó là vấn đề nghiêm trọng: database đang phải quét toàn bộ bảng. Thêm index vào những cột quan trọng là giải pháp ở đây.

Khi nào thì "lên đời" là đúng?

Sau khi đã tối ưu "nát nước" phần mềm mà vẫn thấy các chỉ số như CPU database, response time không cải thiện, hoặc lượng người dùng, dữ liệu tăng trưởng vượt quá khả năng của một con VPS, đó là lúc bạn cần nghĩ đến việc "lên đời" sang Dedicated Server hay Hybrid Cloud.

Giới hạn của "phóng to" (Vertical Scaling)

"Phóng to" hay Vertical Scaling là việc bạn thêm CPU, RAM, ổ cứng cho một con server. Ban đầu thì hiệu quả đấy. Nhưng đến một ngưỡng nào đó, bạn có thêm RAM nữa, CPU nữa, nó cũng không giải quyết được vấn đề nữa rồi (mình đọc trên Unihost.com). Lúc đó bạn cần nghĩ đến "nhân bản" (Horizontal Scaling).

"Nhân bản" (Horizontal Scaling) và Hybrid Cloud

Horizontal Scaling là việc bạn thêm nhiều server nhỏ chạy song song nhau, đằng sau một cái Load Balancer. Cái này phức tạp hơn nhưng là kiến trúc của mọi hệ thống chịu tải cao. Mình đã thấy các case như trên The Cloud Standard, họ dùng VPS cho các application server không trạng thái (stateless), đặt sau một load balancer, còn database thì chuyển hẳn sang Dedicated Server. Đây chính là Hybrid Cloud ở dạng đơn giản nhất.

Database thường là nút thắt cổ chai lớn nhất. Vertical Scaling cho database thường hiệu quả hơn Horizontal Scaling ở giai đoạn đầu. Nhưng khi database dưới áp lực liên tục (hàng ngàn truy vấn/giây) và thời gian phản hồi là critical (latency trên 200-500ms là mất khách) thì cần giải pháp mạnh hơn.

Chuẩn bị cho tương lai lớn hơn: Từ VPS lên Dedicated / Hybrid Cloud

Việc chuyển đổi không chỉ là chuyển files từ máy này sang máy kia. Đó là cả một chiến lược.

Hybrid Cloud là gì? Ưu, nhược điểm và lợi ích của Hybrid Cloud

Load Balancer và Read Replicas

Khi bạn có nhiều application server (dù là VPS hay Dedicated), bạn cần một Load Balancer đứng đầu để phân phối traffic. Cái này giúp hệ thống ổn định và chịu tải tốt hơn.

Với database, khi quá nhiều truy vấn đọc (read) đổ về, bạn có thể tạo các "read replica" – những bản sao của database chính chỉ để xử lý các yêu cầu đọc. Mình đọc được một case study trên mydbops.com, với kiến trúc chính-phụ (Primary + Replica) qua ProxySQL, nếu có 2 Replica thì hệ thống có thể tăng khả năng xử lý lên tới 2.8 lần (ví dụ từ 3.000 TPS lên 8.400 TPS), còn với 4 Replica thì là 4.6 lần (lên 14.000 TPS) so với chỉ dùng Primary đơn. ProxySQL là một "cổng" rất hay, nó có thể chấp nhận tới 50.000+ kết nối client và điều phối chúng vào một pool chỉ 200-500 kết nối MySQL, giảm đáng kể gánh nặng kết nối.

Sharding: Giải pháp cuối cùng cho database khủng

Khi mà ngay cả việc tối ưu database, chia tách read/write, dùng read replica cũng không còn hiệu quả nữa, tức là database của bạn đã đạt đến ngưỡng xử lý 6.000-8.000 TPS ghi (write TPS) liên tục, thì bạn cần nghĩ đến Sharding. Cái này giống như chia nhỏ database ra thành nhiều "mảnh" và đặt trên nhiều server khác nhau. Nó phức tạp kinh khủng và gần như không thể đảo ngược nếu không có đội ngũ kỹ sư mạnh. Đây là giải pháp cho những hệ thống cực lớn, ví dụ như Vitess là một giải pháp sharding middleware cho MySQL đã được chứng minh với các tải ghi trên 10.000 TPS.

Kết: Câu chuyện của mình và lời khuyên

Quay lại với server game của mình, sau vụ "504 gateway time out" đó, mình không vội vã nâng cấp VPS nữa. Mình đã dành nguyên một đêm để mò mẫm tối ưu MariaDB theo những gì mình học được. Mình tinh chỉnh innodb_buffer_pool_size, thay đổi innodb_flush_log_at_trx_commit và đặc biệt là tìm ra một vài query "chết người" làm lag server rồi thêm index cho chúng. Server game của mình đã ổn định trở lại, và kéo dài thêm được cả tháng trời với lượng người chơi tăng đột biến mà không cần nâng cấp gì về phần cứng.

Nói thật: đừng vội chạy theo cấu hình khủng nếu bạn chưa khai thác hết tiềm năng của phần mềm. Hãy bắt đầu từ việc hiểu rõ server của mình đang "kêu" ở đâu, tối ưu những gì có thể, rồi mới tính đến chuyện "lên đời" Dedicated hay Hybrid Cloud. Nó không chỉ giúp bạn tiết kiệm chi phí mà còn giúp bạn trở thành một người vận hành cứng tay hơn nhiều.