이전 실시간 채팅 클론코딩 프로젝트를 진행했을 때, Redis를 사용했었는데 회사에서도 Redis를 사용하고 있어 이에 대해 다시 다져보기로 한다.
Redis(Remote Dictionary Server)의 줄임말로, dictionary 구조 한마디로 key-value 형태로 데이터를 저장하고 관리하는 서버를 의미한다.
아래에는 공식 홈페이지(https://redis.io/)와 같이 Redis의 핵심기능에 대해 정리해보았다.
Redis는 데이터베이스, 캐시, 메세지 브로커 및 스트리밍 엔진으로 사용되는 오픈소스(BSD 라이선스), 인메모리 데이터 구조 저장소이다.
Redis는 strings, hashs, lists, sets, sorted sets, streams와 같은 컬렉션을 제공한다.
Redis에는 복제, Lua 스크립팅, LRU 추출, 트랜잭션 및 다양한 수준의 디스크 지속성이 내장되어 있으며 고가용성을 제공한다.
Redis Sentinel 및 Redis 클러스토를 통한 자동 파티셔닝을 제공한다.
1. 성능
모든 Redis 데이터는 메모리에 저장되어 대기 시간을 낮추고 처리량을 높인다.
평균적으로 읽기 및 쓰기의 작업속도가 1ms로 디스크 기반 데이터베이스보다 빠르다.
2. 유연한 데이터 구조
앞서 말했듯이 Redis의 데이터는 String, List, Set, Hash, Sorted Set, Bitmap, JSON 등 다양한 데이터 타입을 지원한다. 따라서, 애플리케이션의 요구 사항에 알맞는 다양한 데이터 타입을 활용할 수 있다.
3. 개발 용이성
Redis는 쿼리문이 따로 필요로 하지 않고, 단순한 명령 구조로 데이터의 저장 및 조회 등이 가능하다.
4. 영속성
Redis는 영속성을 보장하기 위해 데이터를 디스크에 저장할 수 있다. 서버에 치명적인 문제가 발생하더라도 디스크에 저장된 데이터를 통해 복구가 가능하다.
5. 싱글스레드 방식
Redis는 싱글 스레드 방식을 사용하여 한 번에 하나의 명령어만을 처리한다. 따라서 연산을 원자적으로 처리해 Race Condition이 거의 발생하지 않는다.
다만, 멀티 스레드를 지원하지 않기 때문에 시간 복잡도가 O(n)인 명령어의 사용은 주의해서 사용해야한다.
그렇다면 캐시는 무엇일까?
Cache는 '자주 사용하는 데이터나 값을 미리 복사해놓는 임시장소'를 의미한다. 캐시는 저장공간이 작고 비용이 비싼 대신 빠른 성능을 제공한다.
캐시란 나중에 요청할 결과를 미리 저장해둔 후 빠르게 서비스해주는 것을 의미한다. 즉, 미리 결과를 저장하고 나중에 올 요청에 대해 DB 또는 API를 참조하지 않고 캐시에 접근해 오청을 처리하게 된다. 이러한 캐시가 동작할 수 있는 철학에는 파레토법칙이 있다.
💡 파레토 법칙이란
80%의 결과는 20%의 원인으로 인해 발생한다는 것을 의미한다.

즉, 이것은 바로 캐시가 효율적일 수 있는 이유이다. 모든 결과를 캐싱할 필요는 없고, 그 말은 곧 우리는 서비스를 할 때 많이 사용되는 20%를 캐싱한다면 전체적으로 영향을 주어 효율을 극대화할 수 있다는 뜻이다.
모든 데이터를 캐시에 담기에는 캐시는 저장공간이 작다. 그렇기 때문에 파레토의 법칙에 해당하는 소수의 데이터를 선별해야만 한다. 이 때 사용 되는 것이 바로 지역성(Locality)이다.
💡 캐시의 지역성(Cache Locality)이란
캐시 메모리의 역할을 제대로 수행하기 위해서는 CPU가 어떤 데이터를 원할 것인가를 어느정도 예측할 수 있어야 한다. 캐시의 성능은 작은 용량의 캐시 메모리에 CPU가 이후에 참조할, 쓸모있는 저보가 어느 정도 들어있느냐에 따라 좌우되기 때문이다.
이 때 적중률을 극대화시키기 위해 데이터 지역성(locality)를 사용한다. 지역성의 전제조건으로 프로그램은 모든 코드나 데이터를 균등하게 Access하지 않는다는 특성을 기본으로 한다. 즉, Locality란 기억 장치 내의 정보를 균일하게 Access하는 것이 아닌 어느 한 순간에 특정부분을 집중적으로 참조하는 특성이다.
시간적 지역성(Temporal Locality)
특정 데이터가 한 번 접근 되었을 경우, 최근에 참조된 주소의 내용은 곧 다음에 다시 참조되는 것을 의미한다. 메모리 상의 같은 주소에 여러차례 쓰기를 수행할 경우, 상대적으로 작은 크기의 캐시를 사용해도 효율성을 꾀할 수 있다.
공간적 지역성(Spatial Locality)
기억장치 내에 서로 인접하여 저장되어 있는 데이터들이 연속적으로 엑세스될 가능성이 높아지는 특성을 가지고 있다.

Cache는 일반적으로 위와 같은 flow로 사용된다. 동일한 flow에서 어떻게 사용하냐에 따라서 look aside cache(Lazy Loading)와 write back으로 나뉜다.