Consistent hashing là gì: Cân bằng tải cho hệ thống phân tán

Consistent hashing là gì? Đây là kỹ thuật băm đặc biệt giúp hệ thống phân tán chỉ phải di chuyển một phần rất nhỏ dữ liệu mỗi khi số lượng server thay đổi, thay vì băm lại toàn bộ bảng băm như cách làm truyền thống. Bài viết này giải thích nguyên lý vòng tròn, so sánh với băm theo modulo, và chỉ ra vì sao kỹ thuật này nền tảng cho CDN và bảng băm phân tán.

Vòng tròn consistent hashing với các key và server nằm trên vòng

Vấn đề của cách băm truyền thống

Giả sử bạn có n khóa dữ liệu và muốn trải đều chúng lên m server. Cách đơn giản nhất là lấy giá trị băm của khóa rồi chia lấy phần dư cho số server: zeta = beta % n. Cách này chạy rất nhanh và rất phổ biến, nhưng nó có một điểm yếu chí tử: số lượng server là tham số của phép chia.

Khi bạn thêm hoặc bớt một server, mẫu số thay đổi và gần như mọi khóa sẽ rơi vào một vị trí khác. Với hàng triệu khóa, toàn bộ dữ liệu phải được tính lại vị trí lưu trữ và di chuyển. Trong hệ thống CDN đang phục vụ hàng triệu người dùng, mỗi lần thêm node mới sẽ tạo ra một đợt bão lưu lượng không cần thiết và các khoảng trống phục vụ ngẫu nhiên.

Nguyên nhân sâu hơn nằm ở tính chất của phép chia lấy phần dư: hai khóa chỉ cần lệch nhau một đơn vị trước khi chia là có thể rơi vào hai server hoàn toàn khác nhau. Không có quan hệ nào giữa vị trí cũ và vị trí mới, nên không thể dự đoán phần nào cần di chuyển.

Minh họa ví dụ ánh xạ key vào server với consistent hashing

Ý tưởng cốt lõi: đưa mọi thứ lên một vòng tròn

Consistent hashing bỏ hẳn phép chia lấy phần dư. Thay vào đó, một hàm băm ánh xạ cả khóa dữ liệu lẫn định danh server vào cùng một không gian giả tưởng, thường là một vòng tròn có chu vi 2 pi radian. Mỗi server được biểu diễn bằng một điểm trên vòng tròn theo vị trí của hàm băm trên địa chỉ IP hoặc UUID của nó.

Quy tắc gán rất đơn giản: mỗi khóa được băm ra một điểm trên cùng vòng tròn, rồi gán cho server kế tiếp xuất hiện theo chiều kim đồng hồ tính từ điểm đó. Không cần chia lấy phần dư ở bất kỳ đâu.

Điểm cốt lõi nằm ở tính chất bất biến của quy tắc này. Nếu bạn thêm một server mới, nó chỉ chiếm một đoạn nhỏ trên vòng tròn. Chỉ những khóa nằm trong đoạn đó mới phải chuyển sang server mới, còn toàn bộ khóa còn lại vẫn trỏ tới đúng server cũ. Khi một server chết, chỉ các khóa thuộc vùng của nó mới được dồn sang server kế tiếp.

Trên lý thuyết, số lượng khóa phải di chuyển trung bình bằng tỉ lệ giữa số khóa và số slot, tức là n/m, và con số này gần như không đổi khi số server tăng lên. Đây chính là điểm khác biệt căn bản so với băm theo modulo.

Vì sao CDN dùng kỹ thuật này

Consistent hashing được giới thiệu bởi nhóm của David Karger và cộng sự tại Viện Công nghệ Massachusetts vào năm 1997, trong bài báo hội nghị về lý thuyết tính toán, với mục tiêu phân phối yêu cầu cho một tập server thay đổi liên tục. Ý tưởng này sinh ra từ một sự cố rất cụ thể của thập niên 1990: sự tập trung lưu lượng đột ngột vào một số ít máy chủ phổ biến khiến toàn bộ web chậm lại, hiện tượng mà giới công nghệ gọi là slashdotting.

