Redis avancée - Filtre Bloom

Insérer ici l'image Description


Pré

Nous optimisation du cache Redis -Redis avancée a parlé d'une solution pour empêcher la pénétration du cache: vider le cache que la valeur d'une meilleure façon de résoudre le filtre Bloom, ici , nous expliquons en détail ci - dessous.


Bloom peut résoudre ce problème?

Par exemple: il y a cinq milliards numéro de téléphone, vous maintenant 100.000 numéros de téléphone, la façon de déterminer rapidement et avec précision la présence ou l'absence de ces chiffres?

Schéma A: DB? ----> 5 milliards de numéro de téléphone, cette efficacité de requête?
Programme B: la mémoire? -> Cliquez sur un numéro de téléphone 8 octets 5,000,000,000 octets * 8 = mémoire 40G ...
Programme C: Hyperloglog ----> précision un peu faible?

Il y a beaucoup de problèmes similaires, tels que

  • Filtre anti-spam
  • logiciel de traitement de texte (comme Word) détection d'erreur de mot
  • Web crawlers Détection des URL
  • Filtre de ligne HBase
  • ...

Le principe filtre de bloom

1970 proposé par Burton. Bloom, avec très peu d'espace pour résoudre le problème

Un vecteur binaire longue (vous comprendre que c'est la structure de données sous-jacentes d'un tableau de super-énorme ne dure que 0 et 1), plus un certain nombre de fonctions de hachage

Insérer ici l'image Description

Nous avons k fonctions de hachage pour le calcul de la k-ième, calcul des résultats de hachage pour chaque ensemble dans la position correspondante, puis récupéré lorsque la fonction recalculée de hachage de plus, s'il n'y a pas 1, qui est le filtre de Bloom le nombre n'existe pas, sont tous seulement 1 était présent.

Dépôts et aux méthodes de calcul doivent être les mêmes, sinon Xiecai. . . .


Filtre Bloom Construction

Insérer ici l'image Description

Paramètres: m vecteur binaire, n des données préliminaires, des fonctions de hachage de k

Filtre Bloom Construction: Nième données prêt à aller à nouveau la procédure ci-dessus

Détermination de la présence ou de l'absence d'éléments: ces données, le processus de génération à nouveau pour reprendre (k-fois la fonction de hachage), si à la fois 1, il indique la présence, l'absence et vice versa.


La construction du taux d'erreur Bloom

Entrée de jeu, à l'aide de filtres de Bloom doivent accepter une erreur, la présence d'erreurs possibles. Certes, il y a une erreur, qui est juste tous les succès

Par exemple, il y a deux valeurs après le hachage k, calcule la valeur est 1, cette fois-ci en effet, votre seule valeur du tableau sous-jacent, et Bloom vous dire qu'il ya une autre valeur

Paramètres: m vecteur binaire, n des données préliminaires, des fonctions de hachage de k

: Facteurs intuitifs dans un rapport en nombre de m / n, la fonction de hachage

Supposons que vous petit vecteur m binaire pour stocker une relation de correspondance fournis, tels que 1000 ( à Goyave un exemple, à condition que 1000 stockage 1000 est de ne pas dire, un grand nombre de calculs de données Goyave sous - jacentes, le taux d'erreur en conjonction avec votre jeu calcule la longueur d'une rangée super), vous n (quantité de données) et super multi, tel que 100 millions, il y a trois fonctions de hachage utilisés pour le calcul.

Cette fois, j'ai données « artisan »,

Après la première opération de la fonction de hachage est stocké à l'emplacement de la matrice sous - jacente de cinq éléments
par l'intermédiaire du second calcul de la fonction de hachage est stocké dans l'emplacement de la matrice sous - jacente de 100 éléments au
cours d' une troisième opération de fonction de hachage est stocké dans la matrice sous - jacente l'emplacement des éléments 1024

Cette fois, vous devez déterminer la présence ou l'absence artisan, seulement besoin de recalculer les trois fonctions de hachage, tant que les premiers éléments 51,001,024 correspondant à la valeur de position est 1, alors qu'il existe. Tant qu'il y est un 0, il n'existe pas.

Je suppose qu'il ya une autre donnée xxxx, après trois calculs de hachage, s'il est arrivé d'avoir posé la première position 51,001,024 éléments, que Bloom dit que vous xxx existez en réalité? En fait, la première 51001024 Cette valeur est calculée à partir de l'artisan, plutôt que xxx, ce qui a donné lieu à des données inexactes, vous devez accepter la possibilité d'une erreur.


