App Engine은 애플리케이션의 성능 및 리소스 활용에 대한 사용 보고서를 생성합니다. 리소스를 보다 효율적으로 관리하는 데 도움이 되는 전략을 아래와 같이 소개해 드립니다. 자세한 내용은 가격 책정 페이지를 참조하세요.
사용 보고서 보기
애플리케이션 성능을 평가할 때는 애플리케이션에서 실행되는 인스턴스 수 및 애플리케이션의 리소스 소비 현황을 파악해야 합니다.
다음 섹션에서는 몇 가지 리소스 관리 전략을 제안합니다.
동적 인스턴스 확장 관리
지연 시간 줄이기
애플리케이션의 지연 시간은 트래픽을 처리하는 데 필요한 인스턴스 수에 영향을 줍니다. 지연 시간을 줄이면 애플리케이션을 제공하는 데 사용되는 인스턴스 수를 낮출 수 있습니다. Cloud Trace는 지연 시간에 대한 데이터를 보고 가능한 개선 방안을 파악하는 데 유용한 도구입니다.
Cloud Trace를 사용하여 지연 시간을 확인한 후 다음과 같은 전략을 시도하여 지연 시간을 줄여보세요.
- 자주 액세스되는 공유 데이터의 캐싱 증가 - App Engine Memcache를 사용하면 가능합니다. 또한 애플리케이션의 cache-control 헤더를 설정하면 서버 및 브라우저의 데이터 캐싱 효율이 크게 향상될 수 있습니다. 항목을 단지 몇 초만 캐시해도 애플리케이션의 트래픽 처리 효율이 개선될 수 있습니다. Python 애플리케이션은 런타임 캐싱도 활용해야 합니다.
- App Engine Memcache를 더 효율적으로 사용 - 가져오기, 설정, 삭제 등에 일련의 개별 호출 대신 일괄 호출을 사용하세요. Memcache Async API를 사용해 보세요.
- 요청과 무관한 기능에 태스크 사용 - 애플리케이션이 사용자에게 표시되는 요청의 범위를 초월하여 수행할 수 있는 작업은 태스크로 처리하세요. 이러한 작업이 완료되기를 기다렸다가 응답을 반환하는 대신 태스크 큐를 활용하면 사용자가 체감하는 지연 시간을 크게 줄일 수 있습니다. 또한 태스크 큐는 실행 속도를 더욱 세밀하게 제어하고 부하를 고르게 분산하는 데 도움이 됩니다.
- Datastore 모드의 Firestore(Datastore)를 보다 효율적으로 사용 - 자세한 내용은 아래를 참조하세요.
- 여러 URL Fetch 호출을 동시에 실행:
- 여러 URL 가져오기 호출을 사용자가 관련되는 각 요청 내에서 개별적으로 처리하는 대신 하나로 묶고 비동기 URL 가져오기를 통해 오프라인 태스크로 일괄 처리합니다.
- 비동기식 URL Fetch API를 사용합니다.
- HTTP 세션의 경우 비동기 쓰기 사용
자동 확장 성능 설정 변경
app.yaml
구성 파일에는 특정 버전의 앱에 대한 성능과 리소스 부하 간의 균형점을 조정하는 데 사용할 수 있는 여러 가지 설정이 포함되어 있습니다. 사용 가능한 자동 확장 설정 목록은 확장 요소를 참조하세요.
App Engine 새 스케줄러 설정 동영상을 통해 이 설정의 효과를 확인하세요.
Python에서 동시 요청 사용
Python에서 애플리케이션의 인스턴스는 여러 요청을 동시에 처리할 수 있습니다. 이 설정을 사용하면 애플리케이션의 트래픽을 처리하는 데 필요한 인스턴스 수가 감소하지만, 올바른 동작을 보장하려면 애플리케이션이 스레드 안전 상태여야 합니다. app.yaml
파일에서 threadsafe를 사용 설정하여 동시 요청을 사용하는 방법을 참조하세요.
태스크 큐 설정 구성
태스크 큐의 기본 설정은 성능 우선으로 조정되어 있습니다. 이러한 기본값을 사용하여 큐에 여러 작업을 동시에 보내면 새 프런트엔드 인스턴스가 시작될 가능성이 높습니다. 다음과 같이 태스크 큐를 조정하면 인스턴스 시간을 절약할 수 있습니다.
- 지연 시간에 민감하지 않은 작업에 X-AppEngine-FailFast 헤더를 설정합니다. 이 헤더는 기존 인스턴스를 사용할 수 없으면 요청을 즉시 실패로 처리하도록 스케줄러에 지시합니다. 태스크 큐는 기존 인스턴스가 요청을 처리할 수 있게 될 때까지 재시도와 백오프를 반복합니다. 그러나 X-AppEngine-FailFast가 설정된 요청이 기존 인스턴스를 점유하고 있는 경우, 이 헤더가 없는 요청으로 인해 여전히 새 인스턴스가 시작될 수 있다는 점에 주의해야 합니다.
- 'rate' 매개변수를 더 낮은 값으로 설정하면 태스크 큐가 태스크를 더 천천히 실행합니다.
- 'max_concurrent_requests' 매개변수를 더 낮은 값으로 설정하면 동시에 실행되는 태스크의 수가 감소합니다.
가급적 정적 콘텐츠 제공
Python의 정적 콘텐츠 제공은 인스턴스 시간을 소비하지 않는 특화된 App Engine 인프라에 의해 처리됩니다. 커스텀 헤더를 설정해야 하는 경우 Blobstore API를 사용합니다. Blob 응답이 실제로 제공될 때는 인스턴스 시간이 소비되지 않습니다.
애플리케이션 스토리지 관리
App Engine은 Datastore의 항목 크기, Datastore 색인 크기, 태스크 큐의 태스크 크기, Blobstore에 저장된 데이터 양을 기준으로 스토리지 비용을 계산합니다. 데이터가 필요 이상으로 저장되지 않도록 다음과 같은 조치를 취할 수 있습니다.
- 애플리케이션에서 더 이상 필요하지 않은 항목이나 blob을 모두 삭제합니다.
- 아래 Cloud Datastore 사용량 관리 섹션의 설명에 따라 불필요한 색인을 모두 삭제하여 색인 스토리지 비용을 줄입니다.
Datastore 사용량 관리
App Engine은 Datastore에서 수행하는 작업 수를 계산합니다. 다음은 Datastore 리소스 소비를 줄이고 Datastore 요청의 지연 시간을 단축시킬 수 있는 몇 가지 전략입니다.
- Google Cloud console 데이터 뷰어는 로컬 Datastore에 각 항목을 만드는 데 소요된 쓰기 작업 수를 표시합니다. 이 정보를 사용하여 각 항목의 쓰기 비용을 파악할 수 있습니다. 이 데이터를 해석하는 방법은 쓰기 비용 이해를 참조하세요.
- 불필요한 색인을 모두 삭제하여 저장용량 및 항목 쓰기 비용을 절감합니다. 애플리케이션에 어떤 색인이 정의되어 있는지 확인하려면 '색인 가져오기' 기능을 사용하세요. Google Cloud Console 검색 페이지에서 현재 애플리케이션에 제공되는 색인을 확인할 수 있습니다.
- 데이터 모델을 설계할 때 가능하면 어떠한 경우에도 커스텀 색인이 필요하지 않도록 쿼리를 작성합니다. App Engine에서 색인을 생성하는 방법은 쿼리 및 색인을 참조하세요.
- 가능한 경우 색인이 생성된 속성(기본값)을 색인이 생성되지 않은 속성(Python)으로 바꿔 항목을 배치할 때 Datastore 쓰기 작업 수를 줄입니다. 단, 이후에 색인이 생성되지 않은 속성을 쿼리할 수 있어야 한다고 판단될 경우 색인이 생성된 속성을 사용하도록 코드를 다시 수정해야 할 뿐 아니라 전체 항목을 대상으로 매핑 축소를 실행하여 항목을 다시 삽입해야 합니다.
- App Engine 1.5.2 및 1.5.3 출시 버전의 Datastore 쿼리 플래너 개선사항에 따라 쿼리에 필요한 색인 수가 전보다 감소했을 수 있습니다. 특정 커스텀 색인은 성능상의 이유로 그대로 유지하더라도 나머지 커스텀 색인을 삭제하면 저장소 및 항목 쓰기 비용을 절감할 수 있습니다.
- 데이터 모델을 재구성하여 쿼리 대신 키로 가져오기를 사용하면 비용이 낮아지고 효율성이 향상됩니다.
- 가능하면 항목을 쿼리하는 대신 키만 쿼리합니다.
- 지연 시간을 줄이려면 여러 항목의
get()
을 일괄get()
으로 바꿉니다. - 오프셋 대신 페이지 매김에 Datastore 커서를 사용합니다.
- Async Datastore API를 통해 여러 Datastore RPC를 병렬 처리합니다.
참고: 소규모 Datastore 작업에는 Datastore ID 또는 키 전용 쿼리를 할당하는 호출이 포함됩니다. 비용에 대한 자세한 내용은 가격 책정 페이지를 참조하세요.
대역폭 관리
발신 대역폭을 줄이려면 응답에 적합한 Cache-Control
헤더를 설정하고 정적 파일에 대해 합리적인 만료 시간을 설정해야 합니다. 이러한 방식으로 공개 Cache-Control
헤더를 사용하면 지정한 기간 동안 프록시 서버와 클라이언트의 브라우저가 응답을 캐시할 수 있습니다.
수신 대역폭은 사용자가 앱으로 전송하는 데이터 양이므로 제어하기 어렵습니다. 하지만 App Engine 방화벽 규칙을 사용해서 IP 주소 및 서브넷 범위를 허용하거나 제한할 수 있습니다.