[PYTHON] Connaissance du test de charge minimale acquise lors du premier test de charge du serveur API

Depuis que j'ai fait le test de charge du serveur API pour la première fois, je voudrais présenter brièvement le but du test de charge que j'ai appris à ce moment-là, des exemples de méthodes de préparation et de réglage, et les endroits que j'ai trouvés difficiles.

img1-2.png

Objectif du test de charge

Ce que j'ai utilisé

-Serveur API créé avec Django ・ Locust (outil de test de charge qui peut être écrit en python) ・ Nouvelle relique (service de surveillance des performances)

En supposant des chiffres cibles

Il ne sert à rien de régler à l'aveugle, alors supposez d'abord la valeur de performance minimale requise comme valeur cible. Cette fois

  • Déterminez le taux d'utilisation du processeur, qui est la valeur limite pour un serveur. </ b> ――Déterminez la marge que vous souhaitez définir comme valeur limite. ―― En décidant cela, le nombre de requêtes pouvant être traitées tout en maintenant le taux d'utilisation du processeur déterminé sera la valeur limite de ce serveur pendant le test de charge.

  • En supposant le nombre maximum de requêtes que ce serveur doit traiter par minute. </ b> ―― Ce nombre est basé sur le nombre de demandes que vous devez traiter en un maximum de minutes (ou secondes). «Lorsqu'il est décidé combien de requêtes peuvent être traitées par une unité (valeur limite d'une unité), enfin," nombre maximum de requêtes ÷ valeur limite d'une unité "est utilisé pour déterminer le nombre de serveurs nécessaires. Je peux.

Par exemple, à partir de DAU, etc., supposons que le nombre d'accès pendant les heures de pointe est de 12 000 tr / min et que le taux d'utilisation du processeur pouvant être utilisé par un serveur est de 50%.

  • RPM (nombre de requêtes traitées par minute)
  • RPS (nombre de requêtes traitées par seconde)

Dans ce cas, lorsque l'objectif est de limiter le nombre de serveurs à quatre, L'objectif est de gérer 3 000 tr / min par unité lorsque le taux d'utilisation du processeur est de 50%. </ b>

À propos, la configuration du serveur au moment du test de charge est la suivante. スクリーンショット 2016-03-08 11.45.44.png

Tout d'abord, afin de voir le nombre par unité, nous avons d'abord effectué un test de charge avec un serveur API. New Relic est installé uniquement sur le serveur API n ° 1.

Création de scénarios de test de charge avec Locust

Maintenant, préparons Locust pour le prochain chargement. Voici une référence pour savoir comment utiliser Locust. Créez un scénario en supposant quelle API sera appelée et à quelle vitesse.

Voici un exemple de scénario simple. L'enregistrement de l'utilisateur n'est effectué qu'une seule fois lors de la création d'un client, et l'API de connexion et l'API d'état sont ensuite appelées sans ordre particulier. Cependant, le décorateur de tâches spécifie le pourcentage auquel chaque API est appelée.

# -*- coding:utf-8 -*-
"""
Un scénario d'une semaine de mouvement général

"""
from locust import HttpLocust, task, TaskSet


class ScenarioTaskSet(TaskSet):

    def on_start(self):
        """
Enregistrement de l'utilisateur
Ici, préparez les informations nécessaires pour chaque client
        """
        self.user_id = "xxxxxxxxxxxxxx"
        self.client.headers = {
            'Content-Type': 'application/json; charset=utf-8',
        }
        self.client.post(
            '/user/signup',
            json={
                "user_id": self.user_id,
            }
        )    
    
    @task(1)
    def signin(self):
        """
Utilisateur en ligne
        """
        self.client.post(
            '/user/signin',
            json={
                "client_id": self.client_id,
            }
        )

    @task(10)
    def status(self):
        """
Obtenir des informations utilisateur
        """
        self.client.post(
            '/client/status',
            json={
                "client_id": self.client_id,
            }
        )        
        

class MyLocust(HttpLocust):
    task_set = ScenarioTaskSet
    #Temps d'attente minimum pour l'exécution de la tâche
    min_wait = 1000
    #Temps d'attente maximum pour l'exécution de la tâche
    max_wait = 1000


