Nội dung trên trang web này đã được dịch bằng trí tuệ nhân tạo (AI) hoặc công nghệ dịch máy và có thể có lỗi.

Skip to content

Cách bộ nhớ đệm của Roblox duy trì 1,38 tỷ QPS vượt qua giới hạn của Redis

Đối phó với lượng truy cập tăng gấp 10 lần với sự tin cậy và hiệu quả là ưu tiên hàng đầu

Trong môi trường trò chơi đa người chơi quy mô lớn của Roblox, người dùng đọc và ghi dữ liệu với khối lượng và tốc độ lớn đến mức có thể làm sập các mô hình lưu trữ tạm thời tiêu chuẩn. Người dùng có thể không nhận thấy độ trễ 200 mili giây trên một trang web tiêu chuẩn lưu trữ dữ liệu tĩnh, nhưng độ trễ 200 mili giây trong việc truy xuất dữ liệu tương tác hoặc siêu dữ liệu máy chủ trên Roblox có thể làm gián đoạn trò chơi và phá vỡ thế giới trò chơi mô phỏng. Roblox hoạt động trên một hệ sinh thái dữ liệu khó dự đoán, tốc độ cao và ngắn ngủi, phải được truy xuất trong vòng vài mili giây để duy trì sự đắm chìm. 

Lớp bộ nhớ đệm của chúng tôi được thiết kế để hoạt động như một bộ giảm xóc khổng lồ giữa hàng triệu người dùng đồng thời và hệ thống lưu trữ bền vững. Nó xử lý tải đỉnh lên đến 1,38 tỷ truy vấn mỗi giây (QPS), với các cụm logic đơn lẻ đạt trên 100 triệu QPS. Trong bài viết này, chúng tôi sẽ tiết lộ cách chúng tôi thiết kế dịch vụ bộ nhớ đệm liên kết để mở rộng quy mô vượt quá giới hạn nút Redis® nhằm đạt được thông lượng khổng lồ, đồng thời đối phó với sự gia tăng lưu lượng truy cập gấp 10 lần chưa từng có trên cụm lớn nhất của chúng tôi.

Tổng số lần đọc/ghi bộ nhớ đệm trên tất cả các nút bộ nhớ đệm.

Mở rộng quy mô vượt qua giới hạn ngành để đáp ứng nhu cầu ngày càng tăng

Tại Roblox, dịch vụ bộ nhớ đệm của chúng tôi được xây dựng dựa trên công nghệ Redis®, và một cụm Redis® có khả năng hỗ trợ lên đến 1.000 nút. Tuy nhiên, giới hạn thực tế và được ngành công nghiệp chấp nhận lại thấp hơn nhiều — khoảng 400–500 nút.1 Điều này là do giao thức Gossip phi tập trung của Redis®, sử dụng giao tiếp giữa các nút để chia sẻ thông tin về tình trạng, trạng thái và bản đồ phân mảnh. Trong các cụm có hơn vài trăm nút, hoạt động giao tiếp từ giao thức Gossip bắt đầu tiêu tốn lượng lớn tài nguyên CPU và mạng. Mỗi nút phải xử lý các bản cập nhật trạng thái từ số lượng đối tác ngày càng tăng, làm cạn kiệt tài nguyên dành cho nhiệm vụ chính là cung cấp dữ liệu với độ trễ thấp. Chi phí quản lý này có thể dẫn đến sự không ổn định và hiệu suất không thể dự đoán được, đó là lý do tại sao các nhà cung cấp đám mây quản lý áp đặt giới hạn số nút. Đây là một giới hạn thực tế không thể vượt qua mà không làm ảnh hưởng đến độ tin cậy.

Giới hạn cụm đơn lẻ thực tế này không đủ để hỗ trợ một nền tảng hoạt động ở quy mô của Roblox, nơi dịch vụ backend lớn nhất yêu cầu hơn 100 triệu QPS từ một trong các cụm Redis® logic của chúng tôi vào giờ cao điểm, tăng từ 10 triệu chỉ trong ba tháng.

Chúng tôi đã áp dụng kiến trúc liên kết để khắc phục hạn chế kiến trúc này, đặt một proxy ngược phía khách hàng trước nhiều cụm Redis® nhỏ hơn và độc lập. Chúng tôi áp dụng giới hạn 400 nút cho mỗi cụm để đảm bảo hiệu suất dự đoán được. 

