Фильтр Блума — это структура данных, которая может быстро и эффективно определить, существует ли элемент в наборе. Он характеризуется высокой эффективностью использования пространства и высокой скоростью запросов. В повседневной работе по программированию и разработке проектов фильтры Блума часто используются в таких сценариях, как кэширование и предотвращение проникновения в кэш.
Фильтр Блума — это компактная структура данных, используемая для быстрого определения наличия элемента в наборе. Его главное преимущество заключается в том, что он позволяет выполнять быстрые операции принятия решений при чрезвычайно низком потреблении памяти. Фильтры Блума основаны на принципе хеш-функций и могут быть запрошены за постоянное время.
Вот пример простой реализации фильтра Блума в Java-коде:
import java.util.BitSet;
public class SimpleBloomFilter {
private BitSet bitSet;
private int size;
private int hashFuncs;
public SimpleBloomFilter(int size, int hashFuncs) {
this.size = size;
this.hashFuncs = hashFuncs;
bitSet = new BitSet(size);
}
public void add(String element) {
for (int i = 0; i < hashFuncs; i++) {
int hash = (element + i).hashCode() % size;
bitSet.set(hash, true);
}
}
public boolean contains(String element) {
for (int i = 0; i < hashFuncs; i++) {
int hash = (element + i).hashCode() % size;
if (!bitSet.get(hash)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
SimpleBloomFilter bloomFilter = new SimpleBloomFilter(100, 3);
bloomFilter.add("apple");
bloomFilter.add("banana");
System.out.println(bloomFilter.contains("apple")); // выход true
System.out.println(bloomFilter.contains("orange")); // выход false
}
}
В приведенном выше коде,Мы реализовали простой фильтр БлумаSimpleBloomFilter。Определяем битовый массивbitSet、размер фильтраsizeи количество хэш-функцийhashFuncs,И реализует функции добавления элементов и проверки существования элементов.
Фильтры Блума имеют множество практических применений, таких как дедупликация URL-адресов в краулерных системах, решение проблем проникновения в кэш, перехват вредоносных запросов и т. д. Давайте возьмем простой сценарий дедупликации URL-адресов в качестве примера и реализуем практическое применение фильтра Блума с использованием кода Java.
В системах сканирования один и тот же URL-адрес часто сканируется повторно. Чтобы повысить эффективность и сэкономить ресурсы, фильтры Блума можно использовать для реализации дедупликации URL-адресов и уменьшения количества повторных обходов.
import java.util.BitSet;
import java.util.HashSet;
public class UrlDuplicateChecker {
private BitSet bitSet;
private int size;
private int hashFuncs;
public UrlDuplicateChecker(int size, int hashFuncs) {
this.size = size;
this.hashFuncs = hashFuncs;
bitSet = new BitSet(size);
}
public void addUrl(String url) {
for (int i = 0; i < hashFuncs; i++) {
int hash = (url + i).hashCode() % size;
bitSet.set(hash, true);
}
}
public boolean isUrlDuplicate(String url) {
for (int i = 0; i < hashFuncs; i++) {
int hash = (url + i).hashCode() % size;
if (!bitSet.get(hash)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
UrlDuplicateChecker urlChecker = new UrlDuplicateChecker(1000, 3);
// Имитировать добавление повторяющихся URL-адресов
urlChecker.addUrl("https://www.example.com/page1");
urlChecker.addUrl("https://www.example.com/page2");
urlChecker.addUrl("https://www.example.com/page1");
// Проверьте, не дублируется ли URL-адрес
System.out.println("Is https://www.example.com/page1 duplicate: " + urlChecker.isUrlDuplicate("https://www.example.com/page1"));
System.out.println("Is https://www.example.com/page3 duplicate: " + urlChecker.isUrlDuplicate("https://www.example.com/page3"));
}
}
В приведенном выше примере,Мы создалиUrlDuplicateCheckerдобрый,Имитирует сценарий дедупликации URL. Мы используем фильтр Блума для выявления повторяющихся URL-адресов.,Уменьшите количество сканирования повторяющихся URL-адресов.,Повысьте эффективность гусеничной системы.
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.nio.charset.Charset;
public class BloomFilterDemo {
public static void main(String[] args) {
// Инициализируйте фильтр Блума, установите количество элементов, которые, как ожидается, будут обработаны, равным 10 000, а ожидаемый уровень ложных срабатываний равен 0,01.
BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 10000, 0.01);
// Моделирование Дедупликация сцена данных, добавьте несколько элементов
bloomFilter.put("apple");
bloomFilter.put("banana");
bloomFilter.put("orange");
// Определить, находится ли элемент в фильтре Блума
System.out.println("Is 'apple' in filter: " + bloomFilter.mightContain("apple"));
System.out.println("Is 'grape' in filter: " + bloomFilter.mightContain("grape"));
System.out.println("Is 'banana' in filter: " + bloomFilter.mightContain("banana"));
}
}
BloomFilter, предоставленный библиотекой Google Guava для реализации фильтра Блума. первый,Инициализируем фильтр Блума,Устанавливает количество элементов, которые, как ожидается, будут обработаны, равным 10000.,Ожидаемый уровень ложных срабатываний составляет 0,01. Затем,Мы добавили несколько элементов в фильтр Блума,и проверил, находятся ли некоторые элементы в фильтре Блума. По характеристикам фильтра Блума,Для добавленных элементов,mightContainМетод вернетtrue;Для элементов, которые не добавляются,Хотя существует определенная доля ошибочных суждений,Но в этом случае шансы невелики. так,Мы можем использовать фильтры Блума для быстрой дедупликации данных.
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.nio.charset.Charset;
public class MaliciousRequestFilter {
private static final int EXPECTED_INSERTIONS = 1000;
private static final double FALSE_POSITIVE_PROBABILITY = 0.01;
private BloomFilter<String> bloomFilter;
public MaliciousRequestFilter() {
bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), EXPECTED_INSERTIONS, FALSE_POSITIVE_PROBABILITY);
}
public void addMaliciousRequest(String requestId) {
bloomFilter.put(requestId);
}
public boolean isMaliciousRequest(String requestId) {
return bloomFilter.mightContain(requestId);
}
public static void main(String[] args) {
MaliciousRequestFilter filter = new MaliciousRequestFilter();
// Имитировать добавление вредоносных запросов в фильтр Блума
filter.addMaliciousRequest("malicious_request_1");
filter.addMaliciousRequest("malicious_request_2");
// Имитация, чтобы определить, является ли запрос вредоносным
System.out.println("Is 'normal_request' malicious: " + filter.isMaliciousRequest("normal_request")); // должно вернуть ложь
System.out.println("Is 'malicious_request_1' malicious: " + filter.isMaliciousRequest("malicious_request_1")); // должно вернуть истину
}
}
В приведенном выше коде,Мы создалиназванныйMaliciousRequestFilterиздобрый,Он содержит инициализацию графина Блума.、Добавьте вредоносные запросы и методы, чтобы определить, является ли запрос вредоносным.。существоватьmainв методе,Мы создаем экземплярMaliciousRequestFilterдобрый,И добавил выявление двух вредоносных запросов. впоследствии,Мы делаем это, вызываяisMaliciousRequestМетод определения того, является ли запрос вредоносным。Если фильтр Блума считает, что запрос может быть вредоносным,ТакisMaliciousRequestМетод вернетtrue,В противном случае вернитеfalse。так,Мы можем использовать фильтр Блума, чтобы быстро блокировать конкурентные запросы.,Уменьшите нагрузку на сервер.
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
public class CacheWithBloomFilter {
private Map<String, String> cache = new HashMap<>();
private BloomFilter<String> bloomFilter;
public CacheWithBloomFilter() {
bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()), 1000, 0.01);
}
public String getDataFromCache(String key) {
if (bloomFilter.mightContain(key)) {
return cache.get(key);
} else {
// Simulate fetching data from database or external service
String data = fetchDataFromDatabase(key);
if (data != null) {
cache.put(key, data);
bloomFilter.put(key);
}
return data;
}
}
private String fetchDataFromDatabase(String key) {
// Simulating fetching data from database
if (key.equals("key1")) {
return "Data for key1";
}
return null;
}
public static void main(String[] args) {
CacheWithBloomFilter cacheWithBloomFilter = new CacheWithBloomFilter();
// Fetch data for key1 - cache miss, fetch data from database
System.out.println(cacheWithBloomFilter.getDataFromCache("key1"));
// Fetch data for key1 again - cache hit
System.out.println(cacheWithBloomFilter.getDataFromCache("key1"));
// Fetch data for key2 - cache miss, data not available in database
System.out.println(cacheWithBloomFilter.getDataFromCache("key2"));
}
}
Фильтр Блума — очень практичная структура данных.,Это может повысить эффективность запросов и снизить нагрузку на систему во многих сценариях. Через введение и пример кода в этой статье,Надеюсь, читатели имеют предварительное представление о принципе действия фильтра Блума и его реализации.,И может гибко применяться в реальных проектах. Если вам нужна более сложная и эффективная реализация фильтра Блума,Можно добиться дальнейшего углубленного изучения и оптимизации.