m / n est inversement proportionnel au taux d'erreur, k est inversement proportionnelle au taux d'erreur

m / n est inversement proportionnelle à l'erreur: m vecteur binaire, un n-prêt données, pour stocker m tableau binaire plus grande, plus les données dont vous avez besoin pour stocker le n réelle, alors m / n est supérieur? Que le taux d'erreur est faible en conséquence.

k et le taux d'erreur est inversement proportionnelle: Ye Hao comprendre, supposons que vous avez une seule fonction de hachage, n'est pas vous répéter la probabilité est beaucoup plus élevé? Donc, plus le k, plus le taux d'erreur.


Les projections de taux d'erreur réel

Paramètres: m vecteur binaire, n des données préliminaires, des fonctions de hachage de k

  • 1) un élément, une fonction de hachage, la probabilité d'un bit 1 est 1 / m, la probabilité est 0 1- 1 / m

  • 2) k fonctions, la probabilité de 0 (1-1 / m) de la k-ième puissance, le n-éléments, encore probabilité de 0 (1-1 / m) ième puissance de nk

  • 3) est réglé sur 1, la probabilité est de 1 - (1-1 / m) ième puissance de nk

  • 4) la probabilité d'un nouvel élément dans l'ensemble de Insérer ici l'image Description

Couramment utilisé valeur de fonction de hachage du taux d'erreur à:
Insérer ici l'image Description


filtre de Bloom (niveau JVM)

BitMap peut tout d' abord comprendre les principes et l' application des algorithmes spéciaux Algorithms_ _Bitmap

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;


public class GuavaBloomFilterTest {
    // BloomFilter 容量 (实际上Guava通过计算后开辟的空间远远大于capacity)
    private static final int capacity = 100000;

    // 构建 BloomFilter
    private static BloomFilter bloomFilter = BloomFilter.create(Funnels.integerFunnel(), capacity);

    // 模拟初始化数据
    static{
        for (int i = 0; i < capacity; i++) {
            bloomFilter.put(i);
        }
    }



    public static void main(String[] args) {

        int testData =  999;
        long startTime = System.nanoTime();

        if (bloomFilter.mightContain(testData)){
            System.out.println(testData + " 包含在布隆过滤器中 ");
        }
        System.out.println("消耗时间: " + (System.nanoTime() - startTime) + " 微秒");

        // 错误率判断
        double errNums = 0;
        for (int i = capacity + 1000000; i < capacity + 2000000; i++) {
            if (bloomFilter.mightContain(i)) {
                ++errNums;
            }
        }

        System.out.println("错误率: " + (errNums/1000000));
    }
}

problème de filtre Bloom local

  • Capacité du réservoir est limitée mémoire locale, comme le tomcat jvm
  • Une pluralité des filtres de Bloom d'applications, la construction de synchronisation complexe (l'analogie de la session, la compréhension de l'analogue)

Insérer ici l'image Description

  • Redémarrez les besoins de contenu d'application mis en cache à reconstruire

Pour les attaques malveillantes, un grand nombre de demandes aux données du cache du serveur n'existe pas en raison de la pénétration peut également faire d'abord filtré à travers un filtre de Bloom, pour les données de filtre Bloom ne peuvent existe pas sont généralement à filtrer, ne laissez pas la demande de descendre envoyer arrière.

Lorsque le rendement du filtre Bloom une valeur existe, la valeur ne peut exister, quand il dit là, il n'existe certainement pas.

Insérer ici l'image Description

filtre de Bloom est un grand nombre de bits ne sont pas le même groupe et la fonction de hachage sans biais.

Impartiale est appelée la valeur de hachage de l'élément peut être calculée relativement uniforme.

Lorsque la clé est ajoutée au filtre de Bloom, sera utilisé pour une pluralité de fonction de hachage à la valeur de hachage de clé est alors considérée comme un indice entier du nombre de bits d'opération modulo de la longueur pour obtenir une position, chacune des fonctions de hachage seront pris en considération un autre emplacement. Ensuite, la position de ces bits sont mis à un groupe est terminé opération d'ajout.

Lorsqu'on lui a demandé s'il est la clé du filtre Bloom, comme ajouter, aussi l'emplacement de plusieurs hachage sont calculées pour voir si le nombre de bits dans ces endroits sont mis à 1, tant que bit est 0, alors que filtre Bloom dans cette clé n'existe pas.

Si vous êtes un, cela ne signifie pas que cette clé doit exister, mais il est plus probable que ces bits sont mis à 1 peut être due à la présence d'autres en raison clé.

Si ce groupe de bits, cette probabilité sera grande, si ce bit groupe bondé, cette probabilité est réduite.