Puis exécutez-le avec la commande suivante.

locust -H http://apiserver.co.jp(← Serveur que vous souhaitez charger)

Lorsque vous y accédez avec un navigateur et que l'écran TOP du criquet apparaît, la préparation du criquet est terminée. スクリーンショット 2016-02-22 1.25.19.png Après cela, vous pouvez démarrer le test de charge en spécifiant le nombre d'utilisateurs et le facteur d'amplification.

Lorsque vous démarrez réellement, vous pouvez voir les informations qui se chargent sur le navigateur comme ceci. スクリーンショット_2016-03-06_23_20_59.png

locust a une fonction de synchronisation avec plusieurs esclaves, et cette fois nous avons préparé environ 10 serveurs dédiés pour les criquets, et enfin chargé le serveur API à partir de 10 serveurs locust.

New Relic

Lorsque le criquet est prêt, essayez de le charger et vérifiez l'état du chargement avec New Relic. Dans ce test de charge, cette nouvelle relique jouera un rôle de premier plan. Lors du réglage des performances, chargez-la avec des criquets, vérifiez la partie où la charge est appliquée avec New Relic et réparez-la avec une étoile de réglage. Faire le travail. (Pour plus d'informations sur la configuration de New Relic dans l'application Django, ceci est utile.](Https://gist.github.com/voluntas/7278351))

Vérifier la nouvelle relique

Chargeons-le et jetons un coup d'œil à New Relic. Ci-dessous, la "vue d'ensemble" de New Relic. Vous pouvez voir toutes les informations sur cette page. Ce sont les données avant le réglage, mais le débit est de 43 tr / min. C'est assez terrible. De plus, dans le graphique "temps de réponse de tarnsaction Web", il est codé par couleur pour chaque type de traitement, et dans cet exemple, le bleu clair occupe la majeure partie de celui-ci, vous pouvez donc voir que cela prend trop de temps pour le traitement Python dans son ensemble. Je vais. Si vous regardez la transition ci-dessous, vous pouvez également voir que le traitement de l'API prend trop de temps et qu'il y a de nombreuses erreurs au taux d'erreur. スクリーンショット_2016-02-29_0_25_02.png

Nous ajusterons sur la base de ces données et l'élèverons à la performance cible. Maintenant, laissez-moi vous donner un exemple simple de la façon de régler.

réglage

Jetez un œil à la page Transactions de New Relic pour voir quelles API sont le goulot d'étranglement lorsque le traitement est lent. Si vous sélectionnez La plupart du temps, les demandes seront affichées dans l'ordre de traitement le plus lent. スクリーンショット_2016-03-06_22_54_25.png

À propos, cette fois, la plupart des causes sont le traitement python, donc "App Server ventilation" est tout bleu, mais généralement le ratio pour chaque traitement est visualisé comme ceci. スクリーンショット_2016-03-06_23_03_10.png

De plus, sous le graphique, un "Tableau de répartition" est affiché, où vous pouvez voir où cela prend du temps, y compris SQL. Si le nombre d'appels de requête SQL (appels Moy) est anormalement élevé ou si le traitement prend beaucoup de temps, corrigez-le. Cette fois, j'ai réglé en combinant des requêtes qui ont été appelées plusieurs fois en une seule et en définissant les appels Avg sur 1, et pour SQL avec temps lent, en ajustant INDEX autour et en raccourcissant le temps. スクリーンショット_2016-02-23_18_53_32.png

Cependant, les détails de la fonction qui pointe vers la partie que python traite ne peuvent pas être confirmés ici. Vous pouvez ensuite accéder à la page Trace de transaction sous «Traces de transaction» sous «Tableau de ventilation» pour voir des informations plus détaillées. f0a98788-4354-b552-14bc-782d99234478.png

Par exemple, dans "Détails du suivi", le contenu du traitement est affiché dans l'ordre du traitement de cette manière, il est donc très pratique lorsque vous souhaitez marquer la pièce réparée pour déterminer quelle partie du traitement est la cause. スクリーンショット_2016-03-06_23_51_02.png

