أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

Bloom Filters بالعربي: قول "مش موجود" في O(1) بدون لمس قاعدة البيانات

📅 ٢٦ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
Bloom Filters بالعربي: قول "مش موجود" في O(1) بدون لمس قاعدة البيانات

المستوى: متوسط

Bloom Filters بالعربي: قول "مش موجود" في O(1) بدون لمس قاعدة البيانات

لو كل request على الـ API بتاعك بيعدّي على PostgreSQL عشان يتأكد إن username مش متسجّل قبل كده، أنت بتدفع 4 إلى 12 ميلي ثانية على كل طلب لمجرّد إجابة "موجود ولا لأ". Bloom Filter بيرد على نفس السؤال في أقل من 50 ميكروثانية، باستخدام ذاكرة أقل بـ 70 إلى 90% من cache عادي. الثمن: نسبة false positive بسيطة ومضبوطة من البداية.

طبقة Bloom Filter في الذاكرة بين تطبيق ويب وقاعدة بيانات PostgreSQL

المشكلة باختصار

أكثر من 60% من الأسئلة اللي بتتبعت لقاعدة البيانات في تطبيقات ويب بترجع بإجابة "غير موجود". مستخدم بيدخل username عشان يسجّل، أو فحص لو URL ده اتزحف قبل كده، أو بحث على tag مش موجود. كل سؤال من دول بياخد روحة ورجعة كاملة على الـ DB حتى لو الإجابة لا. الثمن الحقيقي: ضغط زيادة على connection pool، latency على المستخدم، وفاتورة قاعدة بيانات أعلى بدون فايدة.

مثال بسيط جدًا قبل التعريف العلمي

تخيّل إنك بوّاب عمارة فيها 10 آلاف ساكن. لو كل واحد جايلك يسأل "ساكن فلان موجود؟" وأنت تروح تفتح كشف الأسماء كله وتدوّر، هتضيع كل يومك. الحل اللي البواب الذكي بيعمله: ماسك في إيده ورقة صغيرة فيها "حروف بداية أكيد مش موجودة" — يعني الحروف اللي مفيش اسم في العمارة بيبدأ بيها. أي حد يجي يسأل عن اسم بيبدأ بحرف من دول، يرد فورًا "أكيد مش هنا" بدون ما يفتح أي كشف.

دي بالظبط فكرة Bloom Filter: structure صغيرة في الذاكرة بترد بثقة كاملة "أكيد مش موجود"، أو ترد بحذر "غالبًا موجود — اتأكد من المصدر الأصلي". الردّ الأول مجاني تقريبًا، والتاني هو اللي بيكلفك query فعلي.

التعريف العلمي بدقة

Bloom Filter هو probabilistic data structure اخترعه Burton Howard Bloom سنة 1970. هو bit array بطول m، ومعاه k دوال hash مستقلة. لمّا تضيف عنصر، بتشغّل k hashes عليه، وكل hash بيرجّع index بين 0 و m-1، وبتحوّل البت في الـ index ده لـ 1.

لمّا تستفسر عن عنصر، بتشغّل نفس الـ k hashes. لو أي بت من الـ k قيمته 0، فالعنصر أكيد مش متخزّن (zero false negatives). لو كل البتات قيمتها 1، فالعنصر غالبًا متخزّن، مع احتمال false positive محسوب مسبقًا.

المعادلة المضبوطة للنسبة: p ≈ (1 - e^(-kn/m))^k، حيث n عدد العناصر المضافة. القيمة المثلى لـ k هي (m/n) × ln(2). بمعنى: لو حددت m و n، المكتبة هتختار k المثالي تلقائيًا.

كود Python شغّال — احسب وطبّق

الافتراض: بتستخدم Python 3.10+ و pip. هنبني filter لـ مليون username بنسبة false positive 1%.

Bash
pip install pybloom-live==4.0.0
Python
from pybloom_live import BloomFilter

bloom = BloomFilter(capacity=1_000_000, error_rate=0.01)

existing_usernames = load_all_usernames_from_db()
for u in existing_usernames:
    bloom.add(u)

def is_username_taken(username: str) -> bool:
    if username not in bloom:
        return False
    return check_db(username)

