ทำความเข้าใจ Bloom Filter ผ่านตัวอย่าง
(llimllib.github.io)- Bloom Filter คือ โครงสร้างข้อมูลเชิงความน่าจะเป็น ที่ช่วยตรวจสอบได้อย่างรวดเร็วและประหยัดหน่วยความจำว่าองค์ประกอบอยู่ในเซตหรือไม่
- มันบอกได้เพียงว่าองค์ประกอบนั้น ไม่มีอยู่แน่นอน หรืออาจมีอยู่ก็ได้ และมีความเป็นไปได้ที่จะเกิด false positive
- โครงสร้างพื้นฐานใช้ bit vector และ hash function หลายตัวเพื่อตั้งค่าบิตของแต่ละองค์ประกอบเป็น 1
- อัตราความคลาดเคลื่อนและประสิทธิภาพ จะขึ้นอยู่กับขนาดของฟิลเตอร์และจำนวน hash function ซึ่งสามารถปรับให้เหมาะกับการใช้งานได้
- ยังแนะนำ hash function ที่เหมาะสมและ วิธีตั้งค่าที่เหมาะสมที่สุด รวมถึงประสิทธิภาพด้านพื้นที่และกรณีการใช้งานจริง
Bloom Filter คืออะไร
- Bloom Filter เป็นโครงสร้างข้อมูลที่ใช้ ตรวจสอบได้อย่างรวดเร็วและประหยัดหน่วยความจำ ว่าองค์ประกอบหนึ่ง ๆ มีอยู่ในเซตหรือไม่
- เพื่อให้ได้ประสิทธิภาพนี้ Bloom Filter จึงเป็นโครงสร้างข้อมูลเชิงความน่าจะเป็น โดยผลการตรวจสอบจะแบ่งเป็น "ไม่มีอยู่ในเซตแน่นอน" หรือ "อาจมีอยู่ในเซต"
- โครงสร้างหลักของ Bloom Filter คือ bit vector
- เมื่อเพิ่มองค์ประกอบเข้าไป จะนำแต่ละองค์ประกอบไป hash หลายครั้ง แล้วตั้งค่าบิตของดัชนีนั้นเป็น 1
- หากบิตที่ตรงกับดัชนีจาก hash function แต่ละตัวเป็น 1 ทั้งหมด จะตัดสินว่า "อาจมีอยู่" แต่ถ้าไม่ใช่จะถือว่า "ไม่มีอยู่แน่นอน"
ตัวอย่างหลักการทำงาน
- ใช้ hash function หลายตัว (เช่น Fnv, Murmur) เพื่อแมปองค์ประกอบไปยังดัชนีบิตหลายตำแหน่ง
- เมื่อเพิ่มองค์ประกอบเข้าไป จะเปลี่ยนบิตของดัชนีที่คำนวณได้ให้เป็น 1
- เมื่อตรวจสอบว่ามีองค์ประกอบใดอยู่หรือไม่ หากดัชนีที่ได้จาก hash function ชุดเดิมและวิธีเดียวกันเป็น 1 ทั้งหมด ก็จะถือว่า "อาจมีอยู่"
- หากมีบิตใดบิตหนึ่งเป็น 0 ก็สามารถตัดสินได้อย่างแน่นอนว่า "ไม่มีอยู่ในเซต"
- ด้วยเหตุนี้จึงเกิดความเป็นไปได้ของ false positive
หัวข้อขั้นสูง
ข้อควรระวัง: ผู้เขียนไม่มีประสบการณ์ในการนำ Bloom Filter ไปใช้กับบริการขนาดใหญ่จริง
การเลือก hash function
- แนะนำให้ใช้ hash function ที่ เป็นอิสระต่อกัน และมี การกระจายตัวสม่ำเสมอ
- hash function เชิงเข้ารหัส (เช่น sha1) ไม่เหมาะ เพราะทำงานช้า
- ตัวอย่างของ hash function ที่เร็วและเรียบง่าย ได้แก่ Murmur, xxHash, Fnv, HashMix เป็นต้น
- ในกรณีใช้งานจริง มีประสบการณ์ว่าสามารถเพิ่มความเร็วได้มากกว่า 800% เมื่อลองเปลี่ยนจาก md5 เป็น murmur
การกำหนดขนาดของ Bloom Filter
- ขนาดฟิลเตอร์ (m) ยิ่งใหญ่ อัตรา false positive ก็ยิ่งลดลง
- โดยทั่วไปอัตรา false positive สามารถประมาณได้ด้วย (1-e^(-kn/m))^k
- ต้องกำหนดจำนวนองค์ประกอบที่คาดหวัง (n), ขนาดฟิลเตอร์ (m), และจำนวน hash function (k) ให้เหมาะสม
จำนวน hash function ควรมีเท่าไร?
- ยิ่งมี hash function มาก ความเร็วก็ยิ่งลดลง และฟิลเตอร์ก็เต็มเร็วขึ้น
- ถ้าน้อยเกินไป อัตรา false positive จะสูงขึ้น
- ค่า k ที่เหมาะสมที่สุดคำนวณได้จาก (m/n)ln(2)
- ในการออกแบบให้ทำตามขั้นตอนต่อไปนี้:
- ประมาณจำนวนองค์ประกอบที่คาดหวัง n
- กำหนดจำนวนบิต m
- คำนวณค่า k ที่เหมาะสมที่สุด
- ตรวจสอบว่าได้อัตราความคลาดเคลื่อนตามต้องการหรือไม่ ถ้าไม่ได้ให้ปรับ m
ประสิทธิภาพและประสิทธิผลด้านพื้นที่
- ใน Bloom Filter การ เพิ่มองค์ประกอบ/ตรวจสอบการมีอยู่ มีความซับซ้อนเชิงเวลา O(k)
- ประสิทธิภาพด้านพื้นที่ขึ้นอยู่กับขอบเขตความคลาดเคลื่อนที่ยอมรับได้และช่วงขององค์ประกอบ
- หากไม่สามารถคาดการณ์ช่วงขององค์ประกอบได้แม้เพียงคร่าว ๆ hash table หรือ Scalable Bloom Filter อาจเหมาะกว่า
กรณีการใช้งาน
- ตัวอย่างการใช้งานแบบละเอียดดูได้ที่ Wikipedia
- C. Titus Brown นำเสนอ กรณีการประยุกต์ใช้ Bloom Filter ในชีวสารสนเทศศาสตร์
เอกสารอ้างอิง
- Broder, Mitzenmacher : Network Applications of Bloom Filters: A Survey — เป็นบทความภาพรวมเกี่ยวกับ Bloom Filter
- Wikipedia – Bloom Filter
- Kirsch, Mitzenmacher: Less Hashing, Same Performance
- Almeida และคณะ: Scalable Bloom Filters
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
"bloom"กับ"demonstrators "(มีช่องว่างท้ายคำ) ชนกันที่ fnv: 7, murmur: 12