ホームページ  >  記事  >  データベース  >  Redis がデータの交差、結合、および補完を実装する方法の詳細な例

Redis がデータの交差、結合、および補完を実装する方法の詳細な例

WBOY
WBOY転載
2022-06-02 12:01:452709ブラウズ

この記事では、Redis に関する関連知識を提供します。主に、データの交差、結合、補数の実現に関する関連問題を紹介します。すべての計算が JVM メモリ内で実行される場合、その場合、次のような問題が発生しやすくなります。メモリ容量不足による OOM 例外について見ていきましょう。皆様のお役に立てれば幸いです。

Redis がデータの交差、結合、および補完を実装する方法の詳細な例

推奨される学習: Redis ビデオ チュートリアル

シーンの説明

今日は、このようなシナリオをシミュレーションします。ローカルに複数のテキスト ファイルがある。各ファイルには、ユーザーの一意の識別子として多くの 32 ビット文字列が保存されている。各ユーザーは 1 行を保存している。毎日非常に多くのユーザーがいる場合、仕事中に、これらのユーザーに対して交差、結合、または補数の処理を実行する最も簡単な方法は、HashSet を使用して対応する操作を実行するなど、Java でセットを介して操作を実行することですが、そのような操作は存在します 1 つの制限は、一般に JVM 操作中の初期メモリが限られていることですすべての計算が JVM メモリ内で実行されると、メモリ容量不足による OOM 例外が発生しやすくなります。そこで、今日は拡張機能を紹介します。このような交差および補完演算を実行するためのより柔軟な方法: Redis を使用して交差を実現し、データの結合と補完


#環境の説明

  • Redis バージョン: Redis 6.0.6

  • Jedis バージョン: 4.2.2

  • ツール hutool バージョン: 5.8.0.M3

  • ##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>

#交差と補数の計算


初期化定数
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";
    }


データを指定されたファイル
/**
* 初始化数据并写入文件中
*/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);
    }

指定されたファイルを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);
    }}


差分セットの計算
    /**
     * 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);
        }
    }

差分集合の計算結果が指定されたファイルに書き込まれます
    /**
     * 将计算的差集数据写入到指定文件
     */
    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);
        }
    }


交差計算
/**
     *
     * @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);
        }
    }

交差計算の結果指定されたファイルに書き込まれます#
    /**
     * 将计算的交集数据写入到指定文件
     */
    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);
        }
    }

#和合計算

    /**
     * 计算多个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);
         }
     }
#和合計算の結果を指定されたファイルに書き込みます

    /**
     * 将计算的并集数据写入到指定文件
     */
    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);
         }
     }

Redis コマンドの説明


SDIFFSTORE 宛先キー [key …]


例:
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SDIFF key1 key2 key3 = {b,d}
SDIFFSTORE コマンドは SDIFF に似ていますが、結果を宛先セットに保存し、結果セットをクライアントに返す点が異なります。

宛先コレクションが既に存在する場合、上書きされます。

#戻り値

結果セット内のメンバーの数


  • SINTERSTORE 宛先キー [key …]

例の注意:

key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SINTER key1 key2 key3 = {c}
SINTERSTORE コマンドは、結果セットを直接返すのではなく、結果を宛先コレクションに保存する点を除けば、SINTER コマンドと似ています。

宛先コレクションが存在する場合、それは上書きされます。

#戻り値

結果セット内のメンバーの数

  • SUNIONSTORE 宛先キー [key …]
例の注意:
key1 = {a,b,c,d}
key2 = {c}
key3 = {a,c,e}
SUNION key1 key2 key3 = {a,b,c,d,e}

SUNIONSTORE コマンドの機能は SUNION の機能と似ていますが、結果セットが返されず、宛先に保存される点が異なります。 宛先が既に存在する場合は上書きされます。

戻り値

結果セット内のメンバーの数

推奨される学習:
    Redis ビデオ チュートリアル

以上がRedis がデータの交差、結合、および補完を実装する方法の詳細な例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。