← Học cùng Huan Muse

Bản chữ (transcript) — Tập 3

Hot Key: Khi một key Redis làm sập cả hệ thống

Thời lượng 7:21. Tập này nối thẳng tới câu quiz system design số sáu về hot key trong Redis phân mảnh. Nghe tập này trên Apple Podcasts rồi đọc kèm bản chữ dưới đây.

Linh: Chào anh, mừng anh quay lại với Học cùng Huan Muse. Tập hôm nay em bốc ngẫu nhiên một chủ đề, mà bốc xong em cười luôn, vì nó trúng phóc một câu anh từng trả lời sai. Anh còn nhớ câu hỏi số sáu trong bộ quiz system design khó không ạ? Câu về hot key, tức là khóa nóng, trong Redis phân mảnh. Hôm nay mình mổ xẻ đúng vấn đề đó, cho tới khi anh không thể sai lại lần hai.

Minh: Nhớ chứ Linh. Hôm đó anh chọn consistent hashing, tức là băm nhất quán, và sai bét. Anh vẫn chưa phục lắm đâu. Hệ thống đã chia dữ liệu ra nhiều shard, mỗi shard là một mảnh, gánh một phần dữ liệu. Chia đều như vậy rồi thì sao còn quá tải được?

Linh: Đó chính là cái bẫy đẹp nhất của câu hỏi này. Chia đều dữ liệu không có nghĩa là chia đều lượt truy cập. Anh tưởng tượng Redis cluster của mình giống một siêu thị có mười quầy thu ngân. Hàng hóa chia đều cho mười quầy, nghe rất công bằng. Nhưng bỗng nhiên chỉ có một quầy bán vé xem concert của một ca sĩ siêu nổi tiếng. Thế là mười nghìn người cùng chen vào đúng quầy đó, chín quầy còn lại đứng chơi. Quầy kia sập, không phải vì siêu thị thiếu quầy, mà vì nhu cầu dồn hết vào một điểm.

Minh: À, vậy hot key là một khóa dữ liệu cụ thể bị truy cập nhiều đột biến, đúng không?

Linh: Chính xác ạ. Hot key là một key, một khóa dữ liệu, nhận lượng truy cập cao bất thường trong một khoảng thời gian ngắn. Ví dụ kinh điển người ta hay gọi là celebrity problem, vấn đề người nổi tiếng. Một người nổi tiếng có hàng triệu người theo dõi vừa đăng bài mới. Cùng một giây, hàng triệu ứng dụng cùng đọc đúng key chứa bài đăng đó, hoặc cùng đọc key chứa thông tin sản phẩm đang được livestream bán hàng. Key đó nằm trên shard nào, shard đó lãnh đủ. C P U của shard đó lên một trăm phần trăm, độ trễ tăng vọt, trong khi các shard khác rảnh rang ở mức mười, hai mươi phần trăm.

Minh: Vậy tại sao consistent hashing không cứu được? Anh tưởng băm nhất quán là để cân bằng tải mà.

Linh: Băm nhất quán giải quyết một bài toán khác ạ. Nó giúp khi anh thêm hoặc bớt một shard, chỉ một phần nhỏ dữ liệu phải di chuyển, thay vì phải chia lại toàn bộ. Nhưng với một key cụ thể, hàm băm luôn cho ra đúng một kết quả. Một key thì chỉ hash, tức là băm, tới đúng một shard duy nhất, hôm nay, ngày mai, và cả triệu lần đọc sau đó vẫn là shard đó. Băm nhất quán phân tán các key khác nhau ra đều, chứ nó không hề nhân bản hay chia nhỏ một key đang nóng. Cho nên chọn nó để chữa hot key là chữa sai bệnh ạ.

Minh: Nghe hợp lý rồi đó. Vậy trong thực tế, làm sao mình phát hiện ra mình đang dính hot key, thay vì cứ đoán mò?

Linh: Có ba dấu hiệu ạ. Dấu hiệu một, nhìn vào giám sát hệ thống, anh thấy các shard lệch nhau rõ rệt. Một shard C P U cao chót vót, băng thông mạng cũng cao, còn các shard khác thì thấp. Nếu toàn hệ thống cùng quá tải, đó là chuyện khác. Còn một shard nóng, nhiều shard nguội, đó là mùi của hot key. Dấu hiệu hai, độ trễ của các request, tức là yêu cầu, đọc đúng dữ liệu nổi tiếng đó tăng mạnh, trong khi dữ liệu bình thường vẫn nhanh. Dấu hiệu ba, mình dùng công cụ. Redis có tùy chọn hot keys để quét và chỉ ra những key đang được truy cập nhiều nhất. Anh nhớ phân biệt nhé, big key là key chứa quá nhiều dữ liệu, còn hot key là key bị đọc quá nhiều. Một key có thể nhỏ xíu mà vẫn nóng rẫy.

Minh: Rồi, phát hiện xong thì chữa thế nào? Đây là phần anh cần nhất nè.