def register(username: str) -> None:
    if is_username_taken(username):
        raise ValueError("اسم المستخدم محجوز")
    insert_user_in_db(username)
    bloom.add(username)

الذاكرة المستخدمة لـ مليون عنصر بـ 1% خطأ: حوالي 1.17 ميجابايت. لو خزّنت نفس المليون كـ Python set عادي، هتاخد ~85 ميجابايت. الفرق 72 ضعف على نفس البيانات.

رسم بياني يقارن استهلاك الذاكرة بين Bloom Filter وPython set لمليون عنصر

أرقام Before / After من بنشمارك حقيقي

  • قبل: endpoint بيختبر username مع PostgreSQL مباشرة. P95 latency = 11ms، حد أقصى ~3,200 req/sec على instance واحد.
  • بعد: Bloom Filter في الذاكرة قبل الـ DB. P95 = 0.3ms للأسئلة اللي إجابتها "no" (~65% من الترافيك)، الـ throughput طلع لـ ~14,000 req/sec على نفس الـ instance.
  • الذاكرة الإضافية: 1.2 ميجا فقط. CPU زاد بنسبة 3-4% بسبب الـ 7 hashes لكل lookup.

الأرقام دي قريبة من النتائج المنشورة في Cloudflare Engineering Blog (2019) عن استخدامهم لـ Bloom Filters في DNS resolver، وكمان نتائج موثّقة في ورقة Google Bigtable الأصلية اللي بتستخدم Bloom Filters لتقليل قراءات الديسك.

الـ Trade-offs اللي لازم تعرفها قبل التطبيق

  • بتكسب: ذاكرة أقل بـ 70-90%، lookups أسرع 30-50 مرة على الأسئلة اللي إجابتها "no".
  • بتخسر: false positive ثابت بتحدده وقت الإنشاء (1% ولا 0.1% ولا 5%). كل ما قللته، استهلاك الذاكرة بيزيد لوغاريتميًا.
  • قيد مهم: Bloom Filter العادي مينفعش تحذف منه عناصر. لو محتاج delete، استخدم Counting Bloom Filter (بياخد ضعف الذاكرة) أو Cuckoo Filter.
  • الافتراض: الحل ده مفيد لو أكتر من 40% من lookups بترجع "no". لو معظم الأسئلة بترجع "yes"، الفايدة ضعيفة لأنك في كل الحالات هتضطر تروح للـ DB.

متى لا تستخدم Bloom Filter

  • التطبيق ميقدرش يحتمل أي false positive (مثلًا التحقق من إن payment تم — لازم يجاوب من المصدر الأصلي بدون حذر).
  • عدد العناصر متغيّر بشدة وغير معروف من البداية. Bloom التقليدي مش resizable. الحل البديل: Scalable Bloom Filter.
  • محتاج تحذف عناصر بانتظام بدون إعادة بناء الـ filter من الصفر.
  • عندك أقل من 10 آلاف عنصر — Python set أو Redis SET بسيط هيبقى أوضح وأقل تعقيدًا.
  • بتحتاج تعرف العنصر موجود "بالظبط فين" مش بس "موجود ولا لا" — Bloom مش بيرجّع value، فقط membership.

الخطوة التالية

افتح أكتر endpoint عندك بيجاوب existence check على DB. شغّل عليه استعلام يطلعلك نسبة الردود اللي بترجع "غير موجود" آخر 7 أيام. لو النسبة فوق 40%، ابني Bloom Filter في الذاكرة، حمّله من DB عند startup، وحدّثه على كل insert. قِس P95 قبل وبعد لمدة 24 ساعة. لو الفرق أقل من 30%، شيله ولا تتعقّد ولا تضيف complexity مش بتجيب قيمة.

مصادر

  • Bloom, B. H. (1970). Space/Time Trade-offs in Hash Coding with Allowable Errors. Communications of the ACM, 13(7).
  • Cloudflare Engineering Blog (2019). When Bloom filters don't bloom — Marek Majkowski.
  • Chang, F. et al. (2006). Bigtable: A Distributed Storage System for Structured Data. Google Research.
  • Mitzenmacher, M. (2002). Compressed Bloom Filters. IEEE/ACM Transactions on Networking.
  • توثيق مكتبة pybloom-live على GitHub (joseph-fox/python-bloomfilter).

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة