[모르고리즘 4] redis

LILO Ghim·2022년 3월 29일
0
post-thumbnail

2차 프로젝트 중 배포 전까지 시간이 약간 남아서 redis는 아직 하지 말고 캐싱 공부 하라고,,, 가져와서 자기한테 발표하라고 했었는데,,, 보고싶어여 SH님,,, 카네이션 들고 곧 갑니다,,, 기다리세여,,,



지난 우아한 테크 세미나를 들은 이후로,
예제든 뭐든 쳐보고 싶었는데,
일단 간단한 예제를 쳐 본 후에
게시판 API 과제에 적용을 해보았다

#addpost.py
class Command(BaseCommand):
    help = 'Add as many posts as you want'

    def add_arguments(self, parser):
        parser.add_argument('post_cnt', type=int)

    def handle(self, *args, **options):
        post_cnt = options['post_cnt']
        if post_cnt > 0:
            Post.objects.bulk_create(
                [Post(text="Sample Text #{}".format(i)) for i in range(post_cnt)]   
            )
            self.stdout.write(self.style.SUCCESS('Successfully add {} posts'.format(post_cnt)))
            
#case 1
def my_view(request):
    posts = Post.objects.all().values('id', 'text')
    return JsonResponse(list(posts), safe=False)
    
#case 2
def my_view(request):
    posts = cache.get_or_set('posts', Post.objects.all().values('id', 'text'))
    return JsonResponse(list(posts), safe=False)
    

  1. 먼저 python manage.py addpost 100000 를 실행해서
  2. 100000개 객체를 디비에 만들어 넣고,
  3. loadtest로 100번의 요청을 해서
  4. #1번 코드를 실행을 해보고,
  5. #2번 코드로 한 번의 요청으로 redis에 caching을 한 이후
  6. 다시 100번 실행해서 응답 시간을 비교 해본다

#1번 코드
17초!

그리고
#2번 코드
7초!
거의 10초가 줄어든 것을 확인!


그런데 문제는 지금부터

게시판 API 과제에 적용을 해보려고 하는데
DRF로 하다 보니 감이 안와서 구글링을 한참 하다가,,,
두 가지 코드로 진행을 해보았다

#views.py
class BoardListCreateAPIView(generics.ListCreateAPIView):
    queryset = Board.objects.all().order_by("-id")
    serializer_class = BoardSerializer
    filter_backends = [filters.SearchFilter]
    search_fields  = ['category__name', 'tag__name']
    permission_classes = (AllowAny,) 
    
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

요청 보낼 코드는 이러하고
(근데 이것도 문제인듯 함)

원래 인가를 하지만 테스트 할 때만 AllowAny를 설정해주고
(근데 어짜피 게시판은 아무나 봐도 상관없지 않나?)

#case 1

   def get(self, request, *args, **kwargs):
       board = cache.get_or_set('board', self.get_queryset(), 60*10)
       serializer = BoardSerializer(board, many=True)
       return Response(serializer.data)

#case 2

    @method_decorator(vary_on_cookie)
    @method_decorator(cache_page(60*60))
    def dispatch(self, request, *args, **kwargs):
        res = cache.get('board')
        if res:
            return res
        res = super().dispatch(request, *args, **kwargs)
        res.render()
        cache.set('board', res, 60)
        return res

#case 1 코드로 오버라이드 해서 적용을 해 본 이유는,
처음에 #case 2코드가 redis server로 연결이 안되어서
코드의 문제인 줄 알고
(결국 settings의 오타였음;;;)
예제처럼 해야 하는 줄 알고 get method를 만들어서
1000번 요청을 해보았으나

...응...?
이건 아무리 생각해도 아무리 천번이어도 122초는 느리지 않나?
그런데 redis-cli 확인을 해보면 caching은 되어 있는데
redis를 연결 할때나 안 할때나 똑같이 거의 122초가 걸림 흫


...왜지?

그래서 다시 다른 코드로 시도

#case 2 코드로 실행을 해보면 2초로 대폭 시간이 줄어 든 것을 확인하였으나,
이것도 문제인게 그냥 db에서 불러와도 똑같이 2초대로 큰 차이가 없다

...왜지?

그리고 일단 redis를 적용하는 경우와 자료형부터 잘못 된 듯 하다
예를 들어 랭킹 API나, 유저와 관련된 API 등 적용하는 케이스
즉, 상황과 목적이 있고, 일단 이런 식의 get 요청은 아닌 게 확실함

아니 그런데 왜 두 경우 모두 caching이 되고 있는데
그냥 db에서 불러오는 것과 시간 차이가 나지 않고,
예제에서는 확실히 차이가 나는데?

심지어 또 왜 두 코드의 응답 시간 차이는 왜 이렇게 큰 것인가?
122초에서 2초???
왜 이렇게 빨라져???

...왜지?

이 포스팅의 카테고리가 morgorithm to algorithm인데
계속 morgorithm이네?


...WIP...
듣는다. 다시. 세미나.

profile
킴릴로

0개의 댓글