لو بتعمل lookup على جدول فيه 100 مليون صف لكل request علشان تتأكد إن الـ user ده شاف الإعلان قبل كده، أنت بتدفع 200 ميكروثانية و 8GB RAM في كل instance. Bloom Filter بيرفض 99.9% من الطلبات قبل ما توصل للـ DB أصلاً، بـ 11 ميجابايت ذاكرة بس. في المقال ده هتبني واحد من الصفر وتفهم ليه Cassandra و Bitcoin و Chrome بيستخدموه.
Bloom Filter: التركيبة اللي بتقولك "أكيد لأ" أو "غالباً آه"
المشكلة باختصار
عندك قائمة ضخمة من العناصر (URLs زرتها قبل كده، usernames محجوزة، transaction hashes متشاف). كل request جديد لازم يتحقق: هل العنصر ده موجود في القائمة دي؟
الحل التقليدي: HashSet في الذاكرة. لكن لو القائمة 100 مليون string متوسط 40 حرف، الـ HashSet بياكل 6–8 جيجابايت. تحطها على DB؟ كل lookup بيكلفك round-trip شبكة، يعني 1–5 ميلي ثانية. على 10K request في الثانية، DB بتختنق.
Bloom Filter بيحل المشكلة بمقايضة ذكية: بدل ما يجاوبك "موجود" أو "مش موجود"، بيجاوبك "أكيد مش موجود" أو "غالباً موجود". الإجابة الأولى دقيقة 100%، التانية فيها نسبة خطأ صغيرة بتتحكم فيها أنت.
مثال للمبتدئ: حارس باب الحفلة
تخيّل حفلة فيها 1000 مدعو. الحارس مش حافظ كل الأسماء، لكن عنده ورقة فيها 8000 خانة، كلها فاضية في الأول. كل ما اسم يتسجل، الحارس بياخد الاسم ويمرّره على 3 طرق مختلفة لتحديد 3 خانات في الورقة، ويعلّم عليهم.
لمّا حد ييجي يدخل، الحارس بيكرر نفس العملية. لو لقى أي خانة من التلاتة فاضية → "أكيد مش مدعو، روح من هنا". لو الـ 3 كلهم معلّمين → "غالباً مدعو، اتفضل". الكلمة "غالباً" مهمة: ممكن تكون التلات خانات اتعلّموا بسبب أسامي تانية صدفة. ده بالظبط الـ false positive في Bloom Filter.
التعريف العلمي
Bloom Filter هو probabilistic data structure اخترعه Burton Howard Bloom سنة 1970. مكوّن من حاجتين:
- Bit array بحجم m بت، كلهم أصفار في البداية.
- k دالة hash مستقلة بترجّع كل واحدة رقم بين 0 و m-1.
للإضافة (insert): مرّر العنصر على الـ k دوال، اضبط البتات في الأماكن دي على 1.
للبحث (lookup): مرّر العنصر على نفس الـ k دوال. لو أي بت من الـ k بصفر → العنصر أكيد غير موجود. لو الـ k كلهم 1 → العنصر غالباً موجود.
ملحوظة مهمة: الحذف (delete) مش مدعوم في الـ Bloom Filter الكلاسيكي. لو محتاج حذف، استخدم Counting Bloom Filter (variant فيه عدّاد بدل بت).
الرياضيات اللي بتحدد الحجم
عندك n عنصر متوقع، وبتقبل false positive rate تساوي p. الحجم الأمثل m بالـ bits، وعدد دوال الـ hash الأمثل k: