캐시 전략
Redis의 캐싱 전략
개발을 할 때에 Redis를 통해서 값을 캐싱시켜 둔다면, 더 빠르게 값들을 처리할 수 있다.
이 이유를 간단하게 말하자면 DB를 통해 값을 가져오는 것 보다 캐시에 있는 데이터를 사용하면 성능면에서 더 빠르기 때문이다.
그렇기 때문에 cache miss(캐시된 데이터가 없어서 DB를 통해 해당 값을 가져온다.)를 적게 하고 cache hit(캐시된 데이터에서 바로 값을 가져옴)를 최대한으로 해야 한다.
또한 캐시는 RAM데이터를 사용하는데, 이게 데이터가 크지 않기 때문에 이를 잘 관리해야 한다.
즉
- 최대한 DB서버를 통하지 않고 Redis를 통해 값을 받을 수 있도록 하기
- Redis의 크기를 효율적으로 관리하기
를 해내야 할 것이다.
이를 위한 전략들을 살펴보도록 한다.
읽기 전략(Read Cache Strategy)
Look Aside 전략
일반적으로 많이 사용되는 전략이다.
기본적으로 Cache에서 데이터를 확인하고, 여기 없다면 DB를 통해 조회해 오는 방식이다.
- 먼저 Cache에 데이터가 있는지 찾아봄
- 없으면 다음으로 DB에 데이터를 찾아봄
- DB에 데이터가 있는 경우 DB에서 가져온 데이터를 캐시에 저장
- 이후 데이터를 사용자에게 전달
이런 방식으로 진행된다.
- 장점
- 다수의 사용자가 'Read'연산을 하는 경우 빠른 속도를 보장한다.
- Redis가 중간에 뻗어도 DB를 통해 값을 가져올 수 있어서 서비스 장애가 나지 않는다.
- 캐시와 DB가 따로 존재하기 때문에 원하는 데이터만을 Redis에 저장 가능하다.
- 이를 통해 데이터를 낭비하지 않을 수 있다.
- 단점
- 'CUD'연산을 하는 경우, DB와 Cache data 사이의 정합성 문제가 발생할 수 있다.
- DB에는 변경되었지만 Cache Data에서 변경되지 않는경우
- 'Read'연산의 경우도 각각의 사용자가 다 다른 데이터를 불러오는 경우에는 적합하지 않다.
- 최초 실행시 Redis상에 데이터가 없다면 매번 DB를 통해 가져와야 한다.
- 이를 해결하기 위해 Cache warming(미리 데이터 캐싱)을 진행할 수 있다.
- 'CUD'연산을 하는 경우, DB와 Cache data 사이의 정합성 문제가 발생할 수 있다.
정리하자면
다수의 사용자가 비슷한 Data의 Read를 진행할 때에 알맞는 전략이다.
Read Through 전략
캐시에서만 데이터를 불러오는 전략이다.
사실 위의 Look Aside와 비슷하지만, 다른점은 Cache에 데이터가 없을 때에 Server가 아니라, Cache가 DB에 데이터를 조회하여 업데이트 한 후에 그 데이터를 보여주는 방식이다.
- 먼저 Cache에 데이터가 있는지 찾아봄
- 없으면 Cache가 DB에서 데이터를 찾아봄
- DB에 데이터가 있는 경우 DB에서 가져온 데이터를 캐시에 저장
- 캐시를 통해 이 데이터를 사용자에게 전달
과 같은 방식이다.
- 장점
- Server가 DB에 접근하지 않기 때문에 'Read'시 소모 자원을 줄일 수 있다.
- 단점
- 캐시가 뻗는 경우 캐시 서버가 SPOF가 될 수 있다.
- 따라서 Replication이나 Clustering을 통해 가용성을 확보해야 한다.
- 최초 실행시 Redis상에 데이터가 없다면 매번 DB를 통해 가져와야 한다.
- 이를 해결하기 위해 Cache warming(미리 데이터 캐싱)을 진행할 수 있다.
- 캐시가 뻗는 경우 캐시 서버가 SPOF가 될 수 있다.
쓰기 전략(Write Cache Strategy)
Write Back 전략
데이터를 삽입할 때에 이를 캐시에 보관해 두고, 일정 시간마다 DB에 저장시키는 방식이다.
쓰기가 굉장히 빈번하게 일어나는 경우 사용하는 방식이다.
-> 로그 데이터의 경우 굉장히 빈번하게 발생되고, 이를 DB에 매번 저장하기 그러니까 이 방식이 요긴하게 쓰인다고 한다.
- Cache에 데이터를 저장시켜 준다.
- 특정 시간마다 DB에 해당 데이터를 저장시킨다.
- DB에 데이터가 저장되면 Cache에서는 이걸 지울수도 있고, 가지고 있을수도 있다.
와 같은 방식이다.
참고로 DB에 데이터를 저장할 때에 굳이 모아서 배치로 하는 이유는 insert를 뭉탱이로 한꺼번에 처리해주면 연산이 훨씬 줄어서이다.(예를 들어 1000번의 데이터 입력을 1000번 DB에 insert를 보내는 것 보다 insert*1000으로 한번에 보내는게 빠른것)
- 장점
- 'Write'연산이 많은 경우 이를 Redis에 보관하기 떄문에 자원 소모를 줄일 수 있음
- 데이터 정합성이 확보된다
- 이는 캐시에서 데이터를 읽어오는데, 최신 데이터가 캐시에 보관되기 때문이다.
- 단점
- 중간에 캐시가 뻗으면 데이터가 없어져버림
- Cache에 읽을일도 없는 정보가 너무 많이 저장될수 있다.
- 그래서 저장 후 삭제하는 경우도 있다.
이는 로그 데이터처럼 write는 빈번하지만 읽을 일은 별로 없는 데이터의 저장에 알맞는 전략이다.
Write Through 전략
DB와 Cache에 동시에 데이터를 저장하는 전략이다.
- 데이터 write시 Cache에 데이터 저장
- Cache에서 이를 바로 DB에 저장(batch 아님)
- Cache에는 데이터 저장되어 있음.
이런 방식이다.
- 장점
- 'Write'한 데이터를 'Read'하는 경우 cache를 이용해서 해결 가능하다.
- 최근 데이터를 불러오는 일이 많은 경우(공통 최신 read가 많은 경우) 좋은 성능을 갖는다.
- 캐시-데이터간의 데이터 차이가 없다.
- 정합성도, 데이터 유실 위험도 없다.
- 'Write'한 데이터를 'Read'하는 경우 cache를 이용해서 해결 가능하다.
- 단점
- 'Write', 'Update'가 많은 경우 성능이 좀 별로다.
- Cache에서도 DB에서도 매번 변경하기 때문
- 읽을일 없는 쓸데없는 데이터를 가지는 경우가 있다.
- 'Write', 'Update'가 많은 경우 성능이 좀 별로다.
최신 피드를 가져오는 경우에 알맞는 전략이다.
Write Around 전략
데이터를 DB에 저장하고, 캐시에 값이 없는 경우 저장시켜주는 방식이다.
- 데이터 write시 DB에 데이터 저장
- 데이터 read시 Cache를 통해 찾아봄
- Cache에 해당 데이터가 없는 경우 DB를 통해 찾고, 서버가 해당 데이터를 DB에 저장해준다.
- 장점
- Write Through보다 속도가 빠르다.
- 매번 DB, Cache를 변경하지 않고 DB만을 변경하고 cache miss인 경우만 cache를 바꾸기 때문
- Write Through보다 속도가 빠르다.
- 단점
- 데이터 불일치가 발생할 수 있다.
- DB에서는 변경된 값이 Cache에서는 변경되지 않는 경우가 있을 수 있다.
- 이를 위해 Cache expire시간을 짧게 유지해야 한다.
- DB에서는 변경된 값이 Cache에서는 변경되지 않는 경우가 있을 수 있다.
- 데이터 불일치가 발생할 수 있다.