4

Используя фильтр Bloom, мы будем получать оптимизацию пространства. Рамка cassandra также имеет реализацию Bloom Filter. Но подробно, как достигается эта оптимизация пространства?Реализация цветного фильтра

+1

, пожалуйста, отметьте некоторые из ваших вопросов в ответе и немного перефразируйте свой вопрос. Таким образом, люди будут немного больше готовы помочь вам. –

+0

Прошу прощения. Как я буду отмечать ответы на вопросы? – UVM

+0

нажмите на нужную отметку, она станет зеленой для ответа, который вы считаете ответом на самом деле. –

ответ

3

Цветочный фильтр не является «каркасом». Это больше похоже на алгоритм. Реализация не очень длинная.

Вот один в Java я попытался (.jar, исходный код и JavaDoc быть все доступны):

«Автономные реализации Java кукушки HASHING и Блум Фильтры» (вы можете Google для этого в случае следующая ссылка не работает больше):

http://lmonson.com/blog/?page_id=99

+0

У меня есть исходный код для алгоритма фильтра Bloom. Реализовано в рамках Cassandar. – UVM

+0

Но я беспокоюсь, как здесь происходит оптимизация пространства? – UVM

+0

@UNNI: О, хорошо, не знал, что это был ваш вопрос ... В статье в Википедии есть раздел, объясняющий, как достигается космическая эффективность: http://en.wikipedia.org/wiki/Bloom_filter Но это компромисс где вы согласны с некоторыми ложными срабатываниями в обмен на более эффективное с точки зрения памяти представление. – SyntaxT3rr0r

2

Так что я видел этот вопрос раньше, и я использовал совет выше, и оказалось, что способ замедлить для меня. Поэтому я написал свой собственный. Это не в полной мере целом, но я уверен, что если кто-то отчаянным для исполнения, как и я, они сделают его более общим сами по себе :)

Я использовал реализации хэш ропот, который вы можете скачать здесь: http://d3s.mff.cuni.cz/~holub/sw/javamurmurhash/

код: package uk.ac.cam.cl.ss958.SpringBoardSimulation;