Dans ce cas, avant INSERT, le contenu sélectionné dans les deux tables était résumé par un traitement en boucle python et le contenu était INSERT.

En comparant avec "Trace details", il peut être déterminé que le code d'application sous charge fait partie du traitement en boucle de python. Par conséquent, en réduisant la charge de traitement en boucle, nous avons pu éliminer la partie problématique du code d'application.

Fondamentalement, en répétant "chargement → recherche de la cause → réparation de la cause et amélioration des performances", la requête peut être traitée de manière stable jusqu'à la valeur cible d'utilisation du processeur, et il n'y a plus de place pour la réparer. Nous améliorerons les performances du serveur en améliorant toutes les causes, y compris le traitement SQL et le traitement du code.

Mesurer la valeur limite

Après avoir réglé le serveur, il est temps de mesurer les limites. Étant donné que la limite supérieure est de 50% d'utilisation du processeur, la charge est appliquée lors de la vérification de l'utilisation du processeur du serveur avec la commande top. スクリーンショット_2016-03-07_1_03_10.png

Tout d'abord, lorsque l'utilisation du processeur atteint 50%, vérifiez que le traitement est stable sur l'écran du navigateur de locus, ajustez le locus et continuez à appliquer la charge lorsque l'utilisation du processeur est d'environ 50%. .. À ce stade, vous pouvez calculer le RPM à partir du RPS du criquet, mais cette fois, nous ajustons les performances en fonction de la valeur numérique de New Relic, vérifiez donc le RPM de New Relic pour unifier, et la limite du serveur Il a été défini comme une valeur.

En conséquence, les performances d'un serveur ont été décidées, donc si vous pouvez augmenter le nombre et vérifier si la charge est correctement répartie, vous pouvez simplement préparer le nombre requis pour l'opération.

C'est un test de charge difficile

J'ai brièvement présenté la méthode du test de charge, mais ce n'est qu'un exemple, et lorsque vous essayez réellement le test, divers murs se dressent.

  • Difficile de penser aux scénarios acridiens ――Il était difficile d'ajuster le scénario lorsqu'il y a une dépendance entre les tâches et de considérer la fréquence de mise à jour des données. En particulier, la fréquence des mises à jour des données est directement liée à la charge, donc cela seul changera considérablement les résultats du test de charge.
  • Frapper l'API d'un service externe «Dans ce cas, il était nécessaire de calculer combien la charge du service externe affecterait, et il était difficile de penser à une méthode. —— Difficile de rechercher la cause de la charge ――Si le code semble avoir une charge lourde, ou s'il est causé par une instruction SQL, vous pouvez le corriger en lui ajoutant une étoile en suivant la procédure présentée ici. Il existe de nombreux schémas dans lesquels il semble qu'il n'y ait pas de problème à première vue, mais cela ne fonctionne pas pour une raison quelconque. Dans ce cas, il est nécessaire d'avoir beaucoup de connaissances et d'expérience afin de réfléchir à l'approche de la solution sous différents angles.

Résumé

Si vous supprimez la procédure d'utilisation et de réglage de New Relic introduite cette fois, vous pourrez peut-être effectuer un test de charge de base. Cependant, en réalité, davantage de problèmes surviennent et différentes approches de réglage sont nécessaires. Si c'est votre première fois, nous vous recommandons de passer le test avec les conseils d'une personne expérimentée. Si vous pensez avoir assez bien amélioré les performances, et si vous demandez à une personne expérimentée de le vérifier, en fait, la quantité de charge n'est pas suffisante </ b>.

De plus, le test de charge est robuste, donc si vous avez de faibles compétences, vous risquez d'être surchargé à chaque fois que vous chargez le serveur et vous ne savez peut-être pas qui est le test de charge.

Cependant, comme ce sera beaucoup d'étude, je suis sûr que le débit du serveur et de moi-même sera considérablement augmenté au moment où le test de charge douloureux sera terminé! </ b> Si vous avez une chance, une fois que vous en faites l'expérience, ce sera une excellente expérience d'apprentissage. Je suis sûr que vous allez développer votre amitié avec le serveur avec lequel vous avez eu du mal ☆

Articles Liés

Recommended Posts