> 백엔드 개발 > 파이썬 튜토리얼 > AppSignal을 사용하여 Django에서 숫자 찾기 및 수정

AppSignal을 사용하여 Django에서 숫자 찾기 및 수정

DDD
풀어 주다: 2024-12-22 21:10:39
원래의
782명이 탐색했습니다.

이 기사에서는 N 1 쿼리, AppSignal로 이를 감지하는 방법, Django 앱 속도를 크게 높이기 위해 이를 수정하는 방법에 대해 알아봅니다.

이론적인 측면부터 시작한 다음 실제 사례로 넘어갑니다. 실제 사례는 프로덕션 환경에서 접할 수 있는 시나리오를 반영합니다.

시작해 보세요!

N 1 쿼리란 무엇입니까?

N 1 쿼리 문제는 데이터베이스와 상호 작용하는 웹 애플리케이션에서 널리 퍼져 있는 성능 문제입니다. 이러한 쿼리는 심각한 병목 현상을 일으킬 수 있으며, 이는 데이터베이스가 커짐에 따라 더욱 심해집니다.

개체 컬렉션을 검색한 다음 컬렉션의 각 항목에 대한 관련 개체에 액세스할 때 문제가 발생합니다. 예를 들어 책 목록을 가져오려면 단일 쿼리(1개 쿼리)가 필요하지만 각 책의 저자에 액세스하면 모든 항목에 대해 추가 쿼리(N개 쿼리)가 트리거됩니다.

데이터베이스에서 데이터를 생성하거나 업데이트할 때도 N 1 문제가 발생할 수 있습니다. 예를 들어,bulk_create() 또는bulk_update()와 같은 메소드를 사용하는 대신 루프를 반복하여 객체를 개별적으로 생성하거나 업데이트하면 과도한 쿼리가 발생할 수 있습니다.

N 1 쿼리는 작업을 더 적고 큰 쿼리로 통합하는 것보다 수많은 작은 쿼리를 실행하는 것이 훨씬 느리고 리소스 집약적이므로 매우 비효율적입니다.

Django의 기본 QuerySet 동작은 특히 QuerySet의 작동 방식을 모르는 경우 실수로 N 1 문제를 일으킬 수 있습니다. Django의 쿼리 세트는 게으릅니다. 즉, QuerySet이 평가될 때까지 데이터베이스 쿼리가 실행되지 않습니다.

전제조건

다음 사항을 확인하세요.

  • 로컬 컴퓨터에 설치된 Python 3.9 및 Git
  • AppSignal이 지원되는 운영체제
  • AppSignal 계정

참고: 이 프로젝트의 소스 코드는 appsignal-django-n-plus-one GitHub 저장소에서 찾을 수 있습니다.

프로젝트 설정

도서관리 웹앱으로 작업해보겠습니다. N 1 쿼리 문제와 해결 방법을 보여주기 위해 웹 앱이 구축되었습니다.

GitHub 저장소의 기본 브랜치를 복제하여 시작하세요.

$ git clone git@github.com:duplxey/appsignal-django-n-plus-one.git \
    --single-branch --branch base && cd appsignal-django-n-plus-one
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

다음으로 가상 환경을 생성하고 활성화합니다.

$ python3 -m venv venv && source venv/bin/activate
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

요구 사항 설치:

(venv)$ pip install -r requirements.txt
로그인 후 복사
로그인 후 복사
로그인 후 복사

데이터베이스 마이그레이션 및 채우기:

(venv)$ python manage.py migrate
(venv)$ python manage.py populate_db
로그인 후 복사
로그인 후 복사

마지막으로 개발 서버를 시작합니다.

(venv)$ python manage.py runserver
로그인 후 복사

좋아하는 웹 브라우저를 열고 http://localhost:8000/books로 이동합니다. 웹 앱은 데이터베이스에서 500권의 도서가 포함된 JSON 목록을 반환해야 합니다.

Django 관리 사이트는 http://localhost:8000/admin에서 액세스할 수 있습니다. 관리자 자격 증명은 다음과 같습니다.

user: username
pass: password
로그인 후 복사

Django용 AppSignal 설치

Django 프로젝트에 AppSignal을 설치하려면 공식 문서를 따르세요.

  • AppSignal Python 설치
  • AppSignal Django 계측
  • AppSignal SQLite 계측

개발 서버를 다시 시작하여 모든 것이 작동하는지 확인하세요.

$ git clone git@github.com:duplxey/appsignal-django-n-plus-one.git \
    --single-branch --branch base && cd appsignal-django-n-plus-one
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

앱이 AppSignal에 데모 오류를 자동으로 전송해야 합니다. 이 시점부터 모든 오류는 AppSignal로 전송됩니다. 또한 AppSignal은 앱 성능을 모니터링하고 문제를 감지합니다.

웹앱 로직

