Redisson을 이용한 Redis 조작 및 설정

Redisson은 Redis를 기반으로 구현된 Java 인메모리 데이터 그리드(In-Memory Data Grid)입니다. 분산형 Java 표준 객체와 다양한 분산 서비스를 제공합니다. 본문에서는 Redisson을 사용하여 Redis를 조작하는 방법을 설명합니다. 사용된 소프트웨어 버전: Java 1.8.0_191, Redis 5.0.8, Redisson 3.13.2.

  1. 의존성 추가

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.2</version>
</dependency>
  1. Redisson을 이용한 Redis 조작

package com.example.redis.demo;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.redisson.Redisson;
import org.redisson.api.*;
import org.redisson.config.Config;

import java.io.*;
import java.util.concurrent.TimeUnit;

/**
 * Redisson을 이용한 Redis 조작 예제
 * Redisson은 동기 인터페이스 외에 비동기(Async), 반응형(Reactive) 및 RxJava2 표준 인터페이스를 제공합니다.
 * Redisson은 Java 객체를 직렬화하여 Redis에 저장하므로, redis 명령줄로 설정된 값은 Redisson으로 가져올 때 오류가 발생할 수 있습니다.
 * Redisson으로 설정된 값을 redis 명령줄로 가져오면 직렬화 관련 정보가 추가로 표시됩니다.
 */
public class RedissonOperations {
    private RedissonClient client;
    private RedissonReactiveClient reactiveClient;
    private RedissonRxClient rxClient;

    @Before
    public void setup() {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://10.49.196.10:6379").setPassword("123456");
        client = Redisson.create(config);
        reactiveClient = Redisson.createReactive(config);
        rxClient = Redisson.createRx(config);
    }

    @After
    public void cleanup() {
        client.shutdown();
        reactiveClient.shutdown();
        rxClient.shutdown();
    }

    /**
     * 범용 객체 저장소 - 모든 유형의 객체를 저장할 수 있습니다
     */
    @Test
    public void bucketTest() throws Exception {
        // 동기 방식
        RBucket<String> bucket = client.getBucket("userName");
        bucket.set("zhaoyun");
        System.out.println(bucket.get());

        // 비동기 방식
        RBucket<String> bucket2 = client.getBucket("userName2");
        bucket2.setAsync("zhaoyun2").get();
        bucket2.getAsync().thenAccept(System.out::println);

        // 반응형 방식
        RBucketReactive<String> bucket3 = reactiveClient.getBucket("userName3");
        bucket3.set("zhaoyun3").block();
        bucket3.get().subscribe(System.out::println);

        // RxJava2 방식
        RBucketRx<String> bucket4 = rxClient.getBucket("userName4");
        bucket4.set("zhaoyun4").blockingGet();
        bucket4.get().subscribe(System.out::println);

        Thread.sleep(1000 * 5);
    }

    /**
     * 바이너리 스트림
     * InputStream 및 OutputStream 인터페이스 구현을 제공합니다
     */
    @Test
    public void streamTest() throws Exception {
        RBinaryStream stream = client.getBinaryStream("userStream");
        stream.set("zhaoyun".getBytes());
        OutputStream outputStream = stream.getOutputStream();
        outputStream.write("zhangfei".getBytes());

        InputStream inputStream = stream.getInputStream();
        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
        System.out.println(result.toString());
    }

    @Test
    public void atomicLongTest() {
        RAtomicLong atomicLong = client.getAtomicLong("counter");
        atomicLong.set(10);
        atomicLong.incrementAndGet();
        System.out.println(atomicLong);
    }

    /**
     * 레이트 리미터(제한 장치)
     */
    @Test
    public void rateLimiterTest() throws InterruptedException {
        RRateLimiter rateLimiter = client.getRateLimiter("apiRateLimiter");
        // 초기화: 최대 처리량 - 1초에 5개 토큰
        rateLimiter.trySetRate(RateType.OVERALL, 5, 1, RateIntervalUnit.SECONDS);
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                int count = 0;
                @Override
                public void run() {
                    while(true) {
                        rateLimiter.acquire(1);
                        System.out.println(Thread.currentThread() + "-" + System.currentTimeMillis() + "-" + count++);
                    }
                }
            }).start();
        }

        Thread.sleep(1000 * 5);
    }

    /**
     * RList는 java.util.List 인터페이스를 구현합니다
     */
    @Test
    public void listTest() {
        RList<String> list = client.getList("userList");
        list.add("a");
        list.add("zhaoyun");
        list.add("zhangfei");
        list.remove(1);
        System.out.println(list);
    }

    /**
     * RMap은 java.util.concurrent.ConcurrentMap 및 java.util.Map 인터페이스를 구현합니다
     */
    @Test
    public void mapTest() throws Exception {
        RMap<String, String> map = client.getMap("userMap");
        map.put("name", "zhaoyun");
        map.put("location", "changshan");
        map.put("camp", "shu");
        map.remove("location");
        map.forEach((key, value) -> {System.out.println("key=" + key + ",value=" + value);});
    }

    /**
     * RSet은 java.util.Set 인터페이스를 구현합니다
     */
    @Test
    public void setTest() {
        RSet<String> set = client.getSet("userSet");
        set.add("zhaoyun");
        set.add("zhangfei");
        set.forEach(System.out::println);
    }

    /**
     * RQueue는 java.util.Queue 인터페이스를 구현합니다
     */
    @Test
    public void queueTest() {
        RQueue<String> queue = client.getQueue("taskQueue");
        queue.add("zhaoyun");
        queue.add("zhangfei");
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }

    /**
     * 재진입 가능한 RLock - java.util.concurrent.locks.Lock 인터페이스를 구현합니다
     */
    @Test
    public void lockTest() throws InterruptedException {
        RLock lock = client.getLock("resourceLock");
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread() + "-" + System.currentTimeMillis() + "-" + "락 획득 성공");
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }).start();
        }
        Thread.sleep(1000 * 5);
    }

    /**
     * Redisson의 분산 RBitSet Java 객체는 java.util.BitSet과 유사한 구조 디자인을 사용합니다
     */
    @Test
    public void bitSetTest() {
        RBitSet bitSet = client.getBitSet("flagBits");
        bitSet.expire(5, TimeUnit.DAYS);
        bitSet.set(0, true);
        bitSet.set(20, true);
        bitSet.set(96, true);
        System.out.println(bitSet.get(10));
        System.out.println(bitSet.get(20));
    }

    /**
     * Redisson은 Redis를 사용하여 Java 분산 블룸 필터(Bloom Filter)를 구현합니다
     */
    @Test
    public void bloomFilterTest() {
        RBloomFilter<String> bf = client.getBloomFilter("urlFilter");
        if (!bf.isExists()) {
            bf.tryInit(150000000L, 0.05);
            bf.add("test");
            bf.expire(200, TimeUnit.SECONDS);
        }
        bf.add("https://www.baidu.com/");
        bf.add("https://www.tmall.com/");
        bf.add("https://www.jd.com/");
        System.out.println(bf.contains("https://www.tmall.com/"));
        System.out.println(bf.count());
    }
}
  1. Redisson 설정

package com.example.redis.config;

import org.junit.Test;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

/**
 * Redisson 설정 예제
 */
public class RedissonConfiguration {
    /**
     * 단일 Redis 노드 모드
     */
    @Test
    public void singleNodeMode() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://10.49.196.10:6379")
                .setPassword("123456")
                .setConnectionPoolSize(5) // 연결 풀 크기
                .setConnectionMinimumIdleSize(2) // 최소 유휴 연결 수
                .setDatabase(0);
        RedissonClient client = Redisson.create(config);
        RBucket<String> name = client.getBucket("name");
        System.out.println(name.get());
    }

    /**
     * 마스터-슬레이브 모드
     */
    @Test
    public void masterSlaveMode() {
        Config config = new Config();
        config.useMasterSlaveServers()
                .setMasterAddress("redis://10.49.196.20:6379")
                .addSlaveAddress("redis://10.49.196.21:6379")
                .addSlaveAddress("redis://10.49.196.22:6379")
                .setPassword("123456")
                .setMasterConnectionPoolSize(5) // 마스터 노드 연결 풀 크기
                .setMasterConnectionMinimumIdleSize(2) // 마스터 노드 최소 유휴 연결 수
                .setSlaveConnectionPoolSize(5) // 슬레이브 노드 연결 풀 크기
                .setSlaveConnectionMinimumIdleSize(2) // 슬레이브 노드 최소 유휴 연결 수
                .setDatabase(0);
        RedissonClient client = Redisson.create(config);
        RBucket<String> name = client.getBucket("name");
        System.out.println(name.get());
    }

    /**
     * 센티넬 모드
     */
    @Test
    public void sentinelMode() {
        Config config = new Config();
        config.useSentinelServers()
                .setMasterName("mymaster")
                .addSentinelAddress("redis://10.49.196.20:26379")
                .addSentinelAddress("redis://10.49.196.21:26379")
                .addSentinelAddress("redis://10.49.196.22:26379")
                .setPassword("123456")
                .setMasterConnectionPoolSize(5) // 마스터 노드 연결 풀 크기
                .setMasterConnectionMinimumIdleSize(3) // 마스터 노드 최소 유휴 연결 수
                .setSlaveConnectionPoolSize(5) // 슬레이브 노드 연결 풀 크기
                .setSlaveConnectionMinimumIdleSize(3) // 슬레이브 노드 최소 유휴 연결 수
                .setCheckSentinelsList(false)
                .setDatabase(0);
        System.out.println(config.useSentinelServers().getSentinelAddresses());

        RedissonClient client = Redisson.create(config);
        RBucket<String> name = client.getBucket("name");
        name.set("zhaoyun");
        System.out.println(name.get());
    }

    /**
     * 클러스터 모드
     */
    @Test
    public void clusterMode() {
        Config config = new Config();
        config.useClusterServers()
                .setScanInterval(1000 * 2)
                .addNodeAddress("redis://10.49.196.20:7000", "redis://10.49.196.20:7001")
                .addNodeAddress("redis://10.49.196.21:7000", "redis://10.49.196.21:7001")
                .addNodeAddress("redis://10.49.196.22:7000", "redis://10.49.196.22:7001")
                .setPassword("123456")
                .setMasterConnectionPoolSize(5)
                .setMasterConnectionMinimumIdleSize(2)
                .setSlaveConnectionPoolSize(5)
                .setSlaveConnectionMinimumIdleSize(2);
        RedissonClient client = Redisson.create(config);
        RBucket<String> name = client.getBucket("name");
        name.set("zhaoyun");
        System.out.println(name.get());
    }
}

태그: Redisson Redis java 분산 시스템 NoSQL

7월 20일 00:22에 게시됨