django-redis의 cache 방법을 이해하자!
https://github.com/jazzband/django-redis
문제 인식
- DetailView에서 get_context_data를 통해 정제된 데이터를 Template로 보낸다.
- 나는 이 상황에서 dict를 redis에 넣으려고 애를 썼다.
- 문제는 django-redis의 동작을 전혀 이해하지 못하고 있었다.
- django-redis는 기본적으로 pickle 형식으로 데이터를 넣고 뺀다. 때문에 get/set/delete 의 기본 명령어세트만 가지고 있다.
- 데이터 타입을 확인하면 class를 그대로 넣었다 가져온다.
- redis의 데이터 타입을 보면 binary이다.
- 때문에 정말 하루 종일 정말 미친짓을 엄청나게 했다.
해결 방안
- get_queryset에서 처리했다
- 예시 코드는 다음과 같다.
def get_queryset(self):
key = "board:NoticeDetailView" + str(self.kwargs.get(self.pk_url_kwarg))
if key in cache:
queryset = cache.get(key)
else:
queryset = super().get_queryset()
cache.set(key, queryset, timeout=CACHE_TTL)
return queryset
추가 정보
- 트랜잭션
SETNX(동일한 키가 없을 경우에만 저장됨) INCR(1씩 증가)를 사용하는 경우 트랙잭션을 사용할 수 있다.
SETNX는 set()의 파라미터 nx를 통해 사용할 수 있다. SETNX는 “set not exist”라는 의미로, “락이 존재하지 않으면 락을 획득한다”는 연산을 atomic하게 할 수 있도록 만들어 준다.
- 테스트 예제
>>> from django.core.cache import cache
>>> cache.set("key", "value1", nx=True)
True
>>> cache.set("key", "value2", nx=True)
False
>>> cache.get("key")
"value1"
- 실 사용 예제
from django.core.cache import cache
movie_ticket_key = f'movie_ticket_key:{user_id}:{movie_id}'
if cache.set('movie_ticket_key', '1', nx=True):
movie = Movie.objects.get(id=movie_id)
movie.remaining_seat -= 1
movie.save()
- 파이프라인을 사용한 멀티 실행
#first create pipline object using con object
pipeline = con.pipeline()
if feedlist:
for post in feedlist:
pipeline.execute_command('hgetall',post)
#hgetall redis command to get all items of given hash key
result = pipeline.execute()
주절 주절
한달 넘게 redis, rabbitMQ, celery, docker와 씨름을 했다. 쉽게 넘겨도 될 일인데 파다보니 다른것들도 죄다 만져보느라...
kafka, NATS도 같이 겉핧기 정도지만 재밌게 봤다.
단일 큐는 redis, rabbitMQ만 테스트 하고 원래 하려던 pub/sub 테스트는 컴퓨터 문제로 잠시 미뤄졌다.
결국 이렇게 오랜시간 본 코드를 안보고 있었더니 이런 사단이 생겼다 이거다 ㅎㅎ
reference
https://github.com/jazzband/django-redis
http://redisgate.kr/redis/command/setnx.php
http://redisgate.kr/redis/command/incr.php
https://stackoverflow.com/questions/60446903/how-we-can-use-redis-pipeline-in-django-redis
https://redis.io/docs/manual/transactions/
'Study > django' 카테고리의 다른 글
django-redis로 unlink 실행하는 방법 (0) | 2023.03.21 |
---|---|
django-redis의 hset 사용법에 대해 chatGPT에 물어봤을때 (0) | 2023.03.20 |
django MQ 시리즈 3편 - task queue (3) : Custom Study Project (1) | 2023.03.14 |
django MQ 시리즈 2편 - task queue (2) :Learn Django Celery with RabbitMQ (0) | 2023.03.08 |
django MQ 시리즈 1편 - task queue (1) : Asynchronous Tasks With Django and Celery (1) | 2023.03.04 |
댓글