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

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

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

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

المنصة

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

الدعم

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

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

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

Bloom Filters بالعربي: اعرف لو العنصر موجود في مليون سجل بـ 1MB بس

📅 ١٩ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
Bloom Filters بالعربي: اعرف لو العنصر موجود في مليون سجل بـ 1MB بس

لو عندك قايمة بمليون email مسجّل ومحتاج تشيك كل طلب جديد "هل موجود قبل كده"، hash table بتاخد 75MB ذاكرة. Bloom Filter بيعمل نفس الشغل في 1.2MB مع زمن بحث أقل من 10 ميكروثانية. في المقابل، فيه ثمن صريح هتدفعه، والمقال ده بيوريهولك بالظبط.

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

أي نظام بيعمل deduplication أو rate limiting أو URL blacklist بيحتاج يسأل نفس السؤال: هل شفت العنصر ده قبل كده؟ الحل الكلاسيكي hash set في الذاكرة. لمّا القايمة توصل ملايين العناصر، الذاكرة تحط سقف، والتخزين الدائم بيطلب I/O يبطّأ الاستجابة.

Bloom Filter بيحل الجزء ده بطريقة probabilistic: بيجاوب بسرعة وذاكرة قليلة جدًا، مقابل نسبة false positive محددة مسبقًا.

لوحة دوائر إلكترونية تمثّل هيكل بيانات Bloom Filter لتخزين الـ bits بكفاءة

إيه هو الـ Bloom Filter بالظبط

Bloom Filter هو array من bits (أصفار وواحدات) + مجموعة hash functions. لمّا تضيف عنصر، بتمرره على كل hash function، كل واحدة بترجّع رقم index داخل الـ bit array، وبتقلب الـ bit اللي عند الـ index ده لواحد.

لمّا تسأل "هل العنصر ده موجود؟"، بتمرره على نفس الـ hash functions. لو كل الـ bits اللي بتشاور ليهم واحد، ترد "غالبًا موجود". لو أي bit منهم صفر، ترد "أكيد مش موجود".

الفرق الدقيق هنا: No قاطع، Yes احتمالي. ده اللي بيخلّي الهيكل مفيد ومخيف في نفس الوقت.

الـ 3 قواعد الأساسية

  1. مفيش false negatives: لو Bloom Filter قال "مش موجود"، تثق فيه 100%.
  2. في false positives: لو قال "موجود"، ممكن يكون غلطان. النسبة بتحددها انت في التصميم (1%، 0.1%، 0.01%).
  3. مفيش حذف: لمّا تضيف عنصر بتقلب bits مشتركة مع عناصر تانية. لو شيلت الـ bits، هتكسر البحث عنها.

الحل بكود Python شغّال

Python
import hashlib
from bitarray import bitarray

class BloomFilter:
    def __init__(self, size: int, hash_count: int):
        self.size = size
        self.hash_count = hash_count
        self.bits = bitarray(size)
        self.bits.setall(0)

    def _hashes(self, item: str):
        for i in range(self.hash_count):
            digest = hashlib.sha256(f"{i}:{item}".encode()).hexdigest()
            yield int(digest, 16) % self.size

    def add(self, item: str) -> None:
        for idx in self._hashes(item):
            self.bits[idx] = 1

    def contains(self, item: str) -> bool:
        return all(self.bits[idx] for idx in self._hashes(item))

# مقاس بـ false positive rate 1% لمليون عنصر
bf = BloomFilter(size=9_585_059, hash_count=7)
bf.add("ahmed@example.com")

print(bf.contains("ahmed@example.com"))  # True دايمًا
print(bf.contains("unknown@example.com"))  # False في 99% من الحالات

اختيار size=9_585_059 و hash_count=7 مش عشوائي. الصيغة الرياضية بتحسبهم من عدد العناصر المتوقع ونسبة الخطأ المقبولة. في production استخدم pybloom_live اللي بيعمل الحسبة لك.

قياسات حقيقية على مليون email

  • Python set: ~75MB ذاكرة، 0.3 ميكروثانية لكل بحث.
  • Bloom Filter (1% false positive): ~1.2MB ذاكرة، 8 ميكروثانية لكل بحث.
  • الموفّر: 62x في الذاكرة، مقابل بطء 26x في البحث (لسه تحت 10μs، أسرع من أي network call).

الأرقام دي مقاسة على Python 3.11 في بيئة محلية بـ 16GB RAM، وبتختلف على حسب الـ hash function وحجم العنصر. المهم في النسبة مش الرقم المطلق.

trade-offs لازم توزنها

Bloom Filter بيكسب ذاكرة، وبيخسر 3 حاجات:

  • دقة مطلقة: لو عندك false positive بنسبة 1%، يعني في 10 آلاف حالة من مليون هترد "موجود" وهو مش موجود. لو دي حالة دفع أو صلاحية، الرقم ده كارثة.
  • مرونة الحجم: لازم تعرف عدد العناصر المتوقع من البداية. لو العدد زاد 3 أضعاف، نسبة الخطأ بتقفز بشكل غير خطي.
  • الحذف: لو محتاج تشيل عناصر، لازم Counting Bloom Filter أو Cuckoo Filter، وكل منهم بياكل ذاكرة أكتر.

الافتراض إن استخدامك بيحتمل false positive، وإن البديل (I/O أو ذاكرة زيادة) أغلى من الخطأ ده.

حالات استخدام حقيقية

  • Google Chrome بيستخدمه لفحص الـ URLs الخبيثة قبل ما يضرب السيرفر.
  • Cassandra و HBase بيستخدموه في الـ SSTables عشان يمنعوا قراءة من disk لما الـ key مش موجود.
  • Medium و Quora بيستخدموه لمنع عرض نفس المقال للقارئ مرتين.
  • CDN cache layers بيستخدموه كـ first-level check قبل الـ Redis lookup.

متى لا تستخدم هذه الطريقة

متستخدمش Bloom Filter في الحالات دي:

  • لو false positive في حالتك ليه ثمن قانوني أو مالي (هوية، صلاحيات، مدفوعات).
  • لو العدد الإجمالي أقل من 10 آلاف عنصر، الـ set العادي أبسط وأدق.
  • لو محتاج تعرف عدد العناصر اللي ضفتها فعلًا، Bloom Filter مش بيعدّها.
  • لو العناصر بتتشال بانتظام، استخدم Cuckoo Filter مباشرة.

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

لو عندك lookup متكرر في الـ backend بيستهلك ذاكرة ملحوظة، جرّب الخطوات دي:

  1. قيس استهلاك الذاكرة الحالي لهيكل الـ lookup بتاعك (مثلًا بـ sys.getsizeof أو tracemalloc).
  2. ركّب pybloom_live وابدأ بـ capacity=expected_count و error_rate=0.01.
  3. شغّل عينة حقيقية من 100 ألف عنصر واحسب الـ false positive rate الفعلي.
  4. لو الرقم قريب من 1%، ادمجه في الـ request path كطبقة أولى قبل الـ database.

مصادر

  • الورقة الأصلية: Burton Howard Bloom, "Space/Time Trade-offs in Hash Coding with Allowable Errors", Communications of the ACM, 1970.
  • Wikipedia - Bloom filter: https://en.wikipedia.org/wiki/Bloom_filter
  • Cassandra documentation - Bloom filters in SSTables: https://cassandra.apache.org/doc/latest/cassandra/operating/bloom_filters.html
  • مكتبة pybloom_live: https://pypi.org/project/pybloom-live/
  • مقال Cloudflare عن استخدام Bloom filters في URL filtering: https://blog.cloudflare.com/

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

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

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