프로파일링 개념

프로파일링은 동적 코드 분석의 한 형태입니다. 실행되는 동안 애플리케이션의 특성을 캡처한 후 이 정보를 사용하여 애플리케이션을 더 빠르고 효율적으로 만드는 방법을 알아봅니다.

기존에는 프로파일링이 애플리케이션 개발 중에만 수행되었습니다. 이 방식에서는 프로덕션 환경을 정확하게 예측할 수 있는 부하 테스트와 벤치마크의 개발 능력이 요구되었습니다.

지속적인 프로파일링이란 프로덕션 환경에서 실행되는 동안 애플리케이션을 프로파일링하는 것을 말합니다. 이 방식을 사용하면 프로덕션 환경의 정확한 예측 부하 테스트와 벤치마크를 개발할 필요가 없습니다. 연구 결과에 따르면 지속적인 프로파일링은 정확하고 경제적입니다*.

Cloud Profiler는 Google Cloud에서 실행되는 애플리케이션용으로 설계된 지속적인 프로파일링 도구입니다.

  • 오버헤드가 매우 적고 프로덕션 환경에 적합한 통계 또는 샘플링 프로파일러입니다.

  • 일반적인 언어를 지원하고 여러 프로필 유형을 수집합니다. 개요는 사용 가능한 프로파일링 유형을 참조하세요.

프로필 데이터를 생성하도록 Google Cloud 애플리케이션을 구성하는 것은 간단한 일회성 프로세스입니다(서비스를 프로파일링 에이전트와 연결하거나 실행). 애플리케이션이 배포된 후에는 프로파일링 에이전트가 주기적으로 실행되어 성능 데이터를 수집한 후 이 데이터를 Google Cloud 프로젝트로 보냅니다. 이 프로세스에 대한 자세한 내용은 프로필 수집을 참조하세요.

애플리케이션의 프로필 데이터를 수집한 후에는 Profiler 인터페이스를 사용하여 데이터를 분석할 수 있습니다. 프로필 데이터 분석은 일반적으로 애플리케이션 설계와 프로그래밍 언어에 대한 지식을 활용하는 반복 프로세스입니다.

*다음 Google 전체 프로파일링: 데이터 센터용 지속적인 프로파일링 인프라지속적인 프로파일링: 주기 소비 상태를 참조하세요.

사용 가능한 프로파일링 유형

다음 표에는 지원되는 프로필 유형이 요약되어 있습니다.

프로필 유형 Go 자바 Node.js Python
CPU 시간
할당된 힙
경합
스레드
실제 경과 시간

이 섹션의 나머지 부분에서는 이러한 각 프로필 유형을 자세히 설명합니다.

시간 측정값

  • CPU 시간은 CPU가 코드 블록을 실행하는 데 소요된 시간입니다.

    함수의 CPU 시간은 CPU가 명령을 실행하는 데 얼마나 오래 걸렸는지를 나타냅니다. CPU가 대기 중이거나 다른 항목에 대한 명령어를 처리하는 데 소요된 시간은 포함되지 않습니다.

  • 벽시계 시간(실제 경과 시간이라고도 함)은 코드 블록을 실행하는 데 소요된 시간입니다.

    함수의 실제 경과 시간은 함수 입력부터 종료까지의 경과 시간을 측정한 값입니다. 실제 경과 시간에는 잠금 및 스레드 동기화를 포함한 모든 대기 시간이 포함됩니다. 코드 블록의 실제 경과 시간은 CPU 시간보다 짧을 수 없습니다.

실제 경과 시간이 CPU 시간보다 훨씬 길다면 코드가 기다리는 데 많은 시간을 소비하는 것입니다. 이는 리소스 병목 현상을 나타내는 것일 수 있습니다.

CPU 시간이 실제 경과 시간과 비슷할 경우 이는 CPU 집약적인 코드 블록을 의미합니다. 즉, 코드 실행에 소요되는 대부분의 시간이 CPU에서 소비됩니다. 장기 실행되는 CPU 집약적인 코드 블록을 최적화해야 할 수 있습니다.

힙(메모리) 사용량

  • 힙 사용량(이라고도 함)은 프로필이 수집되는 순간 프로그램의 힙에 할당되는 메모리 양입니다. 특정 간격에 걸쳐 데이터가 수집되는 다른 프로필 유형과 달리 이 프로필 유형은 단일 시점에서 힙 사용량을 수집합니다.

  • 힙 할당(할당된 힙이라고도 함)은 프로필이 수집된 간격 동안 프로그램의 힙에 할당된 총 메모리 양입니다. 이 값에는 할당되었다가 지금은 해제되어 더 이상 사용되지 않는 모든 메모리가 포함됩니다. 예를 들어 1MiB를 할당하고 500밀리초간 대기했다가 1MiB를 해제하고 500밀리초를 대기하는 시퀀스를 반복하는 작업을 가정해 보겠습니다. 할당된 힙 프로필이 수집되는 10초 동안 10개의 할당과 10개의 해제가 있습니다. 이 프로필에는 해제는 고려되지 않기 때문에 10MiB의 할당된 힙이 표시됩니다. 할당의 평균 속도는 10MiB/10초 또는 초당 1MiB입니다.

