[입개발] Redis: 왜 Redis에서 어플리케이션에서 keys를 사용하면 안되는가?

@lqez 님께서 http://blog.naver.com/ez_/140172846856에 Redis KEYS 명령어 라는 제목으로 좋은 글을 올려주셨습니다. 그 내용을 살펴보면 keys 가 O(n)의 시간 복잡도를 가지고 또한, 메뉴얼에 어플리케이션에서 쓰지 말라고 되어 있는 것에 대한 분석을 하셨습니다. 저는 그냥 간단히 왜 이런 구조가 되었고, 쓰면 어떤 일들이 벌어지는지에 대해서 추가 설명을 조금 하고자 합니다.

 

일단 keys 명령은 기본적으로는 모든 key들을 넘겨주는 함수입니다. 즉, 전체를 다 체크해서 가져와야 되는 형태인거죠. 그리고 파라매터로 정규표현식을 받을 수 있습니다. 이를 통해서 keys a.c 이러면 abc, acc, aac 등 세 글자의 a와c로 끝나는 모든 key들을 가져올 수 있습니다. 사실 여기서 부터 비극이 시작됩니다. 많은 분들이 key 이름에 규칙을 부여하고, 나중에 이 key들을 쉽게 찾기 위해서 keys 명령을 어플리케이션 내부에 추가하시는 겁니다.(편리하기 때문이죠)

 

그럼 왜 keys를 쓰면 안되는가? 정규 표현식등을 keys에서 처리할려고 하다보니 해쉬를 쓸 수 없고, 결국, 전체를 다 스캔하게 되는데, Redis는 싱글 스레드로 동작합니다. 즉, 이 작업이 끝날 때 까지는 다른 일을 처리 못하는 것이죠. 그래서 이런 작업을 하면 보통 안에 key들이 수천 부터 수백만 이상 들어가 있습니다. 그러니, 시스템이 종종 멈추는 것 처럼 보이는 현상이 여기서 발생하게 됩니다.

 

그럼, 대안은 주고 쓰지 말라고 해야되지 않느냐? 라고 물어보실 분이 계실껍니다. 현실적인 대책은 sorted set 이나 해쉬 이름을 규칙에 맞게 정하고, 거기에 적합하게 저장해놓고, 해당 set의 이름을 통해서 가져오는 것입니다.  실제로 전체를 다 검색할 필요도 없어지고, keys에 비해서 훨씬 빠르게 처리할 수 있습니다. 다만, 이름으로 구별하기가 좀 힘들었던 경우에는 잘 고민할 필요가 있을듯 합니다.