Từ góc độ của hàng nghìn ứng dụng và dịch vụ của chúng tôi, proxy ngược phía client trình bày các cụm phân tán này như một dịch vụ lưu trữ cache duy nhất, thống nhất và có khả năng mở rộng. Liên minh này cho phép chúng tôi mở rộng theo chiều ngang gần như không giới hạn bằng cách đơn giản là thêm các cụm mới vào liên minh, hoàn toàn bỏ qua các hạn chế của giao thức Gossip. Hiện nay, triển khai bộ nhớ đệm đơn lẻ lớn nhất của chúng tôi bao gồm hơn 6.000 nút Redis®, được hỗ trợ bởi hơn 15 cụm Redis® độc lập — quy mô này chỉ có thể đạt được nhờ mô hình liên kết này.

Sơ đồ tổng quan về kiến trúc liên kết.

Quy trình di chuyển ba giai đoạn

Việc chuyển từ cấu hình truyền thống sang kiến trúc liên kết trong khi quản lý hàng trăm cụm sản xuất đang hoạt động là một công việc rất lớn. Vào cuối năm 2024, nhiều cụm trong số này đã gần đạt đến giới hạn 400 nút của chúng tôi, khiến việc chuyển đổi sang mô hình có dung lượng cao hơn trở nên cấp bách. Thách thức chính là các phiên bản Redis® tiêu chuẩn hoạt động riêng lẻ và không có nhận thức cố hữu về các cụm khác, do đó cần phải có một phương pháp tùy chỉnh để sao chép dữ liệu trong quá trình di chuyển.

Để giải quyết vấn đề này, chúng tôi đã phát triển một quy trình di chuyển ba giai đoạn minh bạch, được thiết kế để chuyển đổi các dịch vụ mà không cần sự tham gia của khách hàng hoặc thay đổi từ phía ứng dụng.

Quy trình di chuyển

  1. Ghi kép: Chúng tôi đã cấu hình proxy ngược của máy khách để thực hiện ghi kép, gửi dữ liệu đến cả cụm ban đầu và đích liên kết mới đồng thời.
  2. Đồng bộ hóa và chuyển đổi đọc: Khi quá trình ghi kép đã điền đầy đủ dữ liệu giống hệt nhau vào cụm mới, vì tất cả dữ liệu đều bị giới hạn bởi thời gian tồn tại (TTL), chúng tôi đã chuyển lưu lượng truy cập đọc từ cụm cũ sang kiến trúc liên kết mới.
  3. Ngừng hoạt động: Sau khi xác nhận tính ổn định của cụm mới, chúng tôi đã ngừng tất cả các hoạt động ghi vào cụm ban đầu và ngừng sử dụng nó.

Chúng tôi đã chuyển thành công các dịch vụ quan trọng nhất của mình sang mô hình liên kết hỗ trợ hơn 6.000 nút, vượt xa giới hạn của một cụm Redis® đơn lẻ. 

Xử lý sự tăng trưởng bùng nổ của Grow a Garden

Từ tháng 4 năm 2025, chúng tôi phải đối mặt với thách thức về dung lượng ở mức độ mà ít dịch vụ nào từng gặp phải. Nguyên nhân là do thành công phi thường của Grow a Garden. Chỉ trong vài tuần sau khi ra mắt, Grow a Garden đã phá vỡ không chỉ kỷ lục của Roblox mà còn cả kỷ lục mọi thời đại của ngành game về số người dùng đồng thời (CCU). Chỉ trong ba tháng, lượng người chơi của trò chơi đã vượt qua kỷ lục CCU trước đó của chúng tôi là 2,8 triệu người chơi, đạt đỉnh điểm hơn 21 triệu người. Sự tăng trưởng bùng nổ này đã đẩy lưu lượng truy cập vào cụm Redis® lớn nhất của chúng tôi tăng gấp 10 lần và lưu lượng truy cập vào hệ thống bộ nhớ đệm tổng thể tăng gấp 3 lần.

Roblox vận hành các hệ thống bộ nhớ đệm trên các máy vật lý tại các trung tâm dữ liệu của riêng mình, và sự tăng trưởng chưa từng có này không nằm trong kế hoạch năng lực dài hạn của chúng tôi. Để vượt qua làn sóng này và duy trì sự ổn định của nền tảng, chúng tôi phải cải thiện đáng kể hiệu quả của hệ thống hiện có đồng thời ưu tiên tính ổn định. 

Nâng cao hiệu quả trong thời gian tăng đột biến

