Maison  >  Article  >  base de données  >  Exemples détaillés de la façon dont Redis implémente l'intersection, l'union et le complément de données

Exemples détaillés de la façon dont Redis implémente l'intersection, l'union et le complément de données

WBOY
WBOYavant
2022-06-02 12:01:452709parcourir

Cet article vous apporte des connaissances pertinentes sur Redis, qui introduit principalement les problèmes liés à la réalisation de l'intersection, de l'union et du complément des données. Si tous les calculs sont effectués dans la mémoire JVM, il est facile de provoquer des problèmes de mémoire. l'exception MOO causée par un espace insuffisant, j'espère que cela sera utile à tout le monde.

Exemples détaillés de la façon dont Redis implémente l'intersection, l'union et le complément de données

Apprentissage recommandé : Tutoriel vidéo Redis

Description du scénario

Aujourd'hui, nous allons simuler un tel scénario. Nous avons plusieurs fichiers texte localement, et chaque fichier stocke de nombreuses chaînes de 32 bits comme identifiant unique. d'un utilisateur, chaque utilisateur est stocké sur une ligne. Si nous avons un très grand nombre d'utilisateurs chaque jour, nous devrons peut-être effectuer un traitement d'intersection, d'union ou de complément sur ces utilisateurs au travail. La méthode la plus simple consiste à effectuer des opérations via. collections en Java, comme l'utilisation de HashSet pour effectuer certaines opérations correspondantes. Cependant, il existe une limitation dans de telles opérations, c'est-à-dire que nous avons généralement une mémoire initiale limitée pendant l'exécution de la JVM, donc si tous les calculs sont effectués dans la mémoire de la JVM. , il est facile de provoquer des exceptions MOO causées par un espace mémoire insuffisant. Nous allons donc aujourd'hui présenter une manière plus évolutive d'effectuer de telles opérations d'intersection et de complément : implémenter des données via Redis. Version Redis : Redis 6.0.6


Version Jedis : 4.2.2
  • Version de l'outil hutool : 5.8.0.M3
  • fichier pom :
  • <dependencies>
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>4.2.2</version>
            </dependency>
    
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>5.8.0.M3</version>
            </dependency></dependencies>
  • Calcul d'intersection et de complément


Constantes d'initialisation

public class RedisCalculateUtils {
    static String oneFileString = "/Users/tmp/test-1.txt";
    static String twoFileString = "/Users/tmp/test-2.txt";

    static String diffFileString = "/Users/tmp/diff-test.txt";

    static String interFileString = "/Users/tmp/inter-test.txt";

    static String unionFileString = "/Users/tmp/union-test.txt";

    static String oneFileCacheKey = "oneFile";

    static String twoFileCacheKey = "twoFile";

    static String diffFileCacheKey = "diffFile";

    static String interFileCacheKey = "interFile";

    static String unionFileCacheKey = "unionFile";
    }


Initialiser les données dans le fichier spécifié

/**
* 初始化数据并写入文件中
*/public static void writeFile() {
        File oneFile = new File(oneFileString);
        List<String> fs = new ArrayList<>(10000);
        for (int i = 10000; i < 15000; i++) {
            String s = SecureUtil.md5(String.valueOf(i));
            fs.add(s);
        }

        FileUtil.writeUtf8Lines(fs, oneFile);

        File twoFile = new File(twoFileString);
        fs.clear();
        for (int i = 12000; i < 20000; i++) {
            String s = SecureUtil.md5(String.valueOf(i));
            fs.add(s);
        }

        FileUtil.writeUtf8Lines(fs, twoFile);
    }

Spécifier le fichier à écrire dans Redis

/**
* 读取文件数据并写入Redis
*/public static void writeCache() {
    try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
        Pipeline p = jedis.pipelined();
        List<String> oneFileStringList = FileUtil.readLines(oneFileString, "UTF-8");

        for (String s : oneFileStringList) {
            p.sadd(oneFileCacheKey, s);
        }
        p.sync();

        List<String> twoFileStringList = FileUtil.readLines(twoFileString, "UTF-8");

        for (String s : twoFileStringList) {
            p.sadd(twoFileCacheKey, s);
        }
        p.sync();

    } catch (Exception e) {
        throw new RuntimeException(e);
    }}

