CUCKOO vs BLOOM filtri, bir Gopher baxımından

Bu yazıda, bir çiçək filtrinin üstündəki bir çuxa filtrinin səmərəliliyini tətbiq etməyə və sınamağa çalışıram. (Golang bölgəsində paylanmış hash masası tətbiq edərək Chord DHT-dəki əvvəlki yazını oxuyun)

Giriş

Ehtimal olunan məlumat quruluşları, xüsusilə böyük məlumat dəstləri işləndikdə çox faydalıdır. Əksər hallarda, işlərin məlumat tərəfində işləyərkən, real vaxt məlumatlarını emal edərkən sadə "mövcud olmayan maddə" və ya "artıq mövcud olan elementdir" sorğusunu etmək istəyərsiniz. Suallara real vaxtda cavab vermək istədiyinizi söyləyin, misli görünməyən məlumat quruluşlarından istifadə edərək, bir istifadəçi əvvəlcədən təqdim olunmuşdursa, misilsiz ips sayı, ən çox səslənən iplər kimi suallara cavab vermək üçün boş bir yer təmin edir. Bu cür sorğulara tipik bir yanaşma ya HashMap ya da HashTable-dan istifadə etmək, ya da bəzi xarici önbelleği (redis kimi) saxlamaq olar, lakin problem böyük verilənlər bazası ilə bağlıdır, bu sadə məlumat strukturları yaddaşa sığmaz. Məkan və zaman üstünlükləri səbəbindən ehtimal olunan məlumat quruluşlarının meydana gəldiyi yer budur.

Misal İstifadə halları

  • Google Bigtable, Apache HBase və Apache Cassandra və Postgresql Bloom filtrlərindən istifadə edərək mövcud olmayan sətir və ya sütun üçün disk axtarışlarını azaldır. Bahalı disk axtarışlarından qaçınmaq bir verilənlər bazası sorğu əməliyyatının işini xeyli artırır.
  • Medium, Bloom filtrlərindən bir məqalənin bir istifadəçiyə artıq tövsiyə olunduğunu yoxlamaq üçün istifadə edir
  • Ethereum, Ethereum blockchain-də logları tez bir zamanda tapmaq üçün Bloom filtrlərindən istifadə edir
  • Google Chrome veb brauzeri zərərli URL-ləri müəyyən etmək üçün Bloom filtrindən istifadə edirdi. Hər hansı bir URL əvvəlcə yerli Bloom filtrinə qarşı yoxlanıldı və yalnız Bloom filtri müsbət nəticə qaytarsa, yerinə yetirilən URL-in tam bir yoxlanışı olduqda (və istifadəçi xəbərdar etdi ki, müsbət nəticə də verildi)

"Cuckoo" nədir?

Məlumat platformasında bu cür suallara cavab vermək üçün bir çox yerdə çiçək filtrlərindən istifadə etdik. Bu yaxınlarda maraqlandığım Cuckoo filtrində bu kağıza rast gəldim. Başlığın özü "Cuckoo Filter: Bloom-dan praktik olaraq daha yaxşıdır" deyir, buna görə onu yoxlamağa qərar verdim.

Cuckoo filtrləri, bənzər bir məkan mürəkkəbliyini qorumaqla, silmək, məhdud sayma və məhdud bir saxta müsbət ehtimal təklif edərək çiçəkləmə filtrinin dizaynını yaxşılaşdırır. Toqquşmaları həll etmək üçün kuku hashinqindən istifadə edirlər və mahiyyətcə yığcam kuku hash masasıdır.

Cuckoo və çiçəkləmə filtrləri, orijinal məlumatların ölçüsü böyük olduqda, dəst üzvlüyü testi üçün də faydalıdır. Hər ikisi hər girişdə yalnız 7 bit istifadə edirlər. Beləliklə, müəyyən bir üzvlük sınağı ilə bahalı bir əməliyyatın qarşısını almaq mümkün olduqda faydalıdırlar. Məsələn, bir verilənlər bazasına sorğu verməzdən əvvəl, istədiyiniz obyektin verilənlər bazasında olub olmadığını görmək üçün müəyyən bir üzv testi edilə bilər.

Alqoritm

Filtr parametrləri:
1. İki hash funksiyası: h1 və h2
2. B çarxları olan bir sıra B. İ-ci kova B [i] adlanacaq

Giriş: L, kuku filtrinə qoyulacaq elementlərin siyahısı.