N 1 쿼리를 수정하기 위한 전제 조건은 앱의 데이터베이스 스키마를 이해하는 것입니다. 모델의 관계에 세심한 주의를 기울이십시오. 이는 잠재적인 N 1 문제를 정확히 찾아내는 데 도움이 될 수 있습니다.

모델

웹 앱에는 일대다(1:M) 관계를 공유하는 Author와 Book이라는 두 가지 모델이 있습니다. 즉, 각 책은 한 명의 저자와 연결되고, 한 저자는 여러 책에 연결될 수 있습니다.

두 모델 모두 모델 인스턴스를 JSON으로 직렬화하기 위한 to_dict() 메서드가 있습니다. 게다가 Book 모델은 심층 직렬화(책과 책의 저자를 직렬화)를 사용합니다.

모델은 books/models.py에 정의되어 있습니다.

$ python3 -m venv venv && source venv/bin/activate
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

그런 다음 books/admin.py의 Django 관리 사이트에 다음과 같이 등록됩니다.

(venv)$ pip install -r requirements.txt
로그인 후 복사
로그인 후 복사
로그인 후 복사

AuthorAdmin은 BookInline을 사용하여 저자의 관리 페이지 내에 저자의 책을 표시합니다.

조회수

웹 앱은 다음 엔드포인트를 제공합니다.

  1. /books/는 도서 목록을 반환합니다
  2. /books// 특정 도서를 반환합니다
  3. /books/by-authors/는 저자별로 그룹화된 도서 목록을 반환합니다
  4. /books/authors/는 저자 목록을 반환합니다
  5. /books/authors// 특정 저자를 반환합니다

위 링크는 개발용 웹서버가 구동중인 경우 클릭 가능합니다.

books/views.py에 다음과 같이 정의되어 있습니다.

(venv)$ python manage.py migrate
(venv)$ python manage.py populate_db
로그인 후 복사
로그인 후 복사

좋아요. 이제 웹 앱이 어떻게 작동하는지 아셨군요!

다음 섹션에서는 AppSignal을 사용하여 N 1 쿼리를 감지하도록 앱을 벤치마킹한 다음 코드를 수정하여 이를 제거하겠습니다.

AppSignal을 사용하여 Django 앱에서 N 1 쿼리 감지

AppSignal로 성능 문제를 감지하는 것은 쉽습니다. 평소와 같이 앱을 사용/테스트하기만 하면 됩니다(예: 모든 엔드포인트를 방문하고 응답을 검증하여 최종 사용자 테스트를 수행).

엔드포인트에 도달하면 AppSignal은 이에 대한 성능 보고서를 생성하고 모든 관련 방문을 그룹화합니다. 각 방문은 엔드포인트 보고서에 샘플로 기록됩니다.

뷰에서 N 1 쿼리 감지

먼저 앱의 모든 엔드포인트를 방문하여 성능 보고서를 생성하세요.

  1. /books/
  2. /books//
  3. /books/by-authors/
  4. /books/authors/
  5. /books/authors//

다음으로 AppSignal 대시보드를 사용하여 느린 엔드포인트를 분석해 보겠습니다.

예 1: 일대일 관계(select_관련())

AppSignal 앱으로 이동하여 성능 > 사이드바에 이슈 목록이 있습니다. 그런 다음 평균을 클릭하여 평균 응답 시간을 기준으로 문제를 정렬합니다.

Find and Fix N ueries in Django Using AppSignal

세부 정보를 보려면 가장 느린 엔드포인트(books/)를 클릭하세요.

Find and Fix N ueries in Django Using AppSignal

최신 샘플을 보면 이 엔드포인트가 1090밀리초 안에 응답을 반환하는 것을 볼 수 있습니다. 그룹 분석에 따르면 SQLite는 651밀리초가 걸리는 반면 Django는 439밀리초가 소요됩니다.

이렇게 간단한 엔드포인트는 오래 걸리지 않기 때문에 문제가 있음을 나타냅니다.

무슨 일이 일어났는지 자세히 알아보려면 사이드바에서 샘플을 선택한 다음 최신 샘플을 선택하세요.

Find and Fix N ueries in Django Using AppSignal

이벤트 타임라인으로 스크롤하여 어떤 SQL 쿼리가 실행되었는지 확인하세요.

Find and Fix N ueries in Django Using AppSignal

query.sql 텍스트 위로 마우스를 가져가면 실제 SQL 쿼리가 표시됩니다.

1000개 이상의 쿼리가 실행되었습니다:

$ git clone git@github.com:duplxey/appsignal-django-n-plus-one.git \
    --single-branch --branch base && cd appsignal-django-n-plus-one
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이는 N 1 검색어의 명확한 표시입니다. 첫 번째 쿼리에서는 책(1)을 가져왔고, 이후의 각 쿼리에서는 책의 저자 세부정보(N)를 가져왔습니다.

