TIL-088 | Django's Cache Framework의 FetchFromCacheMiddleware의 활용

Lee, Chankyu·2022년 3월 1일
post-thumbnail

🌈 Django's Cache Framework의 FetchFromCacheMiddleware의 활용

🧐 지난 TIL-085 글을 통해 Homes 프로젝트에 Redis를 활용한 캐싱을 적용했었다. 원했던 간단한 기능을 구현했었기에 점차 범위를 넓혀갈 계획이었는데 마침 스터디 팀원으로부터 Django에서의 캐싱 관련한 질문을 받게 되었다. 질문은 다음과 같다.

" 캐싱이 잘 되어서 캐싱된 데이터가 무사히 리턴이 되는데 캐싱된 이후로 소스코드를 무시하는 것 같아요. print() 함수를 사용해도 전혀 출력이 안됩니다."

팀원 분은 Redis를 사용하진 않고 LocMemCache 메모리 캐시를 사용하였는데 이 이슈를 해결하면서 공부한 내용을 간단하게 정리하고자 한다.

Django 개발 환경에서의LocMemCache

  • 일반적으로 Redis와 Memcached를 많이 비교하지만 스터디 팀원이 활용한 로컬메모리 방식으로 적용해 보았다.

settings.py

✔ Redis

#Redis
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
  • 지난 글을 통해 소개한 적 있었던 django-redis 라이브러리 사용시 추가했던 소스코드이다.

LocMemCache

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 
    } 
}
  • LocMemCache 활용시 위와 같은 소스코드를 추가하도록 한다.
  • 'TIMEOUT' : 3600 과 같은 설정을 추가하기도 한다.

Middleware -> 이슈 발생의 원인

  • settings.py 설정시 MIDDLEWARE에 아래와 같은 미들웨어를 추가하기도 한다.
MIDDLEWARE = [
   'django.middleware.cache.UpdateCacheMiddleware', 
   'django.middleware.cache.FetchFromCacheMiddleware',
   ]
  • 결론부터 이야기하자면, 위에서 언급한 문제가 발생한 원인은 미들웨어에 있었다. 추가된 2개의 미들웨어중 'FetchFromCacheMiddleware' 로 인해 팀원분이 얘기한 이슈가 발생한 것이었다.

  • setting.py에 'FetchFromCacheMiddleware'가 적용되어 있을때는 아래의 그림과 같이 한번 캐싱된 이후에는 print() 가 작동하지 않는 것 처럼 보인다. (두 번째 호출 시, "걸린 시간: 0.XXXXXX"가 출력되지 않는 것을 볼 수 있다.)

  • 하지만 해당 미들웨어를 주석처리하면 캐싱된 이후에도 print() 함수가 잘 작동하는 것을 확인할 수 있었다.


🙆‍♂️ Django 공식 문서에서 'django.middleware.cache.FetchFromCacheMiddleware' 에 대한 설명을 보면 아래와 같이 명시되어있다.

📝 "FetchFromCacheMiddleware caches GET and HEAD responses with status 200, where the request and response headers allow. Responses to requests for the same URL with different query parameters are considered to be unique pages and are cached separately. This middleware expects that a HEAD request is answered with the same response headers as the corresponding GET request; in which case it can return a cached GET response for HEAD request."

  • 요약해보자면, 이 미들웨어는 httpstatuscode 200으로 GET 과 HEAD 응답을 캐시하고, 쿼리 파라미터가 다른 동일한 URL에 대한 요청에 대한 응답은 고유한 페이지로 별도로 캐시된다는 것이다.

  • 다양한 테스트를 해보며 최대한 이해하려고 했지만, 사실 아직 이 문장이 100% 이해 되진 않는다. 아니 정확히는 문장은 이해가 되지만 이 미들웨어의 활용성과 존재 이유 등을 모르겠다.


🙆‍♂️ 개발을 하며 맞닥뜨리게 되는 다양한 이슈 혹은 현상들에 대해서 원인을 찾는것이 점점 익숙해지는 것 같다. 그리고 찾는 속도도 점점 빨리지고 있다. 공식 문서와 그 외에 다양한 문서를 보는 속도가 빨라지는 것도 있겠지만 예상치 못한 현상에 대해 원인을 추론하는 능력이 상승한 것 같다. 예전엔 에러메시지와 현상 그 자체에 대한 묘사로 구글링에 의존했다면 이제는 내가 생각하기에 가능성 있는 요소에 대한 검색도 해보며 좀 더 빠르게 답을 찾는다고나 할까... 아직은 낮은 수준의 단계겠지만 꾸준히 수준을 끌어 올려보겠다!


📝 Reference

  1. Django 공식문서_Django's cache framework
  2. https://docs.djangoproject.com/en/1.8/_modules/django/middleware/cache/
profile
Backend Developer - "Growth itself contains the germ of happiness"

0개의 댓글