المستوى: متوسط / محترف
لو عندك cache بـ 100 مليون مفتاح وكل request بيدوّر هل المفتاح موجود قبل ما يروح للـ DB، Bloom filter بيخلّيك تجاوب على السؤال ده في حوالي 90 نانو ثانية بـ 114MB رام بدل 4GB. الكلام ده مش نظري — Cassandra و RocksDB و Bitcoin Core و Chrome (في Safe Browsing) بتستخدم Bloom filters داخليًا للسبب ده بالظبط.
Bloom Filter: الهيكل اللي بيقولك "مش موجود" بثقة 100% و"موجود" باحتمالية
المشكلة باختصار
تخيّل جدول users فيه 100 مليون email، وكل request جديد لازم تتأكد إن الـ email مش موجود قبل ما تعمل insert. عندك تلات حلول كلها ضعيفة:
- تروح للـ DB في كل lookup → 100% من الـ requests بتلمس القرص.
- تحطّ الـ 100M email في HashSet في الذاكرة → 4GB رام (40 byte لكل مفتاح × 100M).
- تستخدم Redis Set عادي → نفس المشكلة، بس على ماكينة تانية.
Bloom filter بيقدّم خيار رابع: بنية احتمالية بتقولك "المفتاح ده مش موجود مؤكد" أو "ممكن يكون موجود". لو مش موجود (وده 99% من الحالات في الـ workloads الكبيرة)، بتوفّر طلب DB كامل. لو ممكن يكون موجود، بتروح تتحقق فعليًا.
المثال الأبسط: قائمة المدعوّين على باب الفرح
تخيّل صاحب الفرح طبع لك ورقة فيها 1000 خانة فاضية. لكل ضيف مدعو، بياخد اسمه ويحسب عليه 3 حسابات بسيطة (مثلاً: عدد الحروف، أول حرف، آخر حرف)، وكل حساب بيطلع رقم بين 1 و 1000. بيحط علامة ✓ في الخانات الـ 3 دي على الورقة.
لما حد ييجي على الباب، بتعمل نفس الـ 3 حسابات على اسمه. لو واحدة من الـ 3 خانات فاضية، يبقى مؤكد إنه مش مدعو — اعتذر له فورًا. لو الـ 3 مليانين، احتمال يكون مدعو، بس مش مؤكد، فلازم تتحقق من القائمة الأصلية.
المكسب الحقيقي: بدل ما تفتح القائمة الأصلية لكل ضيف (1000 ضيف × 5 ثواني بحث = 80 دقيقة)، بتفتحها بس للـ 1% اللي عدّوا الفلتر بالخطأ — يعني تقريبًا 50 ثانية شغل بدل 80 دقيقة.
التعريف العلمي الدقيق
Bloom filter هو probabilistic data structure اخترعه Burton Howard Bloom سنة 1970 في ورقته الشهيرة "Space/Time Trade-offs in Hash Coding with Allowable Errors". بيتكوّن من عنصرين فقط:
- Bit array بطول m بيت، كله أصفار في البداية.
- k دالة hash مستقلة، كل واحدة بترجّع رقم في النطاق
[0, m-1].
عند الإضافة: تطبّق الـ k دوال على المفتاح، وتشغّل الـ k bits في المواقع الناتجة (تخلّيها 1).
عند البحث: تطبّق نفس الدوال؛ لو فيه bit واحد على الأقل = 0، المفتاح مؤكد غير موجود (false negative مستحيل). لو الـ k bits كلها = 1، المفتاح غالبًا موجود (false positive وارد).
الـ false positive rate بتتحدد رياضيًا بالمعادلة: