Java 환경에서 Redis 클라이언트(Jedis 및 Lettuce) 연동하기

Redis 서버 원격 접근 설정

Redis는 배포 시 기본적으로 127.0.0.1 루프백 인터페이스에만 바인딩되어 있어 외부 네트워크에서의 접근이 제한됩니다. 애플리케이션 서버가 원격에서 Redis 인스턴스와 통신하려면 redis.conf 구성 파일을 다음과 같이 수정해야 합니다.

  • bind 127.0.0.1 지시어를 주석 처리하여 모든 네트워크 인터페이스에서 연결을 수락하도록 변경합니다.
  • requirepass 항목의 주석을 해제하고, 보안 강화를 위해 강력한 인증 비밀번호를 설정합니다.

설정 파일을 저장한 후 Redis 서비스를 재시작하면 외부 클라이언트의 접근이 활성화됩니다.

Jedis 클라이언트 활용

의존성 추가 및 기본 연결

Maven 프로젝트의 의존성 관리 파일에 Jedis 라이브러리를 추가합니다. Jedis는 Redis 명령어와 Java 메서드가 1:1로 대응되어 있어 직관적인 API 사용이 가능합니다.

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.8.0</version>
</dependency>

기본적인 연결 수립 및 상태 확인 로직은 다음과 같이 구현합니다.

import redis.clients.jedis.Jedis;

public class JedisConnectionTest {
    public static void main(String[] args) {
        String serverHost = "192.168.10.50";
        int serverPort = 6379;

        try (Jedis client = new Jedis(serverHost, serverPort)) {
            client.auth("securePass123");
            String response = client.ping();
            System.out.println("Connection Status: " + response);
        }
    }
}

커넥션 풀 및 안전한 자원 관리

Jedis 객체는 스레드에 안전하지 않으므로, 동시성 환경에서는 반드시 커넥션 풀을 통해 인스턴스를 재사용해야 합니다. try-with-resources 구문은 예외 발생 시에도 자원 반납을 보장하지만, 콜백 패턴을 도입하면 풀 관리 로직과 비즈니스 로직을 명확히 분리할 수 있습니다.

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisTemplate {
    private final JedisPool pool;

    public RedisTemplate() {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(16);
        config.setMaxTotal(64);
        config.setMaxWaitMillis(5000);
        config.setTestOnBorrow(true);

        pool = new JedisPool(config, "192.168.10.50", 6379, 5000, "securePass123");
    }

    public void execute(RedisCallback operation) {
        try (Jedis conn = pool.getResource()) {
            operation.invoke(conn);
        }
    }

    @FunctionalInterface
    public interface RedisCallback {
        void invoke(Jedis connection);
    }
}

위 템플릿을 활용하면 호출 측에서는 연결 획득 및 반납 절차를 신경 쓰지 않고 명령어 실행에만 집중할 수 있습니다.

public class AppClient {
    public static void main(String[] args) {
        RedisTemplate template = new RedisTemplate();
        template.execute(conn -> {
            System.out.println("Server Ping: " + conn.ping());
        });
    }
}

Lettuce 클라이언트 아키텍처 및 적용

Jedis와의 차이점

Lettuce는 Netty NIO 프레임워크를 기반으로 구축되어 있어 근본적으로 스레드 안전성을 확보합니다. Jedis와 달리 단일 연결 객체를 다중 스레드가 안전하게 공유할 수 있어 커넥션 풀 오버헤드가 적습니다. 또한 동기, 비동기, 반응형(Reactive) 프로그래밍 모델을 모두 공식 지원하여 현대적인 애플리케이션 아키텍처에 적합합니다.

동기화 API 기본 사용법

Maven 의존성을 설정한 후, URI 스키마를 활용하여 클라이언트를 초기화합니다.

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>5.3.7.RELEASE</version>
</dependency>

동기 호출을 수행하는 경우 RedisClient에서 연결을 생성하고 sync() 메서드를 통해 명령어를 실행합니다.

import io.lettuce.core.RedisClient;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;

public class LettuceSyncDemo {
    public static void main(String[] args) {
        String redisUri = "redis://:securePass123@192.168.10.50:6379";
        RedisClient client = RedisClient.create(redisUri);
        StatefulRedisConnection<String, String> connection = client.connect();
        RedisCommands<String, String> syncCommands = connection.sync();

        syncCommands.set("session_token", "abc-123-xyz");
        String storedValue = syncCommands.get("session_token");
        System.out.println("Retrieved Data: " + storedValue);

        connection.close();
        client.shutdown();
    }
}

태그: Redis jedis Lettuce java connection-pool

9월 15일 17:23에 게시됨