Hiểu về bộ lọc Bloom qua ví dụ
(llimllib.github.io)- Bộ lọc Bloom là một cấu trúc dữ liệu xác suất giúp kiểm tra nhanh sự tồn tại của phần tử trong một tập hợp với hiệu quả bộ nhớ cao
- Nó chỉ cho biết một phần tử chắc chắn không có, hoặc có thể có trong tập hợp, và tồn tại xác suất dương tính giả
- Cấu trúc cơ bản sử dụng vector bit và nhiều hàm băm để đặt các bit tương ứng của mỗi phần tử thành 1
- Tỷ lệ sai số và hiệu năng được quyết định bởi kích thước bộ lọc và số lượng hàm băm, có thể điều chỉnh phù hợp với mục đích sử dụng
- Bài viết cũng giới thiệu các hàm băm được khuyến nghị, cách thiết lập tối ưu, hiệu quả không gian và các trường hợp áp dụng thực tế
Bộ lọc Bloom là gì
- Bộ lọc Bloom là cấu trúc dữ liệu dùng để xác định nhanh và tiết kiệm bộ nhớ xem một phần tử có tồn tại trong tập hợp hay không
- Để đạt được hiệu quả này, bộ lọc Bloom là một cấu trúc dữ liệu xác suất, nên kết quả kiểm tra được chia thành: "chắc chắn không có trong tập hợp" hoặc "có thể có trong tập hợp"
- Cấu trúc cốt lõi của bộ lọc Bloom là vector bit
- Khi thêm phần tử, mỗi phần tử sẽ được băm nhiều lần để đặt các bit ở những chỉ số tương ứng thành 1
- Nếu các bit tương ứng với chỉ số tạo ra từ từng hàm băm đều là 1, thì kết luận là "có thể tồn tại"; nếu không, xử lý là "chắc chắn không có"
Ví dụ về nguyên lý hoạt động
- Nhiều hàm băm (ví dụ: Fnv, Murmur) sẽ ánh xạ một phần tử thành nhiều chỉ số bit
- Khi thêm phần tử, các bit tại những chỉ số đã tính sẽ được đổi thành 1
- Khi kiểm tra sự tồn tại của một phần tử cụ thể, nếu các chỉ số tính theo cùng các hàm băm và cùng cách thức đều là 1, thì được xem là "có thể tồn tại"
- Nếu chỉ cần một bit tương ứng là 0, thì có thể khẳng định chắc chắn phần tử đó "không có trong tập hợp"
- Vì vậy, có khả năng xảy ra dương tính giả (false positive)
Chủ đề nâng cao
Lưu ý: tác giả thực tế chưa có kinh nghiệm áp dụng bộ lọc Bloom vào các dịch vụ quy mô lớn
Lựa chọn hàm băm
- Nên dùng các hàm băm độc lập và có phân bố đồng đều
- Các hàm băm mật mã (như sha1) không phù hợp vì chậm
- Ví dụ về các hàm băm nhanh và đơn giản: Murmur, xxHash, Fnv, HashMix, v.v.
- Trong một trường hợp thực tế, việc chuyển từ md5 sang murmur đã mang lại mức cải thiện tốc độ hơn 800%
Xác định kích thước của bộ lọc Bloom
- Kích thước bộ lọc (m) càng lớn thì tỷ lệ dương tính giả càng giảm
- Tỷ lệ dương tính giả thường có thể được xấp xỉ bằng (1-e^(-kn/m))^k
- Cần chọn hợp lý số phần tử kỳ vọng (n), kích thước bộ lọc (m) và số lượng hàm băm (k)
Số lượng hàm băm là bao nhiêu?
- Số hàm băm càng nhiều thì tốc độ càng chậm và bộ lọc càng nhanh đầy
- Quá ít thì tỷ lệ dương tính giả sẽ cao
- Giá trị k lý tưởng được tính bằng (m/n)ln(2)
- Khi thiết kế, có thể tiến hành theo quy trình sau:
- Ước lượng số phần tử kỳ vọng n
- Xác định số bit m
- Tính ra k tối ưu
- Kiểm tra xem có đạt tỷ lệ sai số mong muốn không; nếu không thì điều chỉnh m
Hiệu năng và hiệu quả không gian
- Trong bộ lọc Bloom, thêm phần tử/kiểm tra tồn tại có độ phức tạp thời gian O(k)
- Hiệu quả không gian phụ thuộc vào mức sai số có thể chấp nhận và phạm vi phần tử
- Nếu không thể dự đoán dù chỉ tương đối phạm vi phần tử, thì bảng băm hoặc bộ lọc Bloom mở rộng có thể phù hợp hơn
Trường hợp sử dụng
- Ví dụ sử dụng chi tiết xem tại Wikipedia
- C. Titus Brown trình bày trường hợp áp dụng bộ lọc Bloom trong tin sinh học
Tài liệu tham khảo
- Broder, Mitzenmacher : Network Applications of Bloom Filters: A Survey — bài báo tổng quan về bộ lọc Bloom
- Wikipedia – Bloom Filter
- Kirsch, Mitzenmacher: Less Hashing, Same Performance
- Almeida và cộng sự: Scalable Bloom Filters
1 bình luận
Ý kiến trên Hacker News