- Бинарный файл для вашей платформы (.deb, .rpm, .gz)
- Docker image
ghcr.io/capricornusx/bloom-du
docker run --rm -v tmpsf:/var/lib/bloom-du/ \
-p 8515:8515 -it \
ghcr.io/capricornusx/bloom-du --log_level=info
Добавить данные в фильтр можно несколькими способами:
В папке с бинарным файлом разместить текстовый файл (например, values.txt
), с одним значением на строку.
После запустить:
bloom-du --log_level=debug --source=values.txt -o sbfData.bloom
Через некоторое время все строки будут загружены в фильтр. Далее исходный файл уже не нужен.
Вся структура фильтра будет сохранена в файл sbfData.bloom
. Последующие запуски весь фильтр
будет загружен из этого файла. Если его удалить, придётся снова его наполнять нужными вам данными.
Поддерживается загрузка значений сразу из .gz файла (без его распаковки):
bloom-du --source=values.txt.gz
Загрузить каждое значение поштучно через API (пока нет bulk загрузки, через API):
curl -X POST --location "http://localhost:8515/api/add?value=blablabla" \
-H "Accept: application/json"
Проверить наличие элемента в фильтре:
curl -X GET --location "http://localhost:8515/api/check?value=12344" \
-H "Accept: application/json"
Метрики, которые можно собирать через Prometheus имеют префикс bloom_du_*
, например:
curl -X GET --location "http://localhost:8515/metrics"
bloom_du_config_info
bloom_du_elements_total
bloom_du_api_http_request_duration_seconds
Кроме этого, есть стандартные метрики, которые отдаёт Go.
Дашборд для Grafana - grafana-bloom-du.json
- Возможность создавать разные фильтры (название, настройки размера, fpRate ...)
- Graceful upgrade - обновление самого бинарника и корректная обработка клиентов (старых и новых)
- config.yml для удобного старта сервиса с разными фильтрами
- Валидация параметров для cli и api
- code coverage
BF.RESERVE, "key", 0.1, 200000000
Скорость работы в однопоточном режиме:
Case | RPS |
---|---|
Нативно в Redis 1 | ~12 190 |
Реализация на Go 2 | ~15 705 |
Клиентом на Go (github.com/redis/go-redis/v9), проверяем наличие ключа. Отправляем 1кк запросов в один поток. Redis работает в docker, на том же ПК.
BF.EXISTS, "key", "some_value"
С помощью Apache benchmark запрос по http:
ab -k -i -n 1000000 -c 1 "http://localhost:8515/api/fcheck?value=some_value"
На своём проекте, есть проверка входящих данных на дубликаты. Причём мы всё равно должны записать эти данные в базу,
поэтому нельзя создать уникальный индекс, переложив процесс валидации на БД. Хотя всё равно необходимо наличие индекса
по искомому полю, чтобы в случае НЕ отрицательного ответа из фильтра, уже точно идти в БД. Нам не важен fpRate
,
т.к. достаточно 100% отсутствия элемента.
Эффективность очень сильно зависит от соотношения оригиналов/дубликатов. В этом случае мы экономим обращениях в БД.
Для наших задач подошло хорошо.
public function isDouble(string $element): bool
{
$isExist = findElementInFilter($element);
if ($isExist === true) {
// Элемент возможно есть фильтре, идём в БД чтобы проверить точно
$isExist = findElementInDatabase($element);
}
return $isExist;
}
$isDouble = isDouble($element);
if ($isDouble === false) {
addElementToFilter($element);
addElementToDatabase($element);
}
-
Нечто похожее есть в Postgresql - но реализация кажется отличается. Требует исследования.
-
Redis. Поддерживается только классическая реализация фильтра
- Redis data-types
- RedisBloom модуль, входящий в состав Redis Stack
- Redis bitmaps – Fast, easy, realtime metrics
- Using Probabilistic Data Structures in Redis
- Understanding Probabilistic Data Structures
- Bloom Filter Calculator Калькулятор для классической реализации
-
Библиотека на Go, которая использована в этом проект как основная. Содержит в себе реализации стабильного фильтра Блума и других Probabilistic (вероятностных) структур.
-
Bitmap-индексы в Go: поиск на дикой скорости Крутая статья и комменты о схожей теме.
-
Probabilistic Data Structures for Web Analytics and Data Mining
-
Daniel Lemire is a computer science professor. Roaring bitmaps contributor