[Lettuce] Redis cluster 교체를 위한 설정 - topology refresh

by 스뎅(thDeng) on

Redis cluster

Redis cluster를 사용하면, 처음 seed node에 접속해서 클러스터 구성(topology)을 얻어온다. 각 노드들의 IP와 같은 접속 정보를 가져온다. 그런데, 간혹 노드 교체나 시스템 점검으로 구성이 바뀌면 문제가 발생하기도 한다.

Cluster topology가 바뀌면 자동으로 그 정보를 가져올 수 있는 설정을 까먹을까봐 정리..

Refresh Redis cluster topology

private fun createRedisClientConfiguration(redisProperties: RedisProperties, clientResources: ClientResources) =
        LettuceClientConfiguration.builder()
            .commandTimeout(redisProperties.timeout)
            .readFrom(ReadFrom.REPLICA_PREFERRED)                     // 읽기 명령은 replica에서 우선으로 실행
            .shutdownTimeout(redisProperties.lettuce.shutdownTimeout)
            .clientOptions(getClusterClientOptions(redisProperties))
            .clientResources(clientResources)
            .build()

private fun getClusterClientOptions(redisProperties: RedisProperties): ClientOptions {
    val topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
        .dynamicRefreshSources(true)                                  // default: true
        .enablePeriodicRefresh(redisProperties.lettuce.cluster.refresh.period)
        .enableAllAdaptiveRefreshTriggers()
        .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(30))       // default: 30초
        .build()

    return ClusterClientOptions.builder()
        .autoReconnect(true)
        .publishOnScheduler(true)
        .disconnectedBehavior(ClientOptions.DisconnectedBehavior.DEFAULT)
        .socketOptions(SocketOptions.builder().connectTimeout(redisProperties.connectTimeout).keepAlive(true).build())
        .topologyRefreshOptions(topologyRefreshOptions)
        .timeoutOptions(TimeoutOptions.enabled(redisProperties.timeout))
        .build()
}

topologyRefreshOptions는 topology가 변경되었을 때 감지하고 변경된 노드에 접속할 수 있도록 하는 설정이다.

Adaptive triggers lead to an immediate topology refresh. These refreshes are rate-limited using a timeout since events can happen on a large scale. Adaptive refresh triggers are disabled by default

- from [7.2.1. Cluster-specific options - Lettuce docs](https://lettuce.io/core/5.3.7.RELEASE/reference/index.html#clientoptions.cluster-specific-options)

DNS Cache

Redis cluster의 노드 정보가 DNS로 설정되어 있는 경우, 어플리케이션은 처음 seed 노드에 접속해서 DNS를 받아오게 된다. 이 때, 노드만 교체되고 DNS가 같은 경우 계속 이전 노드의 IP로 접속을 시도하게 된다. 새로 변경된 IP로 접속할 수 있도록 DNS 캐시 시간을 조절해야 한다.

JVM 실행 시 다음 설정이 있는지 확인한다. 설정이 없다면 기본값은 30초이고, networkaddress.cache.ttl 설정이 sun.net.inetaddr.ttl 보다 우선순위가 높다.

-Dsun.net.inetaddr.ttl=10

// 또는

-Dnetworkaddress.cache.ttl=10

참고

별도로 명시하지 않을 경우, 이 블로그의 포스트는 다음 라이선스에 따라 사용할 수 있습니다: Creative Commons License CC Attribution-NonCommercial-ShareAlike 4.0 International License