Hôm nay, các mạng phân phối nội dung đã trở thành nơi sử dụng phổ biến nhất của kỹ thuật này. Ví dụ nổi tiếng là Akamai, nền tảng CDN được hai tác giả bài báo năm 1997 là Daniel Lewin và F. Thomson Leighton thành lập năm 1998. Trong hạ tầng của họ, consistent hashing dùng để cân bằng tải bên trong một cụm server, còn việc cân bằng giữa nhiều cụm thì dùng một thuật toán khác là stable marriage.

Ngay cả cơ sở dữ liệu phân tán cũng dùng nguyên lý tương tự. Teradata đã áp dụng ý tưởng này vào cơ sở dữ liệu phân tán của họ từ năm 1986, dù họ không dùng cái tên consistent hashing. Ngày nay, consistent hashing là nền móng của bảng băm phân tán, hay DHT, nơi giá trị băm được dùng để chia không gian khóa của toàn hệ thống cho nhiều nút rồi dựng một mạng lớp phủ giúp tìm nút theo khóa hiệu quả.

Rendezvous hashing: biến thể đơn giản hơn

Có một cách tiếp cận cùng mục tiêu nhưng đơn giản và tổng quát hơn, được thiết kế khoảng năm 1996: rendezvous hashing. Thay vì dựng vòng tròn và tìm vị trí kế tiếp, thuật toán này coi mỗi server là một điểm hẹn, mỗi khóa sẽ chọn server có trọng số ngẫu nhiên cao nhất trong số các server đang sống.

Rendezvous hashing đạt cùng kết quả phân bổ với consistent hashing, nhưng không cần cấu trúc vòng tròn, không cần xử lý nhiều điểm ảo cho một server, và việc thêm hoặc gỡ một server chỉ liên quan tới đúng những khóa thuộc server đó. Đổi lại, mỗi lần tra cứu phải tính trọng số cho toàn bộ server trong danh sách.

Điểm cần lưu ý khi triển khai

Consistent hashing không tự động cân bằng tải hoàn hảo. Nếu vị trí của các server trên vòng tròn rơi vào nhau hoặc dồn cục, một server sẽ nhận nhiều khóa hơn vẫn. Các triển khai thực tế dùng nhiều điểm ảo cho mỗi server để làm loãng bố trí, hoặc kết hợp với một cơ chế cân bằng tải riêng.

Chi phí tra cứu cũng cần cân nhắc. Tìm tuyến tính trên vòng tròn có độ phức tạp tuyến tính theo số server, trong khi tìm kiếm nhị phân đưa chi phí xuống mức log của số server, đổi lại vòng tròn phải được duy trì có thứ tự.

Tóm lại, consistent hashing là câu trả lời kinh điển cho bài toán phân phối dữ liệu trên quy mô lớn khi tập server thay đổi liên tục. Nếu bạn đang xây cache phân tán, CDN hay bảng băm phân tán, đây là thuật toán nên đưa vào danh sách cân nhắc đầu tiên.

Tham khảo thêm: bài viết Consistent hashing trên Wikipedia và bài báo gốc năm 1997 của Karger và cộng sự trên Symposium on Theory of Computing.

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

io_uring là gì: API I/O bất đồng bộ hiệu năng cao của nhân Linux

io_uring là giao diện lập trình ứng dụng (API) I/O bất đồng bộ dành riêng cho nhân Linux, cho phép tiến trình gửi hàng loạt yêu cầu đọc ghi mà…

Xem thêm

Tailwind CSS là gì: Utility-first CSS cho lập trình viên

Tailwind CSS là gì? Đây là một framework CSS mã nguồn mở, khác với Bootstrap hay Foundation ở cách tiếp cận: thay vì đưa sẵn một bộ class dựng sẵn…

Xem thêm
Hàng server thật trong data center, nơi Redis chạy trên hạ tầng vật lý

Redis là gì: Kho dữ liệu trong RAM và toàn bộ kiến trúc

Redis là gì và vì sao nó xuất hiện trong gần như mọi kiến trúc backend hiện đại? Câu trả lời nằm ở hai đặc điểm: toàn bộ dữ liệu…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất