728x90

Redisson은 Jedis, Lettuce 와 같은 자바진영의 레디스 클라이언트입니다.

Lettuce와 비슷하게 Netty 를 사용하며 non-blocking I/O 를 사용합니다. Redisson 의 특이한 점은 직접 레디스의 명령어를 제공하지 않고 , Bucket 이나 Map 과 같은 자료구조나 Lock 같은 특정한 구현체의 형태로 제공한다는 점입니다.

 

https://github.com/redisson/redisson

 

GitHub - redisson/redisson: Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects

Redisson - Redis Java client with features of In-Memory Data Grid. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map...

github.com

 

docker 로 redis 시작하기

docker run -d -p 6379:6379 --name myredis --network redisnet redis
docker exec -it my-redis /bin/bash
redis-cli

 

로 docker 안의 redis-cli 환경으로 진입합니다.

 

build.gradle.kt

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("io.spring.dependency-management") version "1.0.6.RELEASE"
    kotlin("jvm") version "1.7.20"
    kotlin("plugin.serialization") version "1.5.0"
    application
}

repositories {
    mavenCentral()
}

dependencyManagement {
    imports {
        mavenBom("io.projectreactor:reactor-bom:2020.0.18")
    }
}


dependencies {
    implementation("org.redisson:redisson:3.17.6")
    implementation("org.junit.jupiter:junit-jupiter:5.8.1")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.0")
    testImplementation("io.projectreactor:reactor-test:3.4.23")
    testImplementation("io.mockk:mockk:1.12.8")
    testImplementation("org.assertj:assertj-core:3.23.1")
    testImplementation("org.junit.jupiter:junit-jupiter-params:5.9.0")

    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.0")

    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs = listOf("-Xjsr305=strict")
        jvmTarget = "11"
    }
}

application {
    mainClass.set("MainKt")
}

 

RedisConfig

import org.redisson.Redisson.create
import org.redisson.api.RedissonClient
import org.redisson.api.RedissonReactiveClient
import org.redisson.config.Config

class RedisConfig {

    lateinit var redissonClient: RedissonClient

    fun getClient(): RedissonClient {
        return if (::redissonClient.isInitialized) redissonClient
        else {
            val config = Config()
            config.useSingleServer()
                .address = "redis://localhost:6379"
            redissonClient = create(config)
            return redissonClient
        }
    }

    fun getRedissionReactiveClient(): RedissonReactiveClient {
        return getClient().reactive()
    }
}

 

initialized 되어 있지 않으면 초기화를 하고 되어있으면 객체를 반환합니다.

Non-blocking RedissonClient 도 만들어 둡니다.

 

TestCode 를 실행하기전 BaseTest Class 를 만들어 줍니다.

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
abstract class BaseTest {
    private val redissionConfig = RedisConfig()
    lateinit var client: RedissonReactiveClient

    @BeforeAll
    fun setClient() {
        this.client = this.redissionConfig.getRedissionReactiveClient()
    }

    @AfterAll
    fun closeClient() {
        this.client.shutdown()
    }
}

 

Redis 에 저장하기 위한 Student data class 를 생성합니다.

data class Student(
    val name: String,
    val age: Int,
    val city: String
) {
    constructor() : this("", 0, "")
}

 

기본 생성자를 만든 이유는 Redis bucket 에 객체를 Set 할때

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.jongyun.redission.Student` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

 

기본 생성자가 없으면 다음과 같이 Deserialize 할수 없다고 에러가 발생합니다.

 

class KeyValueObjectTest : BaseTest() {

    @Test
    fun keyValueObjectTest() {
        val student = Student("jongyun", 28, "seoul")
        val bucket = this.client.getBucket<Student>("student:1", TypedJsonJacksonCodec(Student::class.java))
        val set = bucket.set(student)
        val get = bucket.get()
            .doOnNext { println(it) }
            .then()
        StepVerifier.create(set.concatWith(get))
            .verifyComplete()
    }
}

 

this.client.getBucket 의 두번째 인자로 Codec 전략을 지정했습니다.

 

 

 

728x90