Đầu tiên, chúng tôi cần xác định các điểm nghẽn có tác động lớn nhất trong hệ thống để ưu tiên công việc tối ưu hóa. Hệ thống bộ nhớ đệm Roblox chạy trên hai nhóm phần cứng khác nhau: một dành cho các nút backend Redis® và một dành cho Envoy. Đội máy chủ Redis® của chúng tôi chủ yếu bị giới hạn bởi bộ nhớ, trong khi proxy khách hàng bị giới hạn bởi sức mạnh tính toán. 

Đối với đội máy chủ Redis® bị giới hạn bởi bộ nhớ, chúng tôi đã triển khai một chính sách lập lịch mới để cân bằng tốt hơn việc sử dụng bộ nhớ trên các nhóm máy vật lý của chúng tôi. Chúng tôi cũng đã tinh chỉnh kích thước container để giảm sự phân mảnh bộ nhớ. 

Để cải thiện mức sử dụng CPU, chúng tôi đã triển khai hai tối ưu hóa chính cho hệ thống bộ nhớ đệm của mình:

  1. Tự động điều chỉnh quy mô proxy khách hàng: Chúng tôi đã điều chỉnh chính sách tự động điều chỉnh quy mô cho đội proxy khách hàng bị giới hạn bởi khả năng tính toán. Bằng cách giảm độ lệch cho phép so với CPU mục tiêu, chúng tôi đã đạt được mức sử dụng CPU trung bình cao hơn cho các công việc mà không cần thay đổi ngưỡng mở rộng quy mô.
  2. Kiểm tra tình trạng cụm nội bộ: Chúng tôi đã tối ưu hóa các kiểm tra tình trạng nội bộ để loại bỏ các tín hiệu kiểm tra không cần thiết, đồng thời giữ nguyên khoảng thời gian phát hiện ban đầu và tiết kiệm tài nguyên tính toán.

Những thay đổi này đã giúp cải thiện gần 10% mức sử dụng CPU. Cuối cùng, chúng tôi đã đặt hai khối lượng công việc rất khác nhau này vào cùng một nhóm máy với tính năng cách ly cấp độ container cgroup, giúp giảm 25% nhu cầu dung lượng tổng thể của chúng tôi.

Kỹ thuật để đảm bảo độ tin cậy vững chắc

Độ tin cậy vẫn là ưu tiên hàng đầu của chúng tôi, ngay cả khi chúng tôi phải chạy đua để đáp ứng nhu cầu kỷ lục. 

Khả năng quan sát từ đầu đến cuối

Chúng tôi tập trung vào việc hiểu rõ các sự cố tiềm ẩn bằng cách đầu tư mạnh mẽ vào hệ thống quan sát để theo dõi toàn diện tình trạng hoạt động của hệ thống bộ nhớ đệm từ đầu đến cuối. Bằng cách theo dõi thành công của máy chủ và các sự cố phía client trong suốt vòng đời yêu cầu, chúng tôi nhanh chóng phát hiện và chẩn đoán vấn đề, thường ngăn chặn tác động đến người dùng trước khi nó xảy ra. Ví dụ: chúng tôi đã thêm tính năng phát hiện khóa nóng, lấy mẫu lưu lượng truy cập trực tiếp để xác định dữ liệu bị truy cập quá mức và gây áp lực lên lớp bộ nhớ đệm. Khi hệ thống báo hiệu một khóa nóng, chúng tôi có thể chủ động hạn chế lưu lượng truy cập vào các khóa này ở cả phía máy chủ và phía khách hàng để ngăn chặn tình trạng quá tải hệ thống.

Xử lý sự cố