Alqoritm:
L boş deyil isə:
    X siyahısının ilk maddəsi olaq. X-ni siyahıdan çıxarın.
    B [h1 (x)] boşdursa:
        B yerində x qoyun [h1 (x)]
    Digər halda, B [h2 (x) boşdursa:
        B yerində x qoyun [h2 (x)]
    Digər:
        Qoyun B [h2 (x)] elementi olsun.
        Y-dan L-a qədər əvvəlcədən yazın
        B yerində x qoyun [h2 (x)]

İcra

İcra olduqca sadə görünür, buna görə də bir gəzməyə qərar verdim və boşluq / vaxtın çiçəklənmə filtri ilə müqayisə edildiyini müqayisə etdim. Cuckoo filtri, daxil edilmiş əşyaların "barmaq izlərini" saxlayan bir Cuckoo hash masasından ibarətdir. Bir maddənin barmaq izi, həmin əşyanın hash-dən əldə edilmiş bir az simdir. Cuckoo hash masası, daxil ediləcək bir əşyanın iki hash funksiyasına əsaslanaraq iki mümkün çömçə ilə müqayisə edildiyi bir sıra kovalardan ibarətdir. Hər bir kovada dəyişkən sayda barmaq izlərini saxlamaq üçün konfiqurasiya edilə bilər. Tipik olaraq, bir Cuckoo filtri barmaq izi və çömçə ölçüsü ilə təyin olunur. Məsələn, (2,4) Cuckoo filtri 2 bit uzunluğunda barmaq izlərini saxlayır və Cuckoo hash cədvəlindəki hər bir kovada 4 barmaq izi saxlaya bilər.

Daxil olma

Alqoritm:

f = barmaq izi (x);
i1 = hash (x);
i2 = i1 ⊕ hash (f);
çömçə [i1] və ya kovada [i2] boş bir giriş varsa
   o çömçə f əlavə edin;
   qayıt Bitti;
// mövcud elementləri köçürməlidir;
i = təsadüfi i1 və ya i2 seçin;
n = 0 üçün; n 
// Hashtable tam hesab olunur;
geri qayıtma;

Kod:

Axtarış

Alqoritm:

f = barmaq izi (x);
i1 = hash (x);
i2 = i1 ⊕ hash (f);
çömçə [i1] və ya kovada [i2] f varsa
    Geri qayıt;
geri False;

Kod:

Silin

Alqoritm:

f = barmaq izi (x);
i1 = hash (x);
i2 = i1 ⊕ hash (f);
çömçə [i1] və ya kovada [i2] f varsa
   f nüsxəsini bu kovandan çıxarın;
   Geri qayıt;
geri False;

Kod:

Performans Testi

Bloom filtrində test üçün Will Fitzgerald kitabxanasından istifadə etdim. Kuku filtri üçün alınan FPP (Yalnış müsbət ehtimal) rasionu 0.001-dir

Kosmik mürəkkəblik

Kuku və çiçəklənmə filtrlərinə gəldikdə, fərqli saxta müsbət ehtimallarda fərqli şəkildə fəaliyyət göstərirlər. Süzgəcin saxta müsbət ehtimalı 3% -dən az və ya çox olduqda, kuku filtrində hər giriş üçün daha az bit var. Daha yüksək olduqda, çiçəklənmə filtrində hər giriş üçün daha az bit var.

Zaman mürəkkəbliyi

Cuckoo hashing-da, bir elementin daxil olması ən pis halda O (1) -dən daha pis görünür, çünki toqquşma zamanı çox sayda hal ola bilər, burada cari dəyəri əldə etmək üçün bir dəyəri çıxartmalıyıq. Üstəlik, bir dövr varsa, bütün cədvəl yenilənməlidir.

Hər iki filtrin vaxt təhlili aşağıdakı nəticələr verir:

Bu təcrübə boyunca (kodumu yadda saxlamağım tam optimallaşdırılmamış ola bilər), Bloom filtrləri çox sayda əşyaya daha az yer tutaraq, kosmik mürəkkəblikdə olduqca yaxşı görünür. Cuckoo filtri çox sayda əşyanın daxil olmasında daha yaxşı işləyir, lakin həyata keçirildiyi üçün axtarışda (axtarış vaxtı) bir az yavaş görünür.

Tətbiq

Həqiqətən filtrin tövsiyə ediləcəyi tərəfi götürməzdim, düşünürəm ki, hər ikisinin də öz istifadə davaları var. Bloom filtrləri silinmələri dəstəkləmir, çünki hashing zərərlidir və geri dönməzdir. Çiçəkləmə filtrlərini saymaq bu problemi həll etsə də, Cuckoo filtrləri silmək tələb olunduqda faydalıdır. Əlbətdə ki, Cuckoo filtrləri filtr dolu olduqda səhv verir və bunun da öz üstünlükləri var, Bloom filtrində isə tutuma nəzarət olmur, sadəcə mövcud bit massivini bərpa edir.

Kod

İstinadlar

  • https://brilliant.org/wiki/cuckoo-filter/
  • https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf
  • https://en.wikipedia.org/wiki/Cuckoo_hashing
  • https://blog.fastforwardlabs.com/2016/11/23/probabilistic-data-struktur-showdown-cuckoo.html

P.S Testlər / həyata keçirilmə ilə əlaqədar bir şey taparsanız, təklifinizi / şərhlərinizi çekinmeyin.