follow api 에서
followListRedisRepository.set(hashtagId, userId);
이렇게 hashtagId를 key로, userId를 value로 삽입하는 작업을 하는데 오류가 났다.
아예 저장이 안된거면 모를까 저장이 될 때도 있고 안 될 때도 있어서 감이 잘 안왔는데
찾아보니 ElasticCache에서 클러스터 모드를 사용할 때 클라이언트가 잘못된 노드로 요청을 보내면 발생하는 오류라고 한다. 그니까 요청이 노드를 제대로 찾아갈 때도 있고 잘못 찾아갈 때도 있어서 삽입이 됐다 안됐다 한거였다 ..
ElasticCache로 Redis 서버를 운영할 때 모드가 3가지로 분류된다.

Redis 의 기본설정 모드이다.
하나의 Redis 인스턴스로 서비스를 하는 방식으로 인스턴스가 죽으면 서비스도 다운되므로, 다른 방법을 사용하는게 좋다.

Redis에 Master / Slave 노드를 분리하여 모니터링 하는 서버를 Sentinel 이라 한다.
감시자는 Master 노드가 죽으면 Slave 노드를 Master 노드로 승격시킬지 투표하여 과반수로 결정한다.
정상적인 기능을 위해선 적어도 3개의 Sentinel 인스턴스가 필요하며 각 Sentinel 인스턴스는 Redis의 모든 노드를 감시하며 서로 연결되어 있다.

Master 노드를 여러 개 두어 자동으로 데이터를 분산 저장(데이터 샤딩)하고, 일부 노드가 죽더라도 다른 노드에는 영향이 가지 않으며 죽은 노드의 데이터는 Slave 노드가 복구할 수 있게 하는 방식이다.
난 저장하는건데 왜 잘못된 노드로 요청이 갔다고 하는거지?
이걸 알려면 클러스터의 동작 방식에 대한 이해가 필요하다.
Redis Cluster 환경에서 동작 방식은 이러하다.
Redis 클러스터에서의 키 슬롯
Redis 클러스터는 모든 키를 16384개의 슬롯으로 분할한다.
각 키는 해싱 알고리즘(특히 CRC16 해시 함수)을 통해 특정 슬롯으로 매핑된다.
1. key 값을 CRC16 해시를 통해 계산.
2. 해시 값을 16384로 나눈 나머지가 슬롯 번호가 된다.
3. 각 슬롯 번호는 클러스터 내의 특정 노드에 할당된다.
올바른 슬롯이란, 키 값(여기선 hashtagId)가 해시 함수에 의해 계산된 슬롯을 담당하는 노드를 뜻한다.
클라이언트가 특정 노드에 연결했지만, 해당 노드는 hashtagId에 대한 슬롯을 담당하지 않을 수 있다. (이래서 간헐적인 것)
MOVED란, Redis가 요청 키 값에 대해 “이 키는 다른 노드에 있습니다”라고 알리는 것이다.
Redis 설정파일에서 RedisClient에 대해 클러스터 모드를 올바르게 설정하지 않아 단일 노드로 설정돼 잘못된 노드로 요청이 가고 있었던 것이다.
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
나는 Lettuce 를 Redis Client로 사용하고 있어서 LettuceConnectionFactory 에 host 와 port 만 지정해줬는데 클러스터 모드 사용시 RedisClusterConfiguration을 사용해서 클러스터 설정을 해줘야 한다.
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration()
.clusterNode(host, port);
return new LettuceConnectionFactory(clusterConfig);
}