이 문제를 해결하려면 books/views.py로 이동하여 다음과 같이 book_list_view()를 수정하세요.

$ python3 -m venv venv && source venv/bin/activate
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

Django의 select_관련() 메소드를 활용하여 초기 쿼리에서 추가 관련 개체 데이터(예: 작성자)를 선택합니다. 이제 ORM은 SQL 조인을 활용하며 최종 쿼리는 다음과 같습니다.

(venv)$ pip install -r requirements.txt
로그인 후 복사
로그인 후 복사
로그인 후 복사

개발 서버가 다시 시작될 때까지 기다렸다가 영향을 받은 엔드포인트를 다시 테스트하세요.

Find and Fix N ueries in Django Using AppSignal

다시 벤치마킹한 결과 응답 시간은 1090에서 45로, 쿼리 수는 1024에서 2로 감소했습니다. 이는 각각 24배와 512배 향상된 수치입니다.

예 2: 다대일 관계(prefetch_관련())

다음으로 두 번째로 느린 엔드포인트(books/by-authors/)를 살펴보겠습니다.

이전 단계에서 했던 것처럼 대시보드를 사용하여 엔드포인트의 SQL 쿼리를 검사합니다. 이 끝점에서는 유사하지만 덜 심각한 N 1 패턴을 발견할 수 있습니다.

Django는 자주 실행되는 SQL 쿼리, 즉 반복적으로 책의 저자를 가져오는 쿼리를 캐시할 만큼 똑똑하기 때문에 이 엔드포인트의 성능은 덜 심각합니다. Django 캐싱에 대해 자세히 알아보려면 공식 문서를 확인하세요.

books/views.py에서 prefetch_관련()을 활용하여 엔드포인트 속도를 높이겠습니다.

$ git clone git@github.com:duplxey/appsignal-django-n-plus-one.git \
    --single-branch --branch base && cd appsignal-django-n-plus-one
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

이전 섹션에서는 일대일 관계를 처리하기 위해 select_관련() 메서드를 사용했습니다(각 책에는 단일 저자가 있음). 하지만 이 경우에는 일대다 관계(저자는 여러 권의 책을 가질 수 있음)를 처리하므로 prefetch_관련()을 사용해야 합니다.

이 두 방법의 차이점은 select_관련()이 SQL 수준에서 작동하는 반면 prefetch_관련()은 Python 수준에서 최적화된다는 것입니다. 후자의 방법은 다대다 관계에도 사용할 수 있습니다.

자세한 내용은 prefetch_관련()에 대한 Django 공식 문서를 확인하세요.

벤치마킹 후 응답 시간은 90밀리초에서 44밀리초로 줄어들고 쿼리 수도 32밀리초에서 4밀리초로 줄어듭니다.

Django Admin에서 N 1 쿼리 감지

Django 관리 사이트에서 N 1 쿼리를 검색하는 것도 비슷하게 작동합니다.

먼저 관리 사이트에 로그인하여 성과 보고서를 생성합니다(예: 몇 명의 저자나 책을 만들고 업데이트하고 삭제합니다).

다음으로 AppSignal 앱 대시보드로 이동하여 이번에는 관리자별로 문제를 필터링합니다.

Find and Fix N ueries in Django Using AppSignal

저의 경우 가장 느린 두 엔드포인트는 다음과 같습니다.

  1. /관리자/로그인
  2. /admin/books/author/

/admin/login은 Django에서 전적으로 처리하기 때문에 우리가 할 수 있는 일이 별로 없으므로 두 번째로 느린 엔드포인트에 집중하겠습니다. 이를 검사하면 N 1 쿼리 문제가 드러납니다. 책마다 작가를 따로 불러옵니다.

이 문제를 해결하려면 BookInline에서 get_queryset()을 재정의하여 초기 쿼리에서 작성자 세부 정보를 가져옵니다.

$ python3 -m venv venv && source venv/bin/activate
로그인 후 복사
로그인 후 복사
로그인 후 복사
로그인 후 복사

다시 한 번 벤치마킹하여 쿼리 수가 감소했는지 확인하세요.

마무리

이 게시물에서는 AppSignal을 사용하여 Django에서 N 1 쿼리를 감지하고 수정하는 방법에 대해 논의했습니다.

여기서 배운 내용을 활용하면 Django 웹 앱 속도를 크게 높이는 데 도움이 될 수 있습니다.

유념해야 할 가장 중요한 두 가지 방법은 select_관련()과 prefetch_관련()입니다. 첫 번째는 일대일 관계에 사용되고 두 번째는 일대다 및 다대다 관계에 사용됩니다.

즐거운 코딩하세요!

P.S. Python 게시물이 보도되자마자 읽고 싶다면 Python Wizardry 뉴스레터를 구독하고 게시물 하나도 놓치지 마세요!

위 내용은 AppSignal을 사용하여 Django에서 숫자 찾기 및 수정의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