Trong bất kỳ hệ thống phân tán nào ở quy mô này, đôi khi sẽ xảy ra các sự cố một phần. Chúng tôi đã thiết kế hệ thống để xử lý các sự cố này một cách trơn tru và giảm thiểu tác động của chúng.

  • Lỗi một phần trong các yêu cầu theo lô: Chúng tôi đã tái kiến trúc hệ thống để xử lý các lỗi một phần trong các yêu cầu theo lô. Trước đây, một lỗi duy nhất trong một yêu cầu theo lô được phân mảnh sẽ khiến toàn bộ lô bị lỗi. Giờ đây, các yêu cầu vẫn có thể thành công ngay cả khi một số khóa không thể truy xuất được.
  • Giảm thiểu hiện tượng chặn đầu hàng (head-of-line blocking): Hệ thống bộ nhớ đệm được kỳ vọng phải hoạt động nhanh chóng. Ngay cả sự chậm trễ mạng nhỏ cũng có thể khiến các yêu cầu ứ đọng và hết thời gian chờ, hiện tượng này được gọi là chặn đầu hàng. Chúng tôi đã triển khai các cơ chế thử lại thông minh và chiến lược quản lý kết nối trong cả lớp client và proxy để ngăn chặn một yêu cầu chậm ảnh hưởng đến các yêu cầu khác.
  • Tiêm lỗi và độ trễ: Để kiểm tra khả năng phục hồi, chúng tôi thường xuyên tiêm các lỗi có kiểm soát (mất kết nối nút, mất kết nối giá đỡ, độ trễ mạng, lỗi API) vào môi trường sản xuất bằng cách sử dụng khung tiêm lỗi của chúng tôi. Bằng cách phân tích hành vi của hệ thống trong các điều kiện này, chúng tôi chủ động xác định và khắc phục các điểm yếu, đảm bảo độ tin cậy liên tục.

Khả năng phục hồi phía máy khách

Để ngăn hệ thống bộ nhớ đệm của chúng tôi bị quá tải do sự gia tăng đột ngột của lưu lượng truy cập, chúng tôi đã triển khai khả năng phục hồi lỗi phía client mạnh mẽ. Cơ chế này hoạt động ở cấp độ ứng dụng, đảm bảo rằng không có dịch vụ nào có thể chiếm dụng tài nguyên bộ nhớ đệm.

  • Giới hạn tốc độ để kiểm soát lưu lượng: Ứng dụng khách của chúng tôi có giới hạn về tổng lưu lượng đi ra, đảm bảo rằng nó không gửi nhiều yêu cầu hơn khả năng xử lý của dịch vụ phía sau. Các yêu cầu sẽ bị giới hạn tốc độ khi vượt quá giới hạn này, giúp dịch vụ không bị quá tải.
  • Cơ chế thử lại và thời gian chờ: Các thư viện khách hàng của chúng tôi sử dụng các cơ chế thử lại được điều chỉnh cẩn thận, bao gồm thời gian chờ và ngân sách thử lại, để ngăn chặn các vấn đề về "thundering herd". Điều này hạn chế phạm vi ảnh hưởng, giải phóng tài nguyên và cải thiện khả năng phản hồi tổng thể của hệ thống bằng cách ngăn chặn các tình trạng treo vô thời hạn và các lần thử lại đồng thời làm quá tải hệ thống.

Tương lai của bộ nhớ đệm Roblox

Hành trình lưu trữ của Roblox bắt đầu với các cụm Redis® bare-metal được quản lý trực tiếp bởi từng chủ sở hữu ứng dụng, sau đó chuyển sang các cụm Memcached do nhóm lưu trữ của chúng tôi quản lý, và cuối cùng chuyển sang mô hình Redis®-as-a-service, trong đó cụm Redis® được cung cấp dưới dạng dịch vụ được quản lý. Mặc dù mô hình này đã chứng tỏ hiệu quả cao ở quy mô hiện tại của chúng tôi, chúng tôi nhận ra những hạn chế của nó về hiệu quả dịch vụ và cách ly tài nguyên đối với một nền tảng năng động như Roblox.

Khi nền tảng tiếp tục phát triển, chúng tôi dự định đầu tư đáng kể vào một dịch vụ lưu trữ đa người dùng thế hệ mới được xây dựng trên ValKey. Kiến trúc này được thiết kế để giảm đáng kể chi phí bằng cách chia sẻ các tài nguyên chung thông qua tính năng đa người dùng, đồng thời đảm bảo sự cách ly dữ liệu, tài nguyên và sự cố cho từng người dùng. Mục tiêu của chúng tôi là nâng cao đáng kể hiệu suất, khả năng mở rộng, độ tin cậy và hiệu quả chi phí của cơ sở hạ tầng lưu trữ để đáp ứng nhu cầu ngày càng lớn về trải nghiệm trên Roblox.

Lời cảm ơn: 

Thành tựu này là kết quả của sự hợp tác. Xin cảm ơn các thành viên khác trong nhóm đã đóng góp đáng kể: Utkarsh Singh, Karthick Ramachandran, Vineesha Kasireddy, Weiji Hu và Leon Gao.

1AWS giới hạn ElasticCache ở 500 nút.

*Redis là nhãn hiệu của Redis Labs Ltd. Mọi quyền liên quan đều thuộc về Redis Labs Ltd.