본문 바로가기
개발 이야기

Redis Cluster 환경에서 'DEL Collection'은 왜 안 될까?

by 신재권 2024. 7. 20.

레디스를 로그로 활용해 스케줄링으로 수집하는 로직을 만들 때 발생했던 이슈이다.

사실 increase로 쉽게 개발할 수 있었는데, 그 땐 increase를 몰라서 선택지에 두지 않았다.

 

저장한 키는 prefix_datetime 이런 구조였다. datatime에 ms 단위까지 저장하기 때문에 거의 겹칠일이 없었고, 반드시 수집해야하는 로그도 아니여서 겹칠 수 있다는 상황 자체를 고려하지 않았다.

쨋든, 스케줄링의 역할은 하루에 저장된 여러 개의 prefix_datetime 키가 몇개있는지 찾아와 저장하고, 삭제하는 방식이였다. (사실 삭제할 필요도 없었다. TTL을 걸었다면 .. 옛날의 나는 여기까지는 생각못했던 것 같다.)

 

로컬에서 prefix를 기준으로 키를 가져와 데이터 개수를 세고, 삭제한 후, 가져온 키들을 삭제 시키는 로직을 만든 후 테스트까지 돌려보았다. 하지만 테스트 환경에 배포하니 새벽에 오류 발생하였다.

(error) CROSSSLOT Keys in request don't hash to the same slot

 

오류 내용을 찾아보니, 클러스터 환경에서는 prefix 기준으로 키 여러개 삭제를 지원하지 않는다고 한다.

레디스 클러스터에서 데이터 분산을 위해 사용된 Hash Slot 때문에 발생하는 문제이다. -> 레디스 클러스터는 키들이 클러스터의 어떤 노드에 저장될지 정하는 해싱 알고리즘이 있다.

분산 환경에서 서로 다른 슬롯, 복수의 노드에 영향을 미치는 작업을 수행하면 문제가 생길 수 있다고 판단하여 복수의 키를 하나의 명령으로 처리하지 못한다.

 

정리하면 레디스 클러스터는 데이터를 여러 노드에 분산하여 저장한다. -> 각 노드는 다수의 슬롯을 관리한다. -> 해당 구조에서 DEL Collection 연산이 슬롯 단위만 가능하다.

 

두 가지 해결 방법이 존재하였다.

1. 반복문을 통해 키를 하나하나 삭제하는 방식

2. 해시 태그를 사용하여, 하나의 슬롯에 강제로 몰아서 저장

여기서 최종적으로 2번을 선택하였고 해당 문제를 해결하였다. (사실 DEL Collection 자체가 O(N)이라 위험한 연산인데 그 때 당시에는 그것을 고려하지 못했고 개발하였다.)

 

지금 다시 개발한다면 다음과 같이 개발할 것 같다.

1. increase로 단일 키 사용

2. 여러 키를 사용하되 TTL 적용

그냥 Del Collection을 피하는 방향으로 갈 것같다.

 

해당 경험을 통해 클러스터 환경에 이해하는 계기가 되었고, 기술의 깊이 있는 이해가 중요하다는 것을 다시 한번 상기하였다.