28 điểm bởi GN⁺ 2025-05-05 | 4 bình luận | Chia sẻ qua WhatsApp
  • Discord đã thiết kế lại toàn bộ kiến trúc dựa trên Kubernetes để vượt qua các giới hạn của hạ tầng tìm kiếm dựa trên Elasticsearch trước đây, từ đó cải thiện mạnh mẽ hiệu năng và độ ổn định của việc lập chỉ mục tin nhắn
  • Hàng đợi Redis cũ có rủi ro làm mất tin nhắn, nhưng khi được thay bằng PubSub thì việc truyền tin nhắn ổn định được đảm bảo, đồng thời các tin nhắn được phân loại theo cụm/chỉ mục để xử lý hiệu quả
  • Áp dụng kiến trúc "cell", phân tán thành nhiều cụm Elasticsearch cỡ nhỏ, qua đó giải quyết vấn đề quá tải nút và không thể cập nhật
  • Tin nhắn DM cá nhân và tin nhắn máy chủ (guild) được lập chỉ mục vào các cell riêng biệt, trở thành nền tảng cho tính năng tìm kiếm toàn bộ DM mới được giới thiệu
  • Với các cộng đồng siêu lớn (BFGs), việc dùng cell chuyên dụng và chỉ mục đa shard giúp mở rộng vượt qua giới hạn số lượng tin nhắn tối đa của Lucene

Giới hạn của hạ tầng cũ

  • Hàng đợi tin nhắn dựa trên Redis gây nghẽn khi nút Elasticsearch gặp sự cố, và có khả năng làm mất tin nhắn
  • Các cụm quy mô lớn (hơn 200 nút) có tỷ lệ thất bại lập chỉ mục toàn hệ thống lên tới 40% chỉ vì một nút đơn lẻ gặp sự cố
  • Các chỉ mục chạm giới hạn MAX_DOCS của Lucene (2 tỷ tin nhắn) sẽ khiến việc lập chỉ mục dừng hoàn toàn
  • Do hệ thống đã cũ, ngay cả việc vá log4shell cũng chỉ có thể thực hiện sau khi đưa toàn bộ hệ thống offline

Chiến lược giải quyết

Xây dựng lại trên nền Kubernetes

  • Tận dụng Elastic Kubernetes Operator (ECK) để tự động hóa vận hành các cụm Elasticsearch
  • Có thể khởi động lại luân phiên, nâng cấp OS và phần mềm một cách an toàn

Phân tán cụm bằng kiến trúc “cell”

  • Thay vì một cụm đơn khổng lồ như trước, nhiều cụm nhỏ được ghép thành một cell
  • Trong mỗi cell, số lượng chỉ mục được giới hạn, và kích thước shard được giữ trong mức 50GB, tối đa 200 triệu tin nhắn
  • Cải thiện hiệu năng lập chỉ mục và truy vấn, đồng thời giảm gánh nặng duy trì trạng thái cụm

Hàng đợi tin nhắn dựa trên PubSub

  • Chuyển từ Redis → PubSub giúp duy trì hàng đợi mà không làm mất tin nhắn
  • Việc sử dụng PubSub cũng đang được mở rộng sang các chức năng khác (như lập lịch tác vụ)

Lập chỉ mục theo lô cho từng cụm

  • Các tin nhắn nhận từ PubSub được phân loại theo cụm và chỉ mục đích, rồi xử lý song song như các task riêng biệt
  • Cấu trúc phân tán xử lý tin nhắn được triển khai bằng tokio task + channel của Rust

Cải thiện chức năng tìm kiếm

Tìm kiếm DM theo người dùng

  • Trước đây, DM được lập chỉ mục theo từng kênh nên việc tìm kiếm toàn bộ DM rất kém hiệu quả
  • Giờ đây, tin nhắn DM được lập chỉ mục kép vào chỉ mục theo từng người dùng, cho phép tìm kiếm tất cả DM cùng lúc

Ứng phó với BFG (Big Freaking Guilds)

  • Chỉ mục đa shard được đưa vào để xử lý các cộng đồng siêu lớn vượt quá giới hạn số lượng tin nhắn của Lucene
  • BFG được xử lý bằng cấu trúc nhiều primary shard trong cell Elasticsearch chuyên dụng
  • Sau khi lập chỉ mục kép đồng thời vào chỉ mục cũ và chỉ mục mới, hệ thống sẽ dần chuyển đối tượng truy vấn sang chỉ mục mới

Kết quả

  • Lập chỉ mục hàng nghìn tỷ tin nhắn, với thông lượng lập chỉ mục gấp 2 lần so với trước
  • Tốc độ phản hồi truy vấn: trung bình 500ms → 100ms, p99 từ 1s → dưới 500ms
  • Đang vận hành hơn 40 cụm và hàng nghìn chỉ mục
  • Việc nâng cấp cụm và khởi động lại luân phiên đã được tự động hóa hoàn toàn mà không gây gián đoạn dịch vụ

4 bình luận

 
mhj5730 2025-05-08

Vừa vận hành vừa làm công việc đó... thật sự rất đáng nể.

 
ethanhur 2025-05-08

Kỹ thuật của Discord lúc nào cũng là hình mẫu. Thật đáng ghen tị.

 
jujumilk3 2025-05-07

Tôi cứ tưởng pubsub là gì đó, hóa ra là IaaS do GCP cung cấp.

https://cloud.google.com/pubsub?hl=en

 
mssmss 2025-05-05

Thật ấn tượng. Cả việc dám lật tung mọi thứ để giải quyết vấn đề nữa.