힙 사용량을 프로파일링하면 프로그램의 잠재적인 비효율성과 메모리 누수를 확인할 수 있습니다. 힙 할당을 프로파일링하면 가비지 수집기의 작업 부하를 가장 많이 가중시키는 할당을 알 수 있습니다.

스레딩 정보

스레드를 만드는 애플리케이션의 경우 차단된 스레드, 생성되었지만 실제로 실행되지 않는 스레드, 생성되는 스레드 수가 계속 증가하는 스레드 누수 등의 문제가 발생할 수 있습니다. 첫 번째 문제는 두 번째 문제 원인 중 하나입니다.

경합

다중 스레드 프로그램에서는 공유 리소스에 대한 액세스가 직렬화되기를 기다리는 데 소요되는 시간이 중요할 수 있습니다. 경합 동작을 이해하면 코드 설계 방향을 결정하고 성능 미세 조정에 대한 정보를 얻을 수 있습니다.

프로필 수집

프로파일러 에이전트의 역할은 애플리케이션에서 프로필 데이터를 캡처하고 Profiler API를 사용하여 이 데이터를 Profiler 백엔드로 전송하는 것입니다. 각 프로필은 애플리케이션의 단일 인스턴스용이며 배포를 고유하게 식별하는 다음 4가지 필드를 포함합니다.

  • GCP 프로젝트
  • 애플리케이션 이름
  • 애플리케이션 영역
  • 애플리케이션 버전

에이전트가 프로필을 캡처할 수 있게 되면 Profiler API 명령어를 Profiler 백엔드에 실행합니다. 백엔드는 이 요청을 수신하고 즉시 에이전트에 응답합니다(가장 간단한 시나리오). 이 응답에서 캡처할 프로필 유형을 지정합니다. 이에 응답하여 에이전트는 프로필을 캡처하고 백엔드로 전송합니다. 마지막으로 Profiler 백엔드는 프로필을 Google Cloud 프로젝트와 연결합니다. 그러면 Profiler UI를 사용하여 프로필을 보고 분석할 수 있습니다.

실제 핸드셰이크 시퀀스는 앞의 단락에서 설명한 것보다 더 복잡합니다. 예를 들어 에이전트로부터 프로필을 수집할 준비가 되었다는 요청이 수신되면 백엔드는 데이터베이스에서 이전에 이 에이전트로부터 요청을 수신한 적이 있는지 확인합니다. 그렇지 않으면 백엔드는 이 에이전트 정보를 데이터베이스에 추가합니다. 에이전트 배포 필드가 기록된 다른 에이전트의 필드와 일치하지 않으면 새 배포가 생성됩니다.

백엔드는 평균적으로 1분마다 각 배포와 각 프로필 유형에 에이전트를 선택하고 프로필을 캡처하도록 지시합니다. 예를 들어 배포 에이전트가 힙과 실제 경과 시간 프로파일링을 배포한다면 평균적으로 1분마다 프로필 2개가 캡처됩니다.

  • 힙 사용 및 스레드를 제외한 모든 프로필 유형에서 단일 프로필은 10초 동안 수집된 데이터를 나타냅니다.

  • 힙 사용량 및 스레드 프로필이 즉시 수집됩니다.

주목할 점은 에이전트가 Profiler 백엔드에 데이터를 캡처할 준비가 되었음을 알린 후 백엔드로부터 캡처할 프로필 유형을 지정하는 응답을 받을 때까지 유휴 상태라는 점입니다. 동일한 배포에서 실행 중인 애플리케이션의 인스턴스가 10개이면 프로파일링 에이전트 10개를 만듭니다. 하지만 이러한 에이전트는 대부분 유휴 상태입니다. 10분 동안 프로필 10개를 예상할 수 있습니다. 각 에이전트는 평균적으로 각 프로필 유형별로 응답 1개를 받습니다. 일부 무작위 과정이 있으므로 실제 수는 다를 수 있습니다.

Profiler 백엔드는 Profiler API 할당량과 프로필 배포 필드를 통해 수집되는 프로필을 제한합니다. 프로파일러 할당량을 보고 관리하는 방법에 대한 자세한 내용은 할당량 및 한도를 참조하세요.