>  기사  >  데이터 베이스  >  Redis가 데이터의 교차, 결합 및 보완을 구현하는 방법에 대한 자세한 예

Redis가 데이터의 교차, 결합 및 보완을 구현하는 방법에 대한 자세한 예

WBOY
WBOY앞으로
2022-06-02 12:01:452774검색

이 글에서는 데이터의 교차, 결합, 보완을 구현하는 것과 관련된 문제를 주로 소개하는 Redis에 대한 관련 지식을 제공합니다. 모든 계산이 JVM 메모리에서 수행되면 메모리 문제가 발생하기 쉽습니다. 공간 부족으로 인한 OOM 예외가 모든 분들께 도움이 되기를 바랍니다.

Redis가 데이터의 교차, 결합 및 보완을 구현하는 방법에 대한 자세한 예

추천 학습: Redis 비디오 튜토리얼

장면 설명

오늘 우리는 이러한 시나리오를 로컬에 여러 개 가지고 있으며 각 파일은 많은 32비트 문자열을 고유 식별자로 저장합니다. 매일 사용자 수가 매우 많으면 직장에서 이러한 사용자에 대해 교차, 합집합 또는 보완 처리를 수행해야 할 수 있습니다. 가장 간단한 방법은 다음을 통해 작업을 수행하는 것입니다. 그러나 이러한 작업에는 제한이 있습니다. 즉, 일반적으로 JVM을 실행하는 동안 초기 메모리가 제한되어 있으므로 모든 계산이 JVM 메모리에서 수행되는 경우 , 메모리 공간 부족으로 인해 OOM 예외가 발생하기 쉽습니다. 따라서 오늘은 교차 및 보완 작업을 수행하는 보다 확장 가능한 방법인 Redis를 통한 데이터 구현을 소개하겠습니다.


환경 설명

  • Redis 버전: Redis 6.0.6

  • Jedis 버전: 4.2.2

  • Tool 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);
    }}

bad 계산 설정

    /**
     * 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);
        }
    }

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);
         }
     }

Union 계산 결과가 지정된 파일에 기록됩니다

    /**
     * 将计算的并集数据写入到指定文件
     */
    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 명령은 결과를 대상 컬렉션에 저장하고 결과를 반환한다는 점에서 차이가 있습니다. 클라이언트로 설정합니다.

대상 컬렉션이 이미 존재하는 경우 덮어씁니다.

  • 반환 값
    결과 집합의 멤버 수

SINTERSTORE 대상 키 [키 …]

예:

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제