Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Spring Boot
- Python
- 티스토리 open api
- 보행자 천국
- 가사 검색
- Tistory
- 튜플
- 티스토리
- 알고리즘
- bulk update
- 트라이
- CleanCode
- 호텔 방 배정
- 크레인 인형뽑기 게임
- 징검다리 건너기
- Open API
- jdbc
- 프로그래머스
- trie
- 트라이 #trie #알고리즘
- 불량 사용자
- 카카오 인턴
- pycon
Archives
- Today
- Total
택시짱의 개발 노트
24장. 장고 성능 향상시키기 본문
24.1 정말 (성능이란 것이) 신경 쓸 만한 일일까?
- 서툰 최적화는 오히려 해가 될 수 있다. 사이트가 아직 종소규모이고 페이지 로딩 속도에 문제가 없다면 이 장을 건너 뛰어도 무방하다.
24.2 쿼리로 무거워진 페이지의 속도 개선
- 느리게 반응하는 쿼리 때문에 생긴 문제를 해결하는 방안을 다룰 예정 ( 링크 참조 )
24.2.1 django-debug-toolbar를 이용하여 문제가 되는 쿼리 찾아내기
django-debug-toolbar를 이용하면 쿼리의 출처를 대부분 찾아낼 수 있다. 아래와 같은 병목구간 또한 발견할 수 있다.
- 페이지에서 중복된 쿼리들
- 예상한 것보다 많은 양의 쿼리를 호출하는 ORM 호출( call )
- 느린 쿼리
여러분의 장고 프로젝트에서 대강 어느 URL부터 해볼지 머릿속에 감이 올 것이다.
django-cache-panel는 장고에서 캐시의 이용을 시각화해 보여준다.
django-extensions는 장고의 프로파일링 도구를 활용해 run-server 명령을 시작하는 RunProfileServer라는 도구를 제공
silk는 사용자에게 인터페이스를 보여주기 이전에 HTTP 요청과 데이터베이스 쿼리를 낚아채 저장함으로써 실시간 프로파일링을 가능하게 해준다.
24.2.2 쿼리 수 줄이기
- ORM에서 여러 쿼리를 조합하기 위해 select_related()를 이용해 본다. select_related는 FK 관계를 추적하여 좀더 많은 관계 정보를 담고 있는 큰 크기의 쿼리세트를 생성한다.
- 다대다 대응(N:M)과 다대일 대응(N:1) 관계 에서는 select_related로 최적화 불가능. prefetch_related()를 이용
- 템플릿당 동일한 쿼리가 두 번 이상 생성되는 경우 해당 쿼리를 파이썬 뷰로 이동시켜 context를 변수로 처리하고 context에서 템플릿 ORM이 호출될 수 있도록 하자.
- Memcached or Redis와 같은 key/value 저장소 (NoSQL)을 사용하여 캐싱을 구현
- django.utils.functional.cached_property decorator를 이용하여 객체 인스턴스의 메서드 호출 결과를 메모리에 캐시에 저장하여 사용
24.2.3 일반 쿼리 빠르게 하기
개별 쿼리 속도 또한 병목 지점이 되기도 한다.
- 일반적으로 느린 쿼리들의 대부분은 인덱스로 최적화할 수 있다. 쿼리에서 가장 빈번히 필터되고 정렬되는 항목에 대해 인덱스를 설정한다. 생성된 SQL 문에서 WHERE 절과 ORDER_BY절을 세심하게 살펴보자
- 실제 상용 환경에서 생성된 인덱스들이 정확히 어떤 역활을 하는지 살펴본다. 개발 머신의 환경이 상용 머신의 환경과 완벽히 일치되는 경우는 없다. 데이터베이스에서 어떤 일이 생기는지 이해하고 분석해 보자.
- 쿼리에서 생성된 쿼리 계획(query plan)을 살펴 보자.
- 데이터베이스에서 느린 쿼리 로깅(show query logging) 기능을 활성화하고 빈번히 발생하는 느린 쿼리를 확인하자.
- django-debug-toolbar를 이용하여 잠재적으로 느려질 쿼리를 살펴보자.
- 인덱스를 최적화하여 설정했고 페이지 분석을 통해 수정해야 할 특정 쿼리를 찾아냈다면 다음 방법으로 쿼리를 다시 작성 해보자.
- 가능한 작은 크기의 쿼리 결과가 반환되도록 로직을 재구성해 보자.
- 인덱스가 좀 더 효과적으로 작동할 수 있도록 모델을 재구성해 보자.
- SQL이 ORM에 의해 생성된 쿼리보다 더 효과적일 수 있는 부분에 SQL을 직접 이용해 보자.
24.2.4 ATOMIC_REQUESTS 비활성화하기
- 절대 다수의 장고 프로젝트 사이트에서는 ATOMIC_REQUESTS 설정 값을 True로 설정해도 구동하는데 전혀 문제가 없다. 모든 데이터베이스 쿼리를 트랜젝션으로 처리함에 따라 나타나는 부하 문제는 거의 인지할 수 없는 수준이다.
- 다만 병목지점을 분석한 결과 트랜젝션에서 너무 많은 지연이 나타나는것을 확인
24.3 데이터베이스의 성능 최대한 이용하기
- 데이터베이스 접근 최적화에 대해 좀 더 세부적으로 고려해 볼 수 있다.
24.3.1 데이터베이스에서 삼가야 할 것들
- SQL에 포함되어서는 안되는 두 가지
- 로그
- 데이터베이스에 로그 데이터를 저장하지 말라. 개발 환경에서는 로그 데이터를 DB에 저장해도 큰 문제가 보이지 않는다. 하지만 로그 데이터가 커지면서 많은 양의 데이터가 DB에 추가 됨에 따라 DB 성능이 전체적으로 느려짐을 경험하게 될 것이다.
- 일시적 데이터
- 일시적 데이터를 DB에 저장하지 않기를 바란다. 리라이팅(rewriting)이 이루어지는 데이터의 경우 SQL 이용을 피해야 한다는 의미. 이러한 데이터는 NoSQL을 이용하는것이 좋다.
24.3.2 PostgreSQL 최대한 이용하기
24.3.3 MySQL 최대한 이용하기
- MySQL은 상대적으로 이용하기 쉬운 서버 중 하나.
24.4 Memcached나 Redis를 이용하여 쿼리 캐시하기
- 간단한 세팅으로 엄청난 성능 향상을 꾀할 수 있다.
- 사이트 전반에 적용되는 캐시를 설정할 수도 있고 각 뷰나 템플릿별로 캐시를 할 수도 있다.
- Django의 저수준 레벨 캐시 API를 이용하여 객체를 캐리할 수도 있다.
24.5 캐시를 이용할 곳 정하기
- 가장 많은 쿼리를 포함하고 있는 뷰와 템플릿은 어떤 곳인가?
- 어떤 URL이 가장 많은 요청을 받는가?
- 캐시를 삭제해야 할 시점은 언제인가?
24.6 서드 파티 캐시 패키지
서드 파티 캐시 패키지는 다음과 같은 기능을 제공한다.
- 쿼리세트(QuerySet)캐시
- 캐시 삭제 세팅과 메커니즘
- 다양한 캐시 백엔드
- 기존 캐시 시스템에 대한 대안과 실험적이며 과도기적 방법론
- 인기 있는 장고 캐시 패키지
- django-cachepos
- django-cachalot
24.7 HTML, CSS, JS 압축과 최소화하기
- 브라우저가 웹 페이지를 렌더링할 때 일반적으로 HTML, CSS, JS, 이미지 파일들이 로드된다. 페이지를 느리게 하는 원인
- 장고에서 GZipMiddleware, ($spaceless$) 템플릿태그를 지원 BUT 위의 작업을 하느라 시스템 리소스를 너무 많이 사용하여 시스템 병목 지점이 될 수 있다.
- Nginx, Apache 같은 웹 서버를 이용하여 외부로 나가는 콘텐츠를 압축하는 방법.
24.8 업스트림 캐시나 CDN 이용하기
- 바니시(Vanish)와 같은 업스트림 캐시(upstream cache)는 매우 유용하다. 웹 서버 앞단에서 구동하며 웹 페이지 또는 콘텐츠 제공 속도를 크게 높인다.
요약
- 병목 현상에 대해 프로젝트 초기 단계부터 고민할 것인가?
- 페이지와 쿼리 프로파일링하기
- 쿼리 최적화
- 데이터베이스 잘 이용하기
- 쿼리 캐시하기
- 어떤 것들을 캐시할 것인가?
- HTML, CSS, JS 압축하기
- 기타 다른 참고 자료 살펴보기
반응형
'Django(장고)' 카테고리의 다른 글
29장 - 유틸리티들에 대해 (0) | 2022.01.26 |
---|---|
25장. 비동기 태스크 큐 (0) | 2021.12.09 |
19장. 장고 어드민 이용하기 (2) | 2021.11.08 |
18장. 장고 코어 모듈을 교체할 때 주의점 (0) | 2021.11.03 |
django rest framework에 질문 이메일을 보내봤다. (0) | 2021.10.29 |
Comments