İçeriğe geç

Bloom Filter — "Kesinlikle Yok" mu, "Belki Var" mı?

Orta 9 dk Sık karşılaşılır

Önce şunu oku: Cache Stratejileri — Defter Ne Zaman Yalan Söyler?

30 saniyede özet

Bloom filter, bir şeyin bir kümede olup olmadığını çok az bellekle cevaplar: ya "kesinlikle yok" ya da "belki var". Hiçbir zaman var olanı kaçırmaz, ama bazen yanlış alarm verir. Boyu ve hash sayısı bu oranı belirler.

Büyük bir düğünün vestiyerinde, her misafir adının gösterdiği birkaç askıya bir kurdele bağlıyor. Birinin gelip gelmediğini merak edersen, onun askılarına bakarsın. Askılardan biri boşsa o kişi kesinlikle gelmemiştir.

  1. Bayt: Her ödemede alıcı hesabı şüpheli listesinde mi diye veritabanına soruyoruz. Saniyede binlerce sorgu!

  2. Sen: Ama alıcıların neredeyse hepsi temiz. Bu sorguların çoğu boşa.

  3. Bayt: Temiz olduğunu veritabanına sormadan nasıl bilebiliriz ki?

  4. Bayt: Kesin bilemeyiz, ama çoğu için "kesinlikle yok" diyebiliriz. Birkaç bit yetebilir.

Nasıl çalışır?

Bloom filterBir şeyin kümede olup olmadığını az bellekle cevaplayan bit dizisi. "Kesinlikle yok" ya da "belki var" der; eklenmiş bir şeyi hiç kaçırmaz.Sözlükte gör →, başta hepsi 0 olan bir bit dizisidir. Bir hesap eklerken birkaç hash fonksiyonu hesabın adını dizideki birkaç konuma çevirir ve o bitler 1 yapılır.

Sorgularken aynı konumlara bakılır. Bitlerden biri 0 ise hesap kesinlikle eklenmemiştir. Hepsi 1 ise “belki var” denir, çünkü o bitleri başka hesaplar da doldurmuş olabilir.

Kafam karıştı, daha basit anlat

Eklerken birkaç biti 1 yap. Sorgularken o bitlere bak: biri 0 ise kesinlikle yok.

Hızlı kontrolBaşlangıç

Bloom filter bir sorguya hangi iki cevabı verebilir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Bir kayıt eklenirken Bloom filter'da ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Yanlış alarm nereden gelir?

32 bitlik küçük bir filtreye 20 şüpheli hesap eklendi. Her hesap 1 yerine 3 bit doldursaydı, temiz müşteriler için yanlış alarm azalır mı? Cevabı göster

Hayır, artar. 20 hesap 3’er bit doldurunca küçük dizinin neredeyse tamamı 1 olur. Temiz bir müşterinin bütün bitleri de tesadüfen dolu çıkar.

Boş bir askı kesin bir cevaptır; dolu askılar yalnızca bir ihtimal.
Adım adım oku
  1. Her misafir birkaç askıya kurdele bağlar.
  2. Askılarından biri boşsa: kesinlikle yok.
  3. Hepsi doluysa: belki var.
  4. 'Kesinlikle yok' kesindir, 'belki' değildir.

“Belki var” deyip aslında olmayan her cevap bir false positiveOlmayan bir şey için "var" ya da "belki var" denmesi; yanlış alarm. Bloom filter'da yalnızca bu yönde hata olur.Sözlükte gör →’tir. Bloom filter’da bunun tersi, yani var olanı kaçırmak, hiç olmaz.

Yanlış alarm oranını iki şey belirler: dizinin boyu ve hash sayısı. Yer bolsa birkaç hash, temiz bir müşterinin en az bir bitinin boş kalma ihtimalini artırır. Yer darsa her ek hash diziyi daha çabuk doldurur.

Kafam karıştı, daha basit anlat

Yanlış alarm yalnızca “belki var” tarafındadır. Yer ve hash sayısı birlikte ayarlanır.

Hızlı kontrolOrta

Bloom filter'da false positive nedir?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Bloom filter hangi durumda en çok işe yarar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Kendin gör

Kesinlikle yok mu, belki var mı?

Tohum 286701

Bit dizisi: 0/32 dolu · eklenen şüpheli hesap: 0

■ dolu bit□ son bakılan bitler

Oynat ya da adımla: önce şüpheli hesaplar eklenir, sonra temiz müşteriler sorgulanır.

Hız
Adım 0

Şu an ne oldu?

Küçük (32 bit) · 1 hash

20 şüpheli hesap filtreye eklenecek, sonra 20 temiz müşteri sorgulanacak.

Görevler0/3

  • Temiz müşterilerin en az yarısına "belki var" dedirtaçık

    İpucu

    Varsayılan ayarlar yeter.

  • Hash sayısını artırıp yanlış alarmı çoğaltaçık

    İpucu

    Küçük bir filtrede dene.

  • Hiçbir temiz müşteri için veritabanına gitmeaçık

    İpucu

    Yer ve hash sayısı birlikte.

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. Küçük filtre, 1 hash: 20 temiz müşteriden 11’ine “belki var” dendi.
  2. “3 hash” seç. Küçük dizi neredeyse doldu ve yanlış alarm 15’e çıktı.
  3. “Büyük (256 bit)” ve “1 hash” seç. Yanlış alarm 2’ye düştü.
  4. Büyükte “3 hash” seç. Hiçbir temiz müşteri için veritabanına gidilmedi.
