seminar-2020 icon indicating copy to clipboard operation
seminar-2020 copied to clipboard

Database Caching에 대한 질문

Open YeonghyeonKO opened this issue 4 years ago • 3 comments

client에서 get, filter 등의 동작으로 db를 조회한다고 했을 때, index도 충분히 좋은 방식입니다. 그러나 caching 오픈소스(redis, memcache 등)을 사용하면 읽기 동작 수행 시 데이터를 메모리에 저장하여 서버의 부하를 더욱 줄일 수 있고, caching 오픈소스를 통해 데이터를 여러 노드에 저장하여 Scale-out을 가능하게 해준다고 합니다.

image

위의 사진에서처럼 update를 제외한 select, insert문은 db에 직접 request를 날리는 횟수가 현저히 줄어듭니다. 이때 insert문이 select와 같은 정도로 줄은 이유를 찾아보니 버퍼로 캐시를 사용하여 "모아쓰기"(사실 이 기능 잘 모릅니다.) 기능을 사용해서 그렇다고 합니다.

여기서 질문이 있는데, 서울대학교 수강신청 시스템(방금 들어가봤는데 웹프론트가 완전히 바뀌었네요. 감상하시길)을 예로 들었을 때를 예로 들어보겠습니다. (비록 강의 수가 1000개는 넘을지 모르겠지만 1억개라고 가정하면)

수강신청이 08시 정각에 시작한다고 했을 때, 수강신청 가능 시간을 제외한 강의 검색 화면은 강의자가 수강편람을 업데이트(시간대, 인원 등)하기 전까지 모든 사용자들에게 똑같이 보입니다. 이때 게으른 수백만 명의 서울대 학생들이 수강신청 한 시간 전부터 시간표를 짜기 시작한다면 cache를 이용하여 DB의 부하를 줄일 수 있을 것입니다.

다만 문제는 정각 08시부터인데, 기존의 "수강신청인원" column이 더 이상 0명이 아닌, [0, max(수강신청인원)] 사이에서 변경을 거듭하게 됩니다. 하지만 "수강신청인원" column을 제외한 나머지 column에 대해서는 변동사항이 없기에 기존의 cache를 그대로 사용할 수 있다는 생각이 듭니다. database cache 또한 공간을 희생하면서 시간을 단축시키려는 노력이고, 이 역시 Index와 마찬가지로 database의 형태를 띤다고 알고 있습니다. 따라서 만약 기존의 cache에서 "수강신청인원"과 관련된 부분만 유동적으로 바꾸고 나머지를 그대로 활용한다면 훨씬 효율적인 DB를 구축할 수 있을 것 같습니다. 이에 대해 찾아보려고 했는데, 잘 나오지 않아 세미나 참여자 및 진행자분들의 고견을 여쭙고 싶습니다.

(+) 여담인데 실제 서울대학교 수강신청 사이트에서는 수강신청 시간에 강의 검색을 하려고 하면 "부하시간에는 강의 검색이 불가능합니다"라는 문구가 나옵니다. 서버가 터지는 것을 막기 위한 잠금장치인 것 같은데 이를 해결하기 위해 어떤 방법이 있을지 고민하는 것도 재밌을 것 같습니다.


참고로 아래 사진은 제가 이해하고 있는 일반적인 cache를 포함했을 때의 서버 구조입니다.

image

출처

https://www.slideshare.net/charsyam2/webservice-cache-strategy?ref=https://charsyam.wordpress.com/ https://docs.djangoproject.com/en/3.1/topics/cache/#database-caching https://medium.com/@chrisjune_13837/redis-vs-memcached-10e796ddd717

YeonghyeonKO avatar Oct 17 '20 03:10 YeonghyeonKO

가장 최근에 머릿속에 든 생각은 수강신청 table에서 "수강신청인원"만 따로 분리하는 방식일텐데 이를 위해서는 "수강신청인원"을 계산하기 위한 연산(Count 및 수강신청 인원 초과 제약을 걸기 위한 로직 등)이 더 부하를 주지 않을 합니다. 굳이 caching을 사용해야하는 상황이 아닌데 욕심을 부리는건 아닌가 생각도 드네요.

YeonghyeonKO avatar Oct 17 '20 03:10 YeonghyeonKO

좋은 예시와 충분한 보조자료가 잘 활용된 좋은 글이네요, 감사합니다. caching과 RDB의 table, column 구조는 거의 완전히 무관하다고 생각하시면 됩니다. 일반적인 cache는 그냥 key, value 형태로 내가 원하는 key에다가 정말 원하는 아무 data를 저장할 수 있습니다. value에 들어갈 수 있는 것이 DB에서 뽑아내지 않은 값일 수도 있고, 그냥 DB에서 뽑아낸 값을 일부만 가공한 값일 수도 있는 것입니다. 때문에, 예로 들어주신 수강신청의 경우에는 시간대에 상관 없이, caching을 이용하고 싶다면 애초에 항상 caching을 '수강신청인원'을 빼놓고 하면 될 것 같습니다. 말씀해주셨듯이 실시간성이 강한 데이터는, 4번째 세미나에서도 언급했듯 캐싱하지 않는 것이 바람직할테니까요!

원하시는 답변이 맞을지 궁금하네요.

davin111 avatar Oct 17 '20 05:10 davin111

아하 그렇군요. 실제로 써보면 더 잘 와닿을 것 같습니다. 감사합니다!

YeonghyeonKO avatar Oct 17 '20 05:10 YeonghyeonKO