본문 바로가기
Django Project

헤로쿠로 앱 배포하기(3) - 캐싱으로 db부하 줄이기

by nijex 2022. 10. 9.

헤로쿠로 앱 배포...

간단하다고 생각했지만, 막판에 db 연결하는데 예상치 못한 에러가 마구 발생하여 생각보다 애를 먹었다.

애초에 linux환경에서 작업했던 것을 더이상 aws 인프라를 활용하지 못하게 되어 아쉬운대로 최종 웹페이지만이라도 배포하자는 마음에 진행했던 것이라...

그 과정에서의 설정 충돌 문제는 일단 차치하고, 이상하게 애를 먹었던 db 연동 관련해서만 기록을 남겨둬야지.

 

사실 매우 간단한 문제였지만, 이제 막 시작하는 나에게는 꽤나 고생이었다.

 

 

1. 기존 로컬 mysql의 데이터 가져오기

 

mysqldump를 이용하여 로컬db의 데이터를 옮겨왔다

 

일단, 기존 로컬 데이터베이스를 export해오자

내가 사용하던 데이터베이스의 이름은 phoenix여서 이런 식으로 명령어를 입력하였다.

mysqldump -u root -p phoenix > phoenix.sql (저장 위치는 현재 경로)

mysqldump -u root -p db이름 > 저장경로/저장파일명.sql

이제 export해둔 파일을 다시 원하는 db에 import하자

나는 mysql workbench를 통해 헤로쿠에서 제공받은 jawsdb에 접속하여 쿼리문을 실행해주었다.

 

일단, 헤로쿠에서 해당 프로젝트에 들어가 [Settings] - [Config Vars] - [Reveal Config Vars] - [JAWSDB_URL] 에서 해당 db관련 설정을 확인해두고,

mysql://[username]:[userpassword]@[hostname]:[port]/[dbname]

MySQL Workbench에서 [Database] - [Connect to Database] 클릭하여 해당 db정보를 입력

헤로쿠에서 확인한 hostname, username 입력
Store in Vault...를 클릭하여 userpassword도 입력

 

[OK]를 클릭해주면 왼쪽 Navigator에 db이름을 확인할 수 있을 것이다

그렇다면 중간 Query문 작성 하는 곳에 dump 명령어 입력해주고 실행시켜주면 끝!

예를 들어, db이름이 lcg67xsu3k이고 C드라이브의 Users폴더에 덤프파일이 있으면,

mysqldump -u root -p lcg67xsu3k < C:/Users/phoenix.sql

 

참고 사이트

mysqldump 사용법 :: 코드공장 (tistory.com)

 

mysqldump 사용법

mysqldump MySQL의 대표적인 Logical 백업 프로그램으로서 스토리지 엔진에 상관 없이 백업을 받을 수 있는 tool 입니다. mysqldump 는 기본적으로 dump를 하려고 하는 테이블에 대한 SELECT 권한, dump하려는 vi

code-factory.tistory.com

 

 

 

2. max_questions 제한

 

db에 데이터를 옮겨두고 다시 헤로쿠에 앱에 접속해보니, db와 잘 연동되어 값들이 화면에 뜨는 걸 확인할 수 있었다.

이제 다 끝이구나 하고 이 페이지 저 페이지 둘러보던 중 만난 에러...

 

??

헤로쿠 홈페이지를 찾아보니...

Why am I seeing a 'max_questions' error using MySQL? - Heroku Help

 

Why am I seeing a 'max_questions' error using MySQL? - Heroku Help

Ask on Stack Overflow Engage with a community of passionate experts to get the answers you need Ask on Stack Overflow

help.heroku.com

요약하자면, 헤로쿠에서 제공해주는 무료 jawsdb에는 한시간에 3600번의 쿼리셋을 날릴 수 있는데, 나는 그걸 초과한 것이다...

내가 배포한 프로젝트가 데이터 대시보드여서 쿼리셋 요청이 많기도 했고, 코린이들이 짠 굉장히 비효율적인 코드라 맞이하게 된 에러였다.

일단 생각난 해결방법은 1. 코드 리팩터링 2. 유료db 구매 ...

제대로 찾아보지 않아 다른 쌈박한 해결방법이 있을지도..?

 

 

 

3. 쿼리셋 캐싱

 

헤로쿠 홈페이지를 찬찬히 읽어보니, 다음과 같은 힌트가 있었다.

쿼리를 캐시에 저장해두면, max_question 제한에 걸리지 않는다!

그렇다면 장고에서의 캐시 저장법을 찾아보자.

 

장고에서 사용할 수 있는 캐시 엔진에는 크게 Memcached와 Redis가 있다.

간단하게 정리하자면,

상대적으로 작고 정적이고 유실되어도 상관없는 데이터의 경우에는 Memcached

상대적으로 복잡하고 유형이 다양하고 백업 기능이 필요한 데이터의 경우에는 Redis가 적합하다.

 

처음에는 mamcached를 사용하려고 했으나, 설치 과정에서 버전 충돌이 일어나... 결론적으로 redis를 사용하였다.

 

memcached를 설치할 때 참고했던 페이지

django-heroku-memcacheify · PyPI

 

django-heroku-memcacheify

Automatic Django memcached configuration on Heroku.

pypi.org

 

 

- Redis 데이터베이스 등록

헤로쿠에서 MySQL db를 등록했을 때와 마찬가지로 [Resources] - [Add-ons]에 들어가 redis를 검색하면 다음과 같이 무료 Heroku Data for Redis를 받을 수 있다.

[Submit Order Form]을 클릭하여 등록해주자.

- redis 패키지 설치 

터미널에서 아래 명령어를 입력하여 django-heroku-redisfy를 설치해주자(가상환경 확인)

pip install django-heroku-redisify

 

- requirements.txt 변경

pip freeze > requirements.txt

 

- settings.py 변경

settings.py 파일의 최하단에 다음과 같이 추가해주자.

(REDIS_URL은 db등록할 때 자동으로 환경변수에 등록)

# Redis Cache
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": os.environ.get('REDIS_URL'),
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

 

- views.py 변경

장고에서 캐싱하는 방법에는 5가지가 있는데,

나는 views.py에서만 캐싱을 하였다.

 

일단, import부터 해주고

from django.core.cache import cache

 

캐시를 저장할 때는 cache.set(캐시명, 저장할값, 지속시간)

캐시를 불러올 때는 cache.get(캐시명)

아래의 내용은 supply라는 캐시가 없을 때, 300초 동안 유지되는 supply 캐시를 만드는 코드이다.

supply = cache.get('supply')
if not supply:
    supply = Supply.objects.filter(year=year).values()[0].supply
    cache.set('supply', supply, 300)

 

변경한 코드를 다시 heroku로 push 해주면 해당 내용 반영된 것을 확인할 수 있다.

'Django Project' 카테고리의 다른 글

Django 쿼리셋 특징 - Lazy Loading  (0) 2022.11.07
헤로쿠로 앱 배포하기(2)  (0) 2022.10.09
헤로쿠로 앱 배포하기(1)  (0) 2022.10.06
파이썬 가상환경 설정(conda, venv)  (0) 2022.10.06

댓글