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

WBOY
풀어 주다: 2022-06-02 21:09:18
앞으로
2746명이 탐색했습니다.

이 글에서는 데이터의 교차, 결합, 보완을 구현하는 것과 관련된 문제를 주로 소개하는 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으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!