bad Set calcul

    /**
     * oneKey对应的Set 与 twoKey对应的Set 的差集 并写入 threeKey
     * @param oneKey 差集前面的集合Key
     * @param twoKey 差集后面的集合Key
     * @param threeKey 差集结果的集合Key
     */
    public static void diff(String oneKey, String twoKey, String threeKey) {
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            long result = jedis.sdiffstore(threeKey, oneKey, twoKey);
            System.out.println("oneKey 与 twoKey 的差集的个数:" + result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Les résultats du calcul de l'ensemble de différences sont écrits dans le fichier spécifié

    /**
     * 将计算的差集数据写入到指定文件
     */
    public static void writeDiffToFile() {
        File diffFile = new File(diffFileString);
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            Set<String> result = jedis.smembers(diffFileCacheKey);
            FileUtil.writeUtf8Lines(result, diffFile);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Calcul d'intersection

/**
     *
     * @param cacheKeyArray 交集集合Key
     * @param destinationKey 交集集合结果Key
     */
    public static void inter(String[] cacheKeyArray, String destinationKey) {
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            long result = jedis.sinterstore(destinationKey, cacheKeyArray);

            System.out.println("cacheKeyArray 的交集的个数:" + result);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Les résultats du calcul d'intersection sont écrits dans le fichier spécifié

    /**
     * 将计算的交集数据写入到指定文件
     */
    public static void writeInterToFile() {
        File interFile = new File(interFileString);
        try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
            Set<String> result = jedis.smembers(interFileCacheKey);
            FileUtil.writeUtf8Lines(result, interFile);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

Calcul d'union

    /**
     * 计算多个Key的并集并写入到新的Key
     * @param cacheKeyArray 求并集的Key
     * @param destinationKey 并集结果写入的KEY
     */
     public static void union(String[] cacheKeyArray, String destinationKey) {
         try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
             long result = jedis.sunionstore(destinationKey, cacheKeyArray);

             System.out.println("cacheKeyArray 的并集的个数:" + result);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }

Le résultat du calcul d'union est écrit dans le fichier spécifié

    /**
     * 将计算的并集数据写入到指定文件
     */
    public static void writeUnionToFile() {
         File unionFile = new File(unionFileString);
         try(Jedis jedis = new Jedis("127.0.0.1", 6379)) {
             Set<String> result = jedis.smembers(unionFileCacheKey);
             FileUtil.writeUtf8Lines(result, unionFile);
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
     }

Description de la commande Redis


Clé de destination SDIFFSTORE [clé…]

Exemple : La commande

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}

SDIFFSTORE est similaire à SDIFF. La différence est qu'elle enregistre les résultats dans la collection de destination et renvoie le résultat. défini sur le client.

Si la collection de destination existe déjà, écrasez-la.

Valeur de retour

Nombre de membres dans le jeu de résultats

    Clé de destination SINTERSTORE [clé …]

  • Exemple :
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}

La commande SINTERSTORE est similaire à la commande SINTER, sauf qu'elle ne renvoie pas directement l'ensemble de résultats, mais le résultat est enregistré dans la collection de destination.

Si la collection de destination existe, elle sera écrasée.

Valeur de retour

Le nombre de membres dans l'ensemble de résultats

    Clé de destination SUNIONSTORE [clé …]

  • Exemple :
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}

La fonction de la commande SUNIONSTORE est similaire à celle de SUNION. ne renvoie pas le jeu de résultats, mais stocké dans la destination.

Si la destination existe déjà, elle sera écrasée.

Valeur de retour

Nombre de membres dans l'ensemble de résultats

Apprentissage recommandé :

Tutoriel vidéo Redis

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer