Sử dụng Redis để xây dựng bảng xếp hạng
Ngày cập nhật: 2018-10-12 | Số lần đọc: 16559 | Phân loại: Redis
Tìm kiếm
Việc thực hiện tính năng xếp hạng bằng MySQL thường rất khó khăn, vì bạn không thể dễ dàng lấy được vị trí (rank) của một người dùng hoặc một mục cụ thể. Bạn phải duyệt toàn bộ bảng dữ liệu mới có thể tìm ra thứ hạng mong muốn.
Trong khi đó, Redis với cấu trúc Sorted Set lại cung cấp một cách tiếp cận hiệu quả và linh hoạt hơn rất nhiều để xử lý các bảng xếp hạng phức tạp.
Trong Sorted Sets, điểm số (score) của từng phần tử có thể được cập nhật bất kỳ lúc nào. Chỉ cần gọi lệnh ZADD với một phần tử đã tồn tại trong tập hợp, điểm số cũng như vị trí của nó sẽ được điều chỉnh với độ phức tạp là O(log(N)).
Thêm dữ liệu vào bảng xếp hạng
|
|
Ví dụ tương ứng trong Laravel:
|
|
Lấy vị trí của một phần tử
|
|
Thứ tự mặc định
zrange
trả về kết quả theo thứ tự tăng dần.- Nếu bạn muốn lấy danh sách theo thứ tự giảm dần, hãy sử dụng
zrevrange
.
Lưu ý về phân trang
Khác với MySQL, trong Redis, tham số thứ hai của lệnh zrange
là chỉ số cuối cùng (inclusive), chứ không phải là số lượng bản ghi muốn lấy.
Ví dụ: zrange 'teams_rank' 0 4
sẽ trả về 5 phần tử đầu tiên (từ 0 đến 4).
Giả sử bạn muốn lấy 5 đội hàng đầu:
|
|
Định dạng key
Tôi thường có xu hướng tích hợp nhiều thông tin vào trong một key, ví dụ như:
- Tên đội
- ID đội
- Điểm số
- Danh sách thành viên
Ưu điểm của cách này là sau khi thực hiện zrange
, bạn có thể trực tiếp giải mã và gửi dữ liệu về phía client mà không cần truy vấn thêm.
Tuy nhiên, nhược điểm là nếu điểm số thay đổi liên tục, thì việc cập nhật lại phần tử trong Sorted Set sẽ không thể bao phủ đầy đủ các thuộc tính khác đã lưu trữ trước đó. Điều này khiến việc mở rộng tính năng trở nên phức tạp, đặc biệt là khi dữ liệu cũ và mới không tương thích.
Do đó, phương án tối ưu nhất là chỉ lưu trữ ID của từng đối tượng trong Sorted Set. Khi cần hiển thị chi tiết, bạn chỉ cần lấy danh sách ID từ Redis rồi tiến hành query sang MySQL để lấy thông tin đầy đủ.
Vấn đề nổi bật
Làm thế nào để thuận tiện hơn khi lấy thông tin liên quan đến người dùng hoặc đối tượng đứng ở các vị trí nhất định trong bảng xếp hạng?
Tài liệu
- Redis Sorted Sets