Python에 redis cache를 적용하면서 view count... 방문자가 올때 카운트 값을 1을 늘리기위해 데이터베이스를 업데이트하는 일이 너무 비효율적으로 보였다. 뭔가 방법이 없을까?

만약 방문자의 일일 페이지뷰가 100만명이라면 최소 100만번의 데이터베이스 콜과 업데이트가 이루어지게된다... 아무리 적은 데이터라도 데이터베이스에 이렇게 많은 콜 request는 매우 비효율적일 것이다. 좋은 방법이 없을까 고민하면서 캐쉬서버 redis를 최대한 활용하면 더 좋을 것 같다.



# 얼마나 데이터를 잃을 수 있는가

사실 이 부분은 데이터를 잃을 수 있다는 여지를 남겨놓으면 콜을 줄이고 DB성능을 크게 향상 시킬 수 있게된다. 즉, redis서버가 의도하지 않게 종료되고 일부 값이 유실되어도 큰 문제가 되지 않는다면 말이다. 다행인건 방문자 접속 후 반복적으로 1카운트뷰가 추가될때마다 이루어지는 카운트의 업데이트가 아주 주요한 .. 반드시 지켜야하는 것이 아니며 항상 동기화하지 않아도 된다는 점이다.


# redis를 활용한 뷰 카운트 만들기

자 계획을 세웠으니 실제 구현을 위한 좀 더 새부적인 계획을 세우자. 먼저 뷰카운트를 데이터베이스에 저장하는 주기를 10분 단위로 정하였다. 방문자가 웹사이트에 접속하면 주데이터베이스가 아닌 redis서버의 key에 id를 추가하며 시간 10분마다 주데이터베이스에 한번에 반영하는 방법이다. 매우 간단하지만 위 100만번의 request가 한시간인 6번 * 24시간 = 144번으로 줄어들게된다... 대용량 서비스의 경우 무시할 수 없는 수치일 것이다.


! View count를 redis에 업데이트시 고려할 점먼저 redis 키는 최소한으로 생성하되 2개를 만들려고한다... 하나는 방문자가 보게되는 콘텐츠 페이지의 id값을 저장하게 한다. 그리고 또 다른 하나는 마지막으로 redis를 주 데이터베이스에 업데이트 한 마지막 시간을 저장한다. 정리하면...

  • 방문자로 인해 1뷰 증가시 redis의 방문자의 key에 id 추가
  • 마지막 업데이트 시간을 확인하고 10분이 지나면 이를 주 데이터베이스에 반영 및 key값을 현재 시간으로 업데이트

이때 고려할 부분은 각각의 id는 ,를 구분자로 str으로 길게 연결하는 최대한 단순하게 저장한다. 그리고 10분이라는 시간은 방문자가 적다면 더 길게 가져가도 좋다. 30분 단위... 1시간이라도 큰 문제는 없다. 반대로 방문자가 너무 많은 경우 이를 짧게하여 5분, 1분 단위도 생각해볼만하다.

사실 이 정도만으로도 충분하지만 걸리는 부분이있다.. 바로 ExpireTime을 알기위해 방문자 접속시 매번 redis key를 조회해야한다는 점이다... 물론 In-Memory로 cost가 적다할 수 있지만 개발자래서 개선의 여지가 필요해보인다. 그래서 매번 redis key를 조회하지 않고 조회하는 시간을 설정하는 방법을 고려할 수 있다.


! 그럼 어떻게 구현하는가?이 방법은 redis key를 조회하는 시간을 정해서 항상 조회하지 않도록 제한하는 방법이다. 예를들어 현재의 서버시간을 가져와 0에서 60분 사이에 0이 들어가는 경우... 즉 0, 10, 20 ... 60분인 총 6분 사이에만 redis를 조회하므로 redis 조회를 1/6로 상당히 줄일 수 있다. 다만 일부 콘텐츠... 인기가 없는 콘텐츠의 경우에는 반영이 나중에 될 수 있는 부분이 있다.

혹시 이런 경우 일부 콘텐츠의 카운트 수가 반영되지 않느냐 물을 수 있다. 실제로 그럴 수 있음이 사실이다. 다만 이런 일을 없도록 하기 위해 redis 캐시를 만료하는 경우에 남아있는 데이터를 주서버에 업데이트 갱신하는 과정이 추가되어야 할 것이다. redis를 캐시용도로 사용하는 경우 정기적인 갱신은 추천 할만하다. 데이터가 계속해서 쌓일 수 있는 여지를 없애기 위해서이다.


# 마치면서

이런 고민은 어떻게하면 좀 더 효율적인 아키텍쳐를 가질 수 있을까에 대한 고민의 연장선에 있다... 모든 데이터를 캐싱하면 좋겠지만 그럴 경우 맨 처음 개발 초기단계부터 이런 부분을 사전에 고려 및 설계하여야 수월하게 진행될 수 있을 것이며 완전 새로 개발하는 것이 나을 수도 있다... 개발 시간도 중요하지만 계획를 세우고 설계하는 시간을 느리는 것도 더더욱 중요할 것이다..