import ie.ucd.murmur.MurmurHash; 

    import java.util.BitSet; 
    import java.util.Random; 

    public class FastBloomFilter { 

     private final BitSet bs; 

     final int [] hashSeeds; 

     final int capacity; 

     public FastBloomFilter(int slots, int hashFunctions) { 
      bs = new BitSet(slots); 
      Random r = new Random(System.currentTimeMillis()); 
      hashSeeds = new int[hashFunctions]; 
      for (int i=0; i<hashFunctions; ++i) { 
       hashSeeds[i] = r.nextInt(); 
      } 
      capacity = slots; 
     } 

     public void add(int value) { 
      byte [] b = new byte[] { 
        (byte)(value >>> 24), 
        (byte)(value >>> 16), 
        (byte)(value >>> 8), 
        (byte)value}; 
      for (int i=0; i<hashSeeds.length; ++i) { 
       int h = MurmurHash.hash32(b, 4, hashSeeds[i]); 
       bs.set(Math.abs(h)%capacity, true); 
      } 
     } 

     public void clear() { 
      bs.clear(); 
     } 

     public boolean mightContain(int value) { 
      byte [] b = new byte[] { 
        (byte)(value >>> 24), 
        (byte)(value >>> 16), 
        (byte)(value >>> 8), 
        (byte)value}; 
      for (int i=0; i<hashSeeds.length; ++i) { 
       int h = MurmurHash.hash32(b, 4, hashSeeds[i]); 

       if(!bs.get(Math.abs(h)%capacity)) { 
        return false; 


      } 

      return true; 
     } 


     public static void main(String [] args) { 
      FastBloomFilter bf = new FastBloomFilter(1000, 10); 
      System.out.println("Query for 2000: " + bf.mightContain(2000)); 
      System.out.println("Adding 2000"); 
      bf.add(2000); 
      System.out.println("Query for 2000: " + bf.mightContain(2000)); 


     } 
    } 
7

Вы можете понять, как это экономит пространство, используя этот пример: Допустим, я работаю в Google, в команде Chrome, и я хочу, чтобы добавить элемент в браузере, который уведомляет пользователя, если URL он имеет введенный вредоносный URL. Поэтому у меня есть набор данных, насчитывающий около 1 миллиона злонамеренных URL-адресов, размер которого составляет около 25 МБ. Поскольку размер довольно большой (большой по сравнению с размером самого браузера), я храню эти данные на удаленном сервере.

Случай 1: Я использую хеш-функцию с хеш-таблицей. Я решаю эффективную функцию хеширования и запускаю все 1 миллион URL-адресов через хеширующую функцию для получения хэш-ключей. Затем я создаю хэш-таблицу (массив), где хэш-ключ даст мне индекс для размещения этого URL-адреса. Итак, теперь, когда я хэшировал и заполнял таблицу хеширования, я проверяю его размер. Я сохранил все 1 миллион URL-адресов в хэш-таблице вместе с ключами. Таким образом, размер составляет не менее 25 МБ. Эта хеш-таблица из-за ее размера будет храниться на удаленном сервере. Когда пользователь приходит и вводит URL-адрес в адресной строке, мне нужно проверить, злонамерен ли он. Таким образом, я запускаю URL через хэш-функцию (сам браузер может это сделать), и я получаю хэш-ключ для этого URL-адреса. Теперь я должен сделать запрос на мой удаленный сервер с помощью этого хеш-ключа, чтобы проверить, является ли конкретный URL-адрес в моей хэш-таблице с этим конкретным ключом, таким же, как и введенный пользователем. Если да, то это злонамеренно, и если нет, то это не злонамеренно. Таким образом, каждый раз, когда пользователь вводит URL-адрес, запрос на удаленный сервер должен быть проверен, является ли он злонамеренным URL-адресом. Это займет много времени и, таким образом, сделает мой браузер медленным.

Случай 2: Я использую фильтр цветения. Весь список из 1 миллиона URL-адресов запускается через фильтр цветения с использованием нескольких хеш-функций, а соответствующие позиции помечены как 1, в огромном массиве из 0. Допустим, мы хотим, чтобы ложная положительная ставка составляла 1%, используя калькулятор фильтра цветения (http://hur.st/bloomfilter?n=1000000&p=0.01), мы получаем размер фильтра цветения, который требуется всего лишь 1,13 МБ. Ожидается такой небольшой размер, хотя размер массива огромен, мы сохраняем только 1 или 0, а не URL-адреса, как в случае хэш-таблицы. Этот массив можно рассматривать как бит-массив. То есть, поскольку у нас есть только два значения 1 и 0, мы можем установить отдельные биты вместо байтов. Это сократило бы пространство, затраченное 8 раз. Этот цветной фильтр размером 1,13 МБ, благодаря его небольшому размеру, может храниться в самом веб-браузере!Таким образом, когда пользователь приходит и вводит URL-адрес, мы просто применяем требуемые хэш-функции (в самом браузере) и проверяем все позиции в цветном фильтре (который хранится в браузере). Значение 0 в любой из позиций говорит нам, что этот URL-адрес НЕ ОПРЕДЕЛЕН в списке злонамеренных URL-адресов, и пользователь может действовать свободно. Таким образом, мы не звонили на сервер и, следовательно, экономили время. Значение 1 сообщает нам, что URL-адрес МОЖЕТ быть включен в список злонамеренных URL-адресов. В этих случаях мы делаем звонок на удаленный сервер, и там мы можем использовать некоторую другую хеш-функцию с некоторой хеш-таблицей, как в первом случае, чтобы получить и проверить, действительно ли URL-адрес. Поскольку в большинстве случаев URL-адрес вряд ли будет вредоносным, фильтр маленького цветения в браузере отображает это и, следовательно, экономит время, избегая вызовов на удаленный сервер. Только в некоторых случаях, если фильтр цветка сообщает нам, что URL-адрес может быть вредоносным, только в тех случаях мы делаем звонок на сервер. Это «MIGHT» имеет право 99%.

Таким образом, используя небольшой фильтр цветения в браузере, мы сохранили много времени, так как нам не нужно делать серверные вызовы для каждого введенного URL.

+0

Вот простая реализация фильтра цветения в Python. https://github.com/tarunsharma1/Bloom-Filter – Tarun

+0

В то время как причина выбора фильтра Bloom приведена в качестве примера, то, как хранится сама информация, неясно. – Aravind

+0

@Aravind, следовательно, я представил весь код для реализации в комментарии выше вашего. Объяснение каждой части кода присутствует в git ReadMe. Используется бит-массив и показана реализация в Python – Tarun

1

Вы можете использовать фильтр Bloom на основе сервера Redis с Redisson lib. На основе 128 бит HighwayHash. Вот пример:

RBloomFilter<SomeObject> bloomFilter = redisson.getBloomFilter("sample"); 

// initialize bloom filter once with 
// expectedInsertions = 55000000 
// falseProbability = 0.03 
bloomFilter.tryInit(55000000L, 0.03); 

bloomFilter.add(new SomeObject(someStateHere1)); 
bloomFilter.add(new SomeObject(someStateHere2)); 
// does it contain object? 
bloomFilter.contains(new SomeObject(someStateHere3)); 
0

Я написал short post о реализации цветения фильтра с использованием Java 8 функций, которые я надеюсь, что имеет отношение к вопросу экономии пространства. Я пошел bit further, чтобы обсудить, как бить срез коллекции фильтров цветения, когда некоторые информационно-поисковые системы сделают это, что имеет отношение к эффективности, когда у вас много фильтров цветения.

+0

@richardstarin, я прочитал ваше сообщение. Что вы делаете, когда запускаете код? – UVM

+0

@ichardstartin, мне понравился ваш блог – UVM

+0

Не знаете, что вы имеете в виду o/p? Ложная положительная скорость p зависит от хэш-функций (с этой реализацией вы можете предоставить произвольные хэш-функции), сколько хэш-функций (k), размера (m) и количества данных, которые вы вложили в него. Возможно, было бы более дружелюбно обернуть его, чтобы вы предоставили хеш-функцию * family * и значение p, затем строитель вычисляет k и m для вас. Но тогда гуава довольно хороша, пост - просто для иллюстрации структуры данных. – richardstartin

 Смежные вопросы

  • Нет связанных вопросов^_^