Konzepte der Profilerstellung

Die Profilerstellung ist eine Form der dynamischen Codeanalyse. Sie erfassen Merkmale der Anwendung während der Ausführung und verwenden diese Informationen, um zu ermitteln, wie Sie diese schneller und effizienter machen können.

In der Vergangenheit wurde die Profilerstellung nur während der Anwendungsentwicklung durchgeführt. Dieser Ansatz basierte auf der Fähigkeit, Lasttests und Benchmarks zu entwickeln, anhand derer eine Produktionsumgebung genau vorhergesagt werden konnte.

Die kontinuierliche Profilerstellung hingegen bezieht sich auf die Profilerstellung einer Anwendung, während sie in einer Produktionsumgebung ausgeführt wird. Bei diesem Ansatz müssen keine genauen Lasttests und Benchmarks zu Prognosezwecken für die Produktionsumgebung entwickelt werden. Studien zur kontinuierlichen Profilerstellung haben gezeigt, dass sie präzise Ergebnisse liefert und kostengünstig ist.*

Cloud Profiler ist ein Tool für die kontinuierliche Profilerstellung für Anwendungen, die in Google Cloud ausgeführt werden:

  • Dabei handelt es sich um einen statistischen bzw. Sampling-Profiler mit sehr geringem Overhead, der sich für Produktionsumgebungen eignet.

  • Cloud Profiler unterstützt gängige Sprachen und erfasst mehrere Profiltypen. Einer Übersicht finden Sie unter Verfügbare Arten der Profilerstellung.

Das Konfigurieren einer Google Cloud-Anwendung zum Generieren von Profildaten ist ein einfacher, einmaliger Prozess: Sie müssen Ihren Dienst lediglich mit einem enthaltenen Profiler-Agent verknüpfen oder mit diesem ausführen. Nach dem Bereitstellen der Anwendung wird der Profiler-Agent regelmäßig ausgeführt, um Leistungsdaten zu erfassen und diese dann an Ihr Google Cloud-Projekt zu senden. Weitere Informationen zu diesem Vorgang finden Sie unter Profilerfassung.

Nachdem Sie Profildaten für Ihre Anwendung erfasst haben, können Sie die Daten mithilfe der Profiler-Oberfläche analysieren. Das Analysieren von Profildaten ist in der Regel ein iterativer Prozess, der auf Ihrer Kenntnis des Anwendungsdesigns und deren Programmiersprache basiert.

*Weitere Informationen finden Sie unter Google-Wide Profiling: A Continuous Profiling Infrastructure for Data Centers und Continuous Profiling: Where Have All the Cycles Gone?.

Verfügbare Arten der Profilerstellung

In der folgenden Tabelle sind die unterstützten Profiltypen zusammengefasst:

Profiltyp Go Java Node.js Python
CPU-Zeit JaJa Ja
Heap JaJa Ja
Zugewiesener Heap Ja
Konflikt Ja
Threads Ja
Echtzeit Ja JaJa

Im weiteren Verlauf dieses Abschnitts geben wir Ihnen ausführlichere Informationen zu jedem dieser Profiltypen.

Zeitmessungen

  • Die CPU-Zeit ist die Zeit, welche die CPU für die Ausführung eines Codeblocks aufwendet.

    Die CPU-Zeit für eine Funktion gibt an, wie lange die Ausführung von Anweisungen gedauert hat. Dies schließt die Zeit aus, welche die CPU gewartet oder zum Verarbeiten von Anweisungen für andere Vorgänge aufgewendet hat.

  • Echtzeit (auch tatsächliche Zeit) ist die Zeit, die für die gesamte Ausführung eines Codeblocks benötigt wird.

    Die Echtzeit für eine Funktion misst die Zeit, die zwischen dem Beginn und Ende einer Funktion verstrichen ist. Die Echtzeit umfasst die gesamte Wartezeit, auch die Zeit für das Warten auf Sperren und die Threadsynchronisierung. Somit kann die Echtzeit für einen Codeblock niemals unter der CPU-Zeit liegen.

Sollte die Echtzeit deutlich länger als die CPU-Zeit sein, so ist dies ein Hinweis darauf, dass der Code lange auf andere Vorgänge wartet. Dies kann auf einen Ressourcenengpass hindeuten.

Wenn die CPU-Zeit nahe an der Echtzeit liegt, ist der Codeblock CPU-intensiv. Die für die Ausführung benötigte Zeit wird fast vollständig von der CPU beansprucht. Für diese lang andauernden, CPU-intensiven Codeblöcke kommt eventuell eine Optimierung infrage.

