개발놀이터

Redis for Client Side Caching (이론) 본문

CS 지식/데이터베이스

Redis for Client Side Caching (이론)

마늘냄새폴폴 2024. 7. 4. 21:40

이번 포스팅은 Redis 6부터 제공해주는 신기능 (무려 4년전 기술인 따끈따끈한 신기술입니다.) Redis for Client Side Caching에 대해서 공부해봤습니다. 

 

Client Side Caching

사실 이 내용을 공부하게 된 계기가 Client Side Caching을 공부하려고 했다가 영어로 구글링한 탓일까요... 제일 상단에 뜬 Redis 공식문서를 보고 공부하게 되었습니다. 

 

원래 우리가 흔히 말하는 Client Side Caching은 HTTP header인 Cache-Control과 ETag를 말합니다. 즉, 브라우저에 캐싱하는 것을 Client Side Caching이라고 하는 것입니다. 

 

이번 포스팅은 그 내용은 아니기때문에 다루지는 않겠습니다. 브라우저에서 캐싱하는 것은 어렵지 않은 내용이라 구글링해보시면 쉽게 접하실 수 있을 겁니다. 

 

Redis와 Client Side Caching

그럼 여기서 말하는 Client Side는 뭘까요? 바로 Redis Client입니다. 즉, Redis를 사용하는 곳이죠. Redis Server가 Client가 될 수도 있고, 흔히 생각하기로는 Spring Boot와 같이 Redis를 사용하는 애플리케이션이 될 것 같네요. 

 

처음 Redis의 공식문서를 읽어보면 결론은 이겁니다.

 

"Redis를 사용하는 클라이언트의 로컬에 캐시를 동기화해준다."

 

그럼 일단 왜? 라는 질문을 하게 되고 어떻게? 라는 질문이 따라왔습니다. 

 

왜?

그냥 Redis에서 요청하면 안되나?

왜 Redis가 클라이언트 (편의상 스프링이라고 하겠습니다.) 의 캐시를 업데이트 해줄까요? 그냥 Redis에 요청하면 안되나요? 

 

공식문서에선 "그렇게 하면 응답속도가 빨라지니까!" 라고 말합니다. 일단 일반적인 Redis에서 요청보낼 때와 얼마나 차이가 나는지는 알려주지 않았습니다. 때문에 일단 넘어가도록 하죠. 

 

응답속도가 빨라지면 좋긴 좋으니까요.

 

그럼 왜 동기화를 시켜야하지?

로컬 캐시의 좋은 점은 응답속도가 빠르다는 점입니다. 하지만 단점은 Redis Server에서 만약 값이 변경되면 로컬 캐시가 그걸 알아차릴 수 없습니다. 

 

그럼 Redis Server에서 값이 바뀌더라도 로컬 캐시에 오래된 데이터가 남아있어 사용자에게 실제 데이터베이스와 다른 값을 보여주기 때문에 문제가 됩니다. 

 

때문에 로컬 캐시와 Redis의 데이터들을 동기화시켜줘야합니다. 

 

어떻게?

근데 Redis랑 스프링은 서로 떨어져있는데 어떻게 Redis와 스프링의 캐시가 동기화될까요? 공식문서에선 그 대답을 "Invalidate Message" 라고 말합니다. 

 

https://www.linode.com/docs/guides/redis-client-side-caching/

 

How to Use Redis for Client-Side Caching

Modern web applications rely on client-side caching to enhance its performance. This guide shows you how to use Redis for server-assisted client-side caching.

www.linode.com

 

이 포스팅에서 어떻게 Redis로 Client Side Caching을 할 수 있는지 나와있습니다. 

 

직접 해보겠습니다. 

 

우선 도커로 Redis를 띄웁니다. 저는 Docker Desktop을 이용해서 띄웠습니다. docker-compose.yml 파일을 작성해줍니다. 

 

version: '3.8'
services:
  redis:
    image: redis:6
    container_name: redis
    ports:
      - "6479:6379"
    volumes:
      - redis-data:/data
    restart: unless-stopped

 