Hızlı kontrolOrta

32 bitlik küçük bir filtreye 20 kayıt ekleniyor. Hash sayısını 1'den 3'e çıkarmak ne yapar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Filtre "belki var" dedi. Ödeme servisi ne yapmalı?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Tuzaklar

“Belki var” cevabını kesin saymak. Bir müşteriyi “belki şüpheli” diye engellersen temiz insanları cezalandırırsın. “Belki var” yalnızca “veritabanına sor” demektir.

Silmeye çalışmak. Bir biti 0 yapmak, o biti paylaşan başka hesapları da filtreden siler. Silme gerekiyorsa filtreyi baştan kur ya da sayaçlı bir türünü kullan.

Boyu başta yanlış seçmek. Eklenen kayıt sayısı tahminini aşınca bitler dolar ve yanlış alarm hızla artar. Beklenen kayıt sayısını ve kabul edilebilir oranı baştan belirle.

Kafam karıştı, daha basit anlat

“Belki” kesin değildir, bit silinmez, boyu baştan doğru seç.

Hızlı kontrolOrta

Bir hesap şüpheli listesinden çıkarıldı. Bloom filter'da o hesabın bitlerini 0 yapmak neden tehlikeli?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aşağıdaki örnek bir ödeme servisinden: şüpheli hesap listesi açılışta bir Bloom filter’a yükleniyor, “kesinlikle yok” diyenler için veritabanına gidilmiyor.

Derinleş · Şüpheli hesap kontrolü: veritabanından önce Bloom filter 3 dosya · ~58 satır · ilk okumada atlayabilirsin
Proje dosyaları

src/main/java/com/bank/screening/ SuspiciousAccountFilter.java Filtre: beklenen kayıt sayısı ve kabul edilebilir yanlış alarm oranıyla kuruluyor; boyu ve hash sayısını Guava hesaplıyor.

src/main/java/com/bank/screening/SuspiciousAccountFilter.java
@Component
class SuspiciousAccountFilter {
private static final int EXPECTED_ACCOUNTS = 2_000_000;
private static final double FALSE_POSITIVE_RATE = 0.001;
private final SuspiciousAccountRepository repository;
private volatile BloomFilter<String> filter = empty();
SuspiciousAccountFilter(SuspiciousAccountRepository repository) {
this.repository = repository;
}
private static BloomFilter<String> empty() {
return BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), EXPECTED_ACCOUNTS, FALSE_POSITIVE_RATE);
}
/** Rebuilt from scratch: bits cannot be removed safely. */
@EventListener(ApplicationReadyEvent.class)
@Scheduled(cron = "0 0 3 * * *")
void rebuild() {
BloomFilter<String> fresh = empty();
repository.streamAllIbans().forEach(fresh::put);
filter = fresh; // swap in one step; readers never see a half-built filter
}
boolean mightBeSuspicious(String iban) {
return filter.mightContain(iban);
}
}

src/main/java/com/bank/screening/ RecipientScreening.java Yükleme: açılışta ve her gece listeden baştan kuruluyor; silme yok.

src/main/java/com/bank/screening/RecipientScreening.java
@Service
class RecipientScreening {
private final SuspiciousAccountFilter filter;
private final SuspiciousAccountRepository repository;
private final Counter databaseChecks;
RecipientScreening(SuspiciousAccountFilter filter, SuspiciousAccountRepository repository, MeterRegistry registry) {
this.filter = filter;
this.repository = repository;
this.databaseChecks = registry.counter("screening.database.checks");
}
boolean isSuspicious(String iban) {
if (!filter.mightBeSuspicious(iban)) {
return false; // "definitely not": no database round trip
}
databaseChecks.increment();
return repository.existsByIban(iban); // "maybe": the database has the last word
}
}

src/main/java/com/bank/screening/ SuspiciousAccountRepository.java Kontrol: "kesinlikle yok" ise veritabanına gidilmiyor; "belki var" ise son sözü veritabanı söylüyor.

src/main/java/com/bank/screening/SuspiciousAccountRepository.java
interface SuspiciousAccountRepository extends JpaRepository<SuspiciousAccount, Long> {
boolean existsByIban(String iban);
@Query("select a.iban from SuspiciousAccount a")
Stream<String> streamAllIbans();
}

Kendini sına

Şimşek turu1/4

Bloom filter eklenmiş bir kayıt için "kesinlikle yok" diyebilir.

Soru 1/3İleri

Filtre 1 milyon kayıt için kuruldu; liste 5 milyona çıktı. Ne olur?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Aklında kalacak üç şey

  1. 1 Bloom filter iki cevap verir: "kesinlikle yok" ya da "belki var". Eklenmiş bir şey için asla "kesinlikle yok" demez; yanlış alarm yalnızca "belki var" tarafında olur.
  2. 2 Bloom filter en çok, pahalı bir sorgudan önce bir kapı bekçisi olarak işe yarar. "Kesinlikle yok" diyenler için veritabanına hiç gidilmez.
  3. 3 Yanlış alarm oranını bit dizisinin boyu ve hash sayısı belirler. Daha çok hash yalnızca yer varsa işe yarar; küçük bir dizide bitleri çabuk doldurur.
Sonraki kapı Kilidi aldın, işini yaptın. Peki kilit o sırada hâlâ sende miydi? Dağıtık Kilit ve Fencing Token — Kilit Senin Sandığında · 9 dk

4 kart sonraki derste seni bekliyor

0/4 kart bu dersten toplandı