본문 바로가기
개발 지식/Backend

[Redis] All keys must map to the same slot for MSETNX command

by 에르주 2023. 11. 17.
반응형

실무 개발 레디스 활용 중 값이 없을 경우 set하는 부분이 있었다.

 

ReactiveRedisTemplate를 활용하여 MSETNX (multiSetIfAbsent) 을 하는 경우를 적용하여 테스트 진행 했는데 다음과 같은 오류가 발생하였다.

All keys must map to the same slot for MSETNX command

 

해당 오류는 Redis Cluster에서는 MSET이 지원하지 않는 command라 발생한 상황이었다.

이에 반복분을 통해 SET하는 것으로 수정했는데 그 이유가 궁금했다.

 

 

예를 들어 Redis Cluster를 4개로 구성했다고 하였을 때 각각 Cluster당 hash slot를 배정 받게 된다.

A-Node : 1 ~ 800
B-Node : 801 ~ 1600
C-Node : 1601 ~ 2400
D-Node : 2401 ~ 3200

 

Redis에 데이터를 set 커맨드 발생시 은 Redis 내부적 알고리즘(CRC16 해시 알고리즘)을 통해 각 키의 해시 슬롯을 계산한다.

저장하려는 키의 해시 슬롯을 바탕으로 A, B, C, D Node 중 하나에 SET하게 된다.

 

즉 그렇기 때문에 MultiSet, 여러키에 대한 작업을 포함하므로 하나의 슬롯이 아닌 여러 해시 슬롯에 걸쳐 분산될 가능성이 있기 때문이다.

 

하나의 트랜젝션 내 에서 일관성을 유지하기 위해 동일한 해시 슬롯에 저장을 진행해야 하는데 그렇지 못하고 해당 값에 대한 원자성이 보장되지 않아 지원하지 않는 것이다.

 


 

 -- 추가 -- 

Redis Cluster 환경에서 Spring redisTemplate를 활용하여 SETNX (setIfAbsent) 하려고 하였다.

 reactiveRedisTemplate.opsForValue().setIfAbsent("ms", "er").subscribe()

 

나의 의도 > key값으로 ms가 없다면  "ms", "er"을 key-value 값으로 저장, 있으면 저장하지 않음

 

실제 코드 실행 > 일부 key-value 값들은 redis에 있더라도 set Command 날린다.

 

데이터 각각의 클러스터로 분산 처리 되기 때문에 해당 키가 여러 노드에 걸쳐 존재하는 경우 Absent 일부 특정 데이터는 없다고 판단할 수 있다. 

 

그렇기 때문에 SET 명령이 실행 될 수 있다.


레디스 클러스터 내부적으로 MOVE를 활용하여 다른 노드의 데이터 파악이 가능하다. -> 이유는 계속 찾아봐야 할 것 같다.

 

 

 

 

 

반응형

댓글