포트를 6379로 안한 이유는 제 컴퓨터에 이미 Redis for Windows 가 있어서 그렇습니다. 

 

그리고 docker를 띄우면?

 

 

잘 떴네요. 이제 cli로 접속해봅시다. docker로 띄운 Redis의 cli로 들어가기 위해서는 아래의 명령어를 입력해야합니다. 

 

docker exec -it <컨테이너이름> redis-cli

 

이걸 서로 다른 명령프롬프트로 들어가줘야합니다. 

 

 

왼쪽이 데이터를 변경하는쪽 (Master) 오른쪽이 데이터를 읽는쪽 (Slave) 이라고 가정하겠습니다. 

 

오른쪽 (읽는쪽) 에서 아래의 명령어를 입력합니다. 

 

subscribe __redis__:invalidate

 

그럼 Redis 내부의 Pub/Sub 메세지를 받을 준비를 합니다. 

 

그리고 왼쪽에선 아래의 명령어를 입력합니다. 

 

client tracking on redirect <읽는쪽 client id>

 

한번 진행해보죠. 

 

 

test라는 key로 "hello"라는 value를 저장했습니다. 

 

자 그리고 만약 test라는 key의 value를 바꿔주면?

 

 

읽는 쪽에서 메세지가 도착했습니다. "test라는 key가 변경되었다." 라는 메세지입니다. 

 

이렇게 Redis의 값이 변경되는 것을 확인할 수 있습니다. 

 

이 방법은 기존의 Redis의 프로토콜인 RESP2를 이용한 방식입니다. Redis 6에서 새롭게 선보인 RESP3는 다른 방식을 사용한다고 합니다. 하지만 본질은 같습니다. Invalidate Message를 이용하는 것이죠. 

 

Redis의 값을 변경해주는 것을 저는 Redis CLI에서 했지만 보통의 경우 Redis Client인 Spring Boot일 가능성이 높습니다. 그래서 이제 스프링과 한번 연계해서 보도록 하겠습니다. 

 

스프링과 캐시

우리의 목적은 스프링에서 저 값을 사용하는 것인데요. 제가 처음에 생각했던 것은 이거였습니다. 

 

아하 Pub/Sub 메세징이니까 스프링쪽에서 저 채널 (__redis__:invalidate) 을 subscribe로 열어두고 저 메세지가 오면 스프링에서 직접 설정해주는 거구나?

 

그 과정에서 @CachePut @CacheEvict 같은 어노테이션으로 로컬 캐시를 업데이트 하는거구나? 

 

저는 캐시라고 하길래... 그냥 곧이곧대로 캐시인줄 알았죠... 하지만 아니었습니다. 

 

무려... Map 자료구조와 Redis 데이터를 동기화하는 것이었습니다. 

 

처음에 subscribe로 뻘짓을 엄청나게 해댔는데 아래의 링크에서 Redis 개발자로 추측되는 사람이 자바로 예시 코드를 적어줬는데 처음에 보고 물음표를 수백개 띄울 수밖에 없었습니다. 이게 된다고?

 

https://github.com/redis/lettuce/issues/1281

 

Add support for Client-side caching · Issue #1281 · redis/lettuce

See https://redis.io/topics/client-side-caching

github.com

 

이게 최신기술이라 사람들이 많이 안써봐서 그런가 예제코드를 찾아보기 힘들었고 겨우겨우 찾았습니다. 다음 포스팅에서 직접 스프링과 연동해서 실습해보겠습니다. 

 

 

출처

https://redis.io/docs/latest/develop/use/client-side-caching/

 

Client-side caching in Redis

Server-assisted, client-side caching in Redis

redis.io

https://www.linode.com/docs/guides/redis-client-side-caching/

 

How to Use Redis for Client-Side Caching

Modern web applications rely on client-side caching to enhance its performance. This guide shows you how to use Redis for server-assisted client-side caching.

www.linode.com