Featured image of post [Django] API 성능을 개선해보자 : 캐싱

[Django] API 성능을 개선해보자 : 캐싱

Redis를 이용하여 데이터 캐싱하기

# 캐싱이란?

캐싱은 데이터나 계산 결과를 임시 저장소에 저장하는 프로세스를 말한다. 이는 데이터나 계산 결과를 나중에 빠르게 검색하거나 재사용할 수 있게 해준다.
캐싱은 방법에 따라 메모리나 디스크, DB등에 저장할 수 있다. 내 프로젝트는 현재 sqlite3이라는 내장DB를 하는데, 보통은 DB서버를 두는 게 일반적이다. 따라서 테스트를 위해 DB서버를 열고 연결해 주었다.

# 분석에 사용한 도구

  • Postman : 단일 API 호출과 Runner를 이용해 테스트를 진행했다.
  • Django-debug-toolbar : SQL이 어떻게 호출되는지 확인하는 데 사용했다.

# 전체공개 게시글 리스트를 호출하는 API

  • 글 : 10000개

# 개선 전

현재는 API를 호출할 때마다 쿼리 호출을 통해 DB에서 데이터를 받아 전달한다.

# 개선 과정

# Redis

Redis는 메모리 기반의 데이터 저장소이자 오픈 소스의 키-값 데이터 구조 저장소이다. 이를 이용하여 전체공개 게시글에 대해 캐싱을 해두고,데이터에 대해 변경이 있을 때만 업데이트했다.

# 왜 전체 공개 게시글인가?

캐싱을 이용하는 이유는

  1. 데이터 액세스 빈도가 높은 경우
  2. 네트워크 대역폭 절약
  3. 서버 부하 감소
  4. 실시간성이 필요하지 않은 데이터

정도로 볼 수 있다. 그중 전체 게시글에 적용한 이유는 다음과 같다.

  1. FUNSUN의 특성상 전체 공개 게시글의 업데이트 빈도는 낮으리라 예상했다.
  2. 검색 화면으로 진입 시 보여야 하는 데이터이기에 호출 빈도가 높을 것이라고 예상했다.

# 고려 사항

  1. 캐싱 제한
    광고등의 도배성 게시글로 인해 public 게시글에 대해 짧은 시간에 많은 POST 요청이 생길 수 있다는 약점을 고려하고 싶었기에 업데이트가 필요할 시 5초에 한번만 캐싱하게끔 제한을 걸었다.
  2. 코드의 작성
    READ를 제외한 CUD함수마다 코드를 중복하여 작성하고 싶지 않았기에 처음에는 미들웨어에서 제어하려고 했다. 하지만 이 방법은 요청 시 수행되는 작업이기 때문에 정작 업데이트되야 하는 정보가 반영이 안됐다. 이는 Funding 모델에 update_cache_if_public함수를 만들어 중복을 최소화했다.

# 개선 후

Redis를 통해 데이터베이스 호출 없이 게시글을 불러옴으로써 Response Time을 줄일 수 있었다.

# 추가 내용

# 추가적으로 적용될 수 있는 API는 무엇이 있을까

  • 사용자 프로필 : 정보를 한번 등록하면 업데이트가 자주 일어나지 않는다.
  • 펀딩한 게시글 리스트 : 개인 마다의 업데이트 빈도가 짧지 않다.

# 데이터 중복에 대하여

결국 캐싱을 한다는 것은 사실 데이터를 중복으로 가지고 있는 것과 같다. 디스크과 메모리에 있어서 리소스 낭비가 일어날 수 있기에 캐싱을 남발하는 것은 주의해야 할 것 같다. 적절한 데이터를 엄선하여 캐싱하는 것이 캐싱을 구현하는 것보다 훨씬 어려웠다.

Hugo로 만듦
JimmyStack 테마 사용 중