Cette méthode ne convient pas à coup de données élevé, des données relativement fixes, à faible temps réel (généralement plus ensemble de données) scénarios d'application, la maintenance du code plus complexe, mais le cache prend très peu de place .


Code pseudo

Sac de transport peut guvua filtre de Bloom, la dépendance introduite

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>22.0</version>
</dependency>
import com.google.common.hash.BloomFilter;


//初始化布隆过滤器 

//1000:期望存入的数据个数,0.001:期望的误差率
BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf‐8")), 1000, 0.001);


//把所有数据存入布隆过滤器
void init(){
	for (String key: keys) {
       bloomFilter.put(key);
    } 
 }


String get(String key) {
	// 从布隆过滤器这一级缓存判断下key是否存在
	Boolean exist = bloomFilter.mightContain(key);
	if(!exist){
		return "";
	}
	// 从缓存中获取数据
	String cacheValue = cache.get(key);
	// 缓存为空
	if (StringUtils.isBlank(cacheValue)) {
		// 从存储中获取
		String storageValue = storage.get(key);
		cache.set(key, storageValue);
		// 如果存储数据为空, 需要设置一个过期时间(300秒)
		if (storageValue == null) {
		cache.expire(key, 60 * 5);
	 }
	 	return storageValue;
	 } else {
		 // 缓存非空
		 return cacheValue;
	 }
 }




filtre de Bloom (distribué)

Nous avons analysé les lacunes du filtre Bloom local, une seule application, les difficultés de synchronisation filtre Bloom entre plusieurs applications existent seulement, et une fois que le redémarrage de l'application, erreurs de cache.

Pour un environnement distribué, il peut être utilisé pour construire des filtres distribués Bloom Redis

Utiliser redisson cadre

https://github.com/redisson/redisson/wiki/6.-distributed-objects#68-bloom-filter

RBloomFilter<SomeObject> bloomFilter = redisson.getBloomFilter("sample");
// initialize bloom filter with 
// expectedInsertions = 55000000
// falseProbability = 0.03
bloomFilter.tryInit(55000000L, 0.03);

bloomFilter.add(new SomeObject("field1Value", "field2Value"));
bloomFilter.add(new SomeObject("field5Value", "field8Value"));

bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
bloomFilter.count();

Bloom filtres sont résolus Redis la pénétration du cache de la scène, entraînant un grand nombre de demandes tombent sur la DB, DB écrasé.

Filtre Bloom devrait donc Redis entre le cache et DB.

Bloom vous dit qu'il n'y a pas nécessairement existe, il ne doit pas exister. Alors, quand vous ne trouvez pas la valeur de la DB, vous devez mettre cette mise à jour clé du filtre Bloom, la prochaine fois que cette clé, puis au fil du temps, il n'y a pas de retour directe, la nécessité d'interroger la base de données à nouveau.

Code pseudo

public String getByKey(String key) {
    String value = get(key);
    if (StringUtils.isEmpty(value)) {
        logger.info("Redis 没命中 {}", key);
        if (bloomFilter.mightContain(key)) {
            logger.info("BloomFilter 命中 {}", key);
            return value;
        } else {
            if (mapDB.containsKey(key)) {
                logger.info("更新 Key {} 到 Redis", key);
                String valDB = mapDB.get(key);
                set(key, valDB);
                return valDB;
            } else {
                logger.info("更新 Key {} 到 BloomFilter", key);
                bloomFilter.put(key);
                return value;
            }
        }
    } else {
        logger.info("Redis 命中 {}", key);
        return value;
    }
}

L'inconvénient de filtre Bloom

filtre fleur au détriment de la précision du jugement, commodité, supprimé, pour atteindre une efficacité dans le temps et l'espace est relativement élevé, parce que

  • Qu'une fausse détermination peut être trouvée dans les éléments non dans le conteneur, mais les positions k obtenues après les valeurs de hachage sont 1. Si le filtre bloom est stocké dans une liste noire, vous pouvez stocker des éléments peut être une erreur judiciaire par l'établissement d'une liste blanche.

  • Supprimer les données. Élément dans un conteneur k mappé à des positions de bits de la matrice est de 1, ne peut pas simplement être retirés lorsqu'ils sont directement mis à 0, peuvent affecter la détermination d'autres éléments. Filtre de comptage Bloom peut être considéré comme

Publié 831 articles originaux · Praise won 2074 · Vues 4,23 millions +

Je suppose que tu aimes

Origine blog.csdn.net/yangshangwei/article/details/105107779
conseillé
Classement