Heap-Speichernutzung

  • Die Heap-Nutzung (auch Heap genannt) ist die Arbeitsspeichermenge, die im Heap des Programms zugewiesen wird, in dem Moment, wenn das Profil erfasst wird. Im Gegensatz zu anderen Profiltypen, für die Daten für ein Intervall erfasst werden, erfasst dieser Profiltyp die Heap-Nutzung zu einem einzigen Zeitpunkt.

  • Die Heap-Zuweisung (auch zugewiesener Heap) ist der gesamte Arbeitsspeicher, der im Heap des Programms zugewiesen wurde, während das Profil erfasst wurde. Dieser Wert umfasst jeglichen zugewiesenen Speicher, der freigegeben wurde und nicht mehr verwendet wird. Nehmen wir als Beispiel einen Job, der die folgende Sequenz wiederholt: weist 1 MiB zu, wartet 500 ms, gibt 1 MiB frei und wartet 500 ms. In den 10 Sekunden, in denen das zugewiesene Heap-Profil erfasst wird, erfolgen 10 Zuweisungen und 10 Freigaben. In diesem Profil würde 10 MiB zugewiesener Heap angezeigt, da die Freigaben nicht berücksichtigt werden. Die durchschnittliche Zuweisungsrate beträgt 10 MiB/10 Sekunden oder 1 MiB pro Sekunde.

Mit Heap-Nutzungsprofilen können Sie potenzielle Ineffizienzen und Arbeitsspeicherlecks in Ihren Programmen finden. Heap-Zuweisungsprofile zeigen dagegen auf, welche Zuweisungen den größten Aufwand für den Garbage Collector darstellen.

Informationen zum Threading

Anwendungen, die Threads erstellen, können verschiedentlich beeinträchtigt werden, zum Beispiel durch blockierte Threads, durch Threads, die zwar erstellt, jedoch nicht tatsächlich ausgeführt werden, und durch Threadlecks, bei denen die Anzahl der erstellten Threads ständig steigt. Das erste Problem ist eine der Ursachen für das zweite Problem.

Konflikt

In Programmen mit mehreren Threads kann es zu erheblichen Wartezeiten kommen, bis der Zugriff auf eine gemeinsam genutzte Ressource serialisiert ist. Ein gutes Verständnis des Konfliktverhaltens kann beim Codedesign eine Orientierungshilfe sein und Informationen zur Leistungsoptimierung liefern.

Profilerfassung

Die Rolle des Profiler-Agents besteht darin, Profildaten aus Ihrer Anwendung zu erfassen und über die Profiler API an das Profiler-Back-End zu übertragen. Für jede einzelne Instanz einer Anwendung wird ein eigenes Profil erstellt, das vier Felder enthält, mit denen die Bereitstellung der Anwendung eindeutig identifizierbar ist:

  • GCP-Projekt
  • Name der App
  • Anwendungszone
  • Anwendungsversion

Wenn ein Agent bereit ist, ein Profil zu erfassen, gibt er einen Profiler API-Befehl an das Profiler-Back-End aus. Das Back-End erhält diese Anfrage und antwortet im einfachsten Fall sofort dem Agent. Die Antwort gibt den zu erfassenden Profiltyp an. Als Antwort erfasst der Agent das Profil und überträgt es an das Back-End. Schließlich verknüpft das Profiler-Back-End das Profil mit Ihrem Google Cloud-Projekt. Sie können es dann über die Benutzeroberfläche des Profilers ansehen und analysieren.

Die tatsächliche Handshake-Sequenz ist komplexer als im vorherigen Abschnitt beschrieben. Wenn der Profiler beispielsweise eine Anfrage von einem Agent empfängt, der bereit ist, ein Profil zu erfassen, wird die Datenbank des Back-Ends auf vorherige Anfragen von diesem Agent durchsucht. Wenn keine Anfragen vorhanden sind, werden die Agent-Informationen zur Back-End-Datenbank hinzugefügt. Eine neue Bereitstellung wird erstellt, wenn die Agent-Bereitstellungsfelder nicht mit denen eines anderen aufgezeichneten Agents übereinstimmen.

Das Back-End wählt für jede Bereitstellung und jeden Profiltyp durchschnittlich einmal pro Minute einen Agent aus und weist diesen an, ein Profil zu erfassen. Wenn die Agents für eine Bereitstellung beispielsweise die Erstellung von Heap- und Echtzeitprofilen unterstützen, werden durchschnittlich zwei Profile pro Minute erfasst:

  • Für alle Profiltypen mit Ausnahme von Heap-Nutzung und Threads stellt ein einzelnes Profil Daten dar, die 10 Sekunden lang erfasst wurden.

  • Die Heap-Nutzung und die Thread-Profile werden sofort erfasst.

Der wichtigste Aspekt besteht darin, dass der Agent, nachdem er dem Profiler-Back-End mitgeteilt hat, dass er zur Datenerfassung bereit ist, in den Zustand der Inaktivität wechselt. Er wird erst wieder aktiv, wenn er eine Antwort vom Back-End erhält, die den Typ des zu erfassenden Profils enthält. Wenn zehn Instanzen einer Anwendung in derselben Bereitstellung ausgeführt werden, erstellen Sie zehn Profiler-Agents. In den meisten Fällen sind diese Agents jedoch inaktiv. In einem Zeitraum von zehn Minuten werden zehn Profile erfasst. Jeder Agent erhält durchschnittlich eine Antwort pro Profiltyp. Es liegt eine gewisse Randomisierung vor, sodass die tatsächliche Anzahl variieren kann.

Das Profiler-Back-End verwendet Profiler API-Kontingente und die Felder für die Profilbereitstellung, um die aufgenommenen Profile zu begrenzen. Weitere Informationen zum Aufrufen und Verwalten Ihrer Profiler-Kontingente finden Sie unter Kontingente und Limits.