Linh: Có ba chiêu chính, và trong thực tế người ta hay kết hợp cả ba. Chiêu một, nhân bản key nóng ra nhiều bản. Thay vì chỉ có một key duy nhất, mình tạo ra, ví dụ, mười bản sao giống hệt nhau, đặt tên thêm số thứ tự ở cuối, và rải các bản sao đó ra các shard khác nhau. Khi ứng dụng đọc, nó chọn ngẫu nhiên một trong mười bản. Vậy là tải đọc được chia mười, mỗi shard chỉ gánh một phần mười. Đây là đáp án đúng của câu sáu hôm đó anh ạ.

Minh: Nhưng nhân bản như vậy, khi dữ liệu thay đổi, mình phải cập nhật cả mười bản, lỡ sót một bản là dữ liệu lệch nhau đúng không?

Linh: Đúng ạ, đó là cái giá. Chiêu này hợp nhất với dữ liệu đọc nhiều, ít thay đổi, và chấp nhận được độ trễ cập nhật ngắn, ví dụ thông tin sản phẩm, bài đăng, hay cấu hình nổi bật. Còn chiêu hai, là đặt một lớp cache, tức là bộ nhớ đệm, ngay trong chính ứng dụng. Người ta hay gọi là local cache, bộ nhớ đệm cục bộ, dùng thư viện như Caffeine trong Java. Mỗi server ứng dụng tự giữ một bản copy của key nóng trong R A M của chính nó, với thời gian sống rất ngắn, chỉ vài giây thôi. Trong vài giây đó, hàng nghìn request đọc thẳng từ bộ nhớ trong máy, không cần chạm vào Redis nữa. Redis gần như được nghỉ ngơi hoàn toàn.

Minh: Cache trong ứng dụng thì nhanh thật, nhưng mỗi server giữ một bản riêng, dữ liệu có thể không nhất quán giữa các server.

Linh: Chuẩn ạ, nên thời gian sống phải ngắn, và chiêu này chỉ hợp với dữ liệu chấp nhận được chuyện cũ hơn thực tế vài giây. Với tin tức, số lượt xem, hay thông tin người nổi tiếng, cũ vài giây không ai chết cả. Nhưng với số dư tài khoản hay tồn kho đang chốt đơn, anh phải cân nhắc kỹ hơn nhiều. Chiêu ba, dành cho trường hợp đặc biệt hơn, là chia nhỏ chính key nóng nếu nó là một bộ đếm. Ví dụ đếm lượt xem của một video đang viral. Thay vì một triệu request cùng cộng vào một key duy nhất, mình chia thành, ví dụ, một trăm key đếm con ở các shard khác nhau, mỗi request cộng vào một key con ngẫu nhiên, và khi cần tổng thì cộng một trăm số đó lại. Đây gọi là counter sharding, chia mảnh bộ đếm.

Minh: Vậy tóm lại là, với key đọc nóng thì nhân bản và cache cục bộ, với key đếm nóng thì chia nhỏ bộ đếm.

Linh: Anh tóm gọn quá chuẩn luôn ạ. Và anh để ý một điểm chung nhé. Cả ba chiêu đều không cố làm cho một shard khỏe hơn. Cả ba đều tìm cách không để một key dồn vào một điểm duy nhất nữa. Nguyên lý nhớ suốt đời là, vấn đề tập trung thì phải giải bằng cách phân tán điểm nóng đó ra, chứ không phải tối ưu cái điểm đang nóng.

Minh: Cho anh một câu tự kiểm tra cuối tập đi, giống các tập trước.

Linh: Đây ạ. Hệ thống Redis của anh có tám shard. Sau khi một người nổi tiếng đăng bài, một shard C P U lên chín mươi lăm phần trăm, bảy shard còn lại chỉ ở mức mười lăm phần trăm. Anh nên làm gì đầu tiên trong các lựa chọn sau? Một, đổi sang consistent hashing. Hai, tăng R A M cho shard đang nóng. Hay ba, nhân bản key nóng ra các shard khác và thêm cache cục bộ trong ứng dụng với thời gian sống vài giây. Đáp án đúng là lựa chọn ba ạ. Lựa chọn một không chia được một key, còn lựa chọn hai chỉ giúp shard đó chịu đựng thêm một chút, chứ không xóa được điểm nóng.

Minh: Lần này mà gặp lại câu sáu, anh không sai nữa đâu.

Linh: Em tin anh. Mình gói tập này lại với ba ý thôi ạ. Ý một, hot key là một key bị truy cập dồn dập, và sharding không tự chữa được nó, vì một key chỉ nằm trên đúng một shard. Ý hai, dấu hiệu nhận biết là một shard nóng bất thường trong khi các shard khác vẫn rảnh. Ý ba, cách chữa là nhân bản key nóng, thêm cache cục bộ ngay trong ứng dụng, và với bộ đếm thì chia nhỏ bộ đếm ra nhiều mảnh. Cảm ơn anh đã nghe Học cùng Huan Muse. Tập sau em lại bốc ngẫu nhiên một chủ đề khác, biết đâu lại trúng đúng điểm anh đang yếu. Hẹn anh ở tập tiếp theo ạ.