Fer ou optimisation? Badoo, Avito et Mamba - à propos des performances PHP

Le problème de performances PHP pour Badoo est l'un des plus importants. La qualité du backend PHP dépend directement de la quantité de ressources que nous dépensons pour le développement et le fonctionnement, de la vitesse du service et de l'impression qu'il fait aux utilisateurs.

Par conséquent, le sujet de la troisième réunion de la communauté des développeurs PHP dans notre bureau, nous avons fait des performances de backend et invité des collègues d'Avito et Mamba à discuter.



Lisez la transcription de la discussion, dans laquelle j'ai eu la chance d'être modérateur: comment l'infrastructure des trois sociétés est organisée, comment nous mesurons la productivité et sur quelles mesures nous nous concentrons, quels outils nous utilisons, comment nous faisons un choix entre le matériel et l'optimisation.

Et le 15 février, venez au prochain Meetup Badoo PHP : discutez de Legacy.



Nous n'avons déchiffré que la partie de la discussion qui nous a paru la plus intéressante. La version complète est disponible en vidéo.

Experts:

  • Semyon Kataev, chef de l'unité de développement chez Core Services Avito
  • Pavel Murzakov pmurzakov, PHP Timlid à Badoo
  • Mikhail Buylov mipxtx, Directeur informatique de Mamba


Racontez une histoire sur l'optimisation de votre pratique: grand succès ou grand échec est quelque chose d'intéressant à partager.

Mikhail Buylov, Mamba


J'ai une parabole.

Environ une fois tous les six mois, nous examinons les mesures et recherchons ce qui ralentit, ne fonctionne pas bien, ce qui doit être optimisé. Une fois que nous avons remarqué notre conteneur de dépendances symfony, qui est passé à 52 000 lignes. Nous avons décidé que lui, le scélérat, était à blâmer pour tout: 20 ms de frais généraux pour chaque demande. Nous l'avons vu. Nous l'avons réduit. Nous avons en quelque sorte essayé de le séparer, mais rien n'a aidé.

Et puis il s'est avéré que nous avons un anti-spam qui doit aller dans 20 bases de données afin de répondre à toutes les demandes nécessaires.

Les solutions qui viennent en premier ne sont pas toujours les bonnes. Regardez mieux les traces, les journaux et les repères de vos demandes, et ne cassez pas directement. Voici une histoire.

Pavel Murzakov, Badoo


Nous avons un écosystème assez vaste en PHP, nous faisons donc régulièrement de l'optimisation. Nous grandissons, nous atteignons un certain niveau de CPU, nous comprenons que nous devons soit acheter du matériel, soit optimiser. Pesez les arguments pour et contre chaque option et décidez. Le plus souvent - en faveur de l'optimisation, car le fer a besoin de beaucoup.

À l'un de ces points, nous avons identifié tout un groupe qui était engagé dans la recherche de diverses choses non optimales dans les scripts PHP et l'optimisation. Cela s'est produit littéralement «goutte à goutte»: ici, ils ont trouvé un pourcentage, là, ils ont trouvé un pourcentage - plusieurs personnes ont trouvé un pourcentage en un mois. À un moment donné, notre sishnik était à proximitéeinstein_man. Il a décidé de voir ce qu'il pouvait faire: il est allé le soir, a lancé Perf, a trouvé quelques problèmes dans les extensions PHP - et a tout accéléré de 13% en quelques soirées!

Semyon Kataev, Avito


J'ai deux histoires. L'un sur le fichier, l'autre sur le super développeur.

À propos de l'échec. Nous avons de nombreux microservices, dont PHP. Tout le monde travaille chez Kubernetes. J'ai travaillé sur l'un de ces microservices. Il y avait une utilisation importante du processeur: ils ont passé une semaine à optimiser et à trouver des problèmes. Il s'est avéré que l'un des développeurs a ajouté Xdebug aux images de base pour calculer les tests de couverture de code dans son (autre) service, après quoi tous les microservices en production ont travaillé avec Xdebug pendant un trimestre! Après un trimestre, nous avons découvert cela, fixé des images de base - et commencé à attraper des cadeaux inattendus: j'ai relancé mon service, et cela a commencé à fonctionner plus rapidement. À chaque déploiement, notre image de service est reconstruite, et maintenant sans Xdebug.

Histoire de succès. Nous avons de nombreux microservices, et ils sont devenus de plus en plus nombreux. Dans cette situation, le nombre d'appels RPC devient un problème. Par exemple, sur une carte d'annonce - et c'est l'une des pages les plus fréquentes dans Avito - environ 30 microservices sont impliqués dans le rendu d'une page. De plus, tout cela n'a pas été fait de manière très explicite: il semble que vous appeliez une sorte d'abstraction, et en dessous, cinq appels RPC vers d'autres services sont effectués séquentiellement.

Au fil des ans, la carte d'annonce s'est considérablement dégradée. Un développeur solide s'est battu pendant un trimestre, optimisé et a lancé tous les appels RPC. Lorsqu'il a pu le faire, il les a parallélisées via plusieurs requêtes Guzzle - et au lieu de 30 requêtes synchrones consécutives, il a reçu les mêmes 30 requêtes, mais parallèles, ce qui a considérablement accéléré le travail. Après cette refactorisation, le temps de réponse de la carte est égal au temps de réponse maximum de l'un des services. Mais il avait besoin d'un quart entier pour optimiser / réécrire le code d'affichage de la carte d'annonce.

Dites-nous, quelle est la taille de votre cluster PHP, comment est-il configuré - au moins PHP-FPM, ou peut-être un endroit où Apache a eu des problèmes?

Mikhail Buylov, Mamba


Nous avons environ 15 000 RPS. Un cluster de 80 serveurs FPM acheté il y a plusieurs années. Sur chaque cluster, FPM (jusqu'à 50 enfants maximum) est lancé en statique. Il a chargé environ dix heures de pointe aux heures de grande écoute. Le temps de réponse moyen est de 100 ms, et nous essayons de le maintenir (lorsqu'il dépasse 100 ms, nous commençons la recherche de pièces de freinage).

Nous avons notre propre système de surveillance des performances. Nous avons dispersé un grand nombre de compteurs dans le code, environ 120 par demande. Nous surveillons de nombreux événements qui se produisent dans le code en PHP.

Pavel Murzakov, Badoo


Tout est standard chez nous: nginx, PHP-FPM. Environ 600 serveurs avec FPM. Si nous parlons de PHP, alors, il y a probablement environ 300 serveurs supplémentaires à des fins diverses, comme les scripts, le back-office et autres.

Parmi les fonctionnalités de configuration, il y en a deux. Premièrement, nous avons un proxy BMA - c'est un proxy pour mobile. Autrement dit, avant qu'une demande n'arrive dans nginx, elle parvient à un proxy spécial qui détient une connexion persistante et envoie des demandes à nginx. La deuxième fonctionnalité - parfois, vous devez désactiver l'opcache CLI (nous l'avons activé sur les machines de script). Une fois que nous ne l'avons pas éteint et que nous avons perdu 30% du processeur. Après avoir réalisé leur erreur, ils ont été surpris de voir combien vous pouvez économiser avec un seul réglage.

Nous avons des correctifs PHP, mais ils ne sont presque pas liés aux performances.

Il y a un point avec le verrou APCu compétitif - quand vous avez besoin d'écrire beaucoup sur la même clé. L'architecture interne d'APCu est conçue de manière à ce qu'il y ait un verrouillage global des touches et pendant l'enregistrement intensif, les freins commencent. Par conséquent, nous avons une extension personnalisée qui résout ce problème. Cela ne concerne que partiellement les performances, car il affecte le temps de réponse, mais pas la consommation du processeur.

Semyon Kataev, Avito


Nous avons environ 2 millions de demandes par minute (~ 33 kRPS). Une application monolithique écrite en PHP est écrite depuis plus de 11 ans. Il est dans une phase de croissance rapide. Lorsque l'entreprise a démarré, il y avait 65 LXC sur 65 serveurs physiques. Sur chaque conteneur avec l'application, PHP-FPM, nginx et un logiciel auxiliaire pour les métriques et la journalisation sont en cours d'exécution. Rien de spécial.

Au fil des ans, nous n'avons jamais ajouté de fer pour un monolithe. Nous augmentons la fréquentation, le nombre d'annonces, le nombre de transactions des utilisateurs, et nous optimisons constamment, améliorons le code, optimisons les logiciels. La consommation de CPU et de mémoire a diminué ces dernières années: 65 conteneurs pour un monolithe nous suffisent désormais.

Comment mesurez-vous les performances? Quel outil mesurez-vous le temps de réponse du client?

Mikhail Buylov, Mamba


Nous avons un système de collecte de journaux. Il enregistre deux indicateurs - le temps entre le début de FPM et la fonction d'arrêt et jusqu'à la fin du script. La deuxième mesure est nécessaire pour voir ce qui se passe après la fonction d'arrêt.

Nous mesurons JS. En fait, il s'agit d'une métrique médiocre; les canaux réseau sont très souvent violés. En conséquence, le chargement quelque part dans l'outback russe commence à émousser. Par conséquent, nous ressemblons à ceci: "Oh, a sauté - cela signifie que quelque part quelque chose est tombé." De plus, la publicité tierce déforme considérablement la métrique. Et, plus important encore, les spammeurs viennent, et c'est généralement une sorte de hasard.

Semyon Kataev, Avito


Soit dit en passant, nous utilisions très activement Pinba de Badoo. Je l'aime maintenant. La plupart des métriques ont été collectées par lui, mais sont ensuite passées au protocole StatsD. Maintenant, nous prenons des mesures à partir de différents points: de l'avant, des serveurs devant l'application, de nginx et de l'application PHP elle-même. Nous avons une équipe de performance dédiée. Elle a commencé par la performance du front, mais est ensuite passée au support. De face, il collecte non seulement JS, CSS et autres statiques, mais également le temps de réponse du serveur. Tout d'abord, nous nous concentrons sur le temps de réponse de l'application.

Pavel Murzakov, Badoo


Tout est similaire à ce que les gars nous ont dit. En utilisant le Pinba classique pour PHP, nous mesurons le temps d'exécution d'un script PHP en termes de PHP. Mais nous avons aussi, par exemple, Pinba pour nginx, qui mesure le temps de réponse du point de vue de nginx. Nous collectons également des métriques sur le client.

Que regardons-nous? D'une part, le temps de réponse. Elle n'est pas liée à la planification des ressources. S'il est mauvais, il doit être amélioré, car c'est en fait la qualité du service. Une autre chose est que vous devez planifier le fer à repasser. Nos ITOps et nos équipes de surveillance surveillent tout le matériel. Il y a quelques barres sur le réseau, sur le disque. Il y a certaines valeurs après lesquelles l'alerte se produit - et nous faisons quelque chose. Comme la pratique l'a montré, nous optimisons généralement pour le CPU: nous le rencontrons.

Semyon Kataev, Avito


Chez nous, l'application PHP se mesure et dans register_shutdown_function () jette des métriques. Chaque LXC possède un serveur StatsD, qui collecte ces métriques et les envoie via les collecteurs au cluster Graphite (y compris ClickHouse), où les données sont stockées. Ceci est un auto-diagnostic.

Sur chaque conteneur se trouve également nginx, c'est-à-dire nginx + PHP-FPM. Avec nginx, nous collectons des métriques externes liées au temps d'exécution d'une application PHP. Ils sont également confrontés à des serveurs distincts (nous les appelons avi-http) nginx, qui effectue un routage de base, qui collecte également des mesures de niveau supérieur, telles que le temps de réponse, le nombre de 500 codes de réponse, etc.

De quels outils disposez-vous pour une piste de performance? Qu'utilisez-vous le plus souvent?

Mikhail Buylov, Mamba


Nous avons écrit notre propre outil. Lorsque Pinba est sorti - en 2012, il y a très longtemps - c'était un module pour MySQL qui a reçu quelque chose comme ça sur UDP. Il était difficile de retirer les graphiques; il n'était pas très optimisé pour les performances. Et nous n’avons rien trouvé de mieux que d’écrire notre propre truc appelé Better Than Pinba. C'est juste un serveur de comptoir qui les accepte d'un client PHP.

Nous avons dispersé beaucoup de minuteurs dans le code: chaque fois que nous voulons mesurer quelque chose, nous définissons le début et la fin du minuteur dans le code. Le module lui-même calculera le temps d'exécution du compteur, agrégera les compteurs accumulés dans un paquet et les enverra au démon. L'interface elle-même extraira tout ce dont vous avez besoin et construira des graphiques connectés sur le compteur souhaité.

Un des problèmes de Pinba était le manque de sa propre interface - il était nécessaire de transférer des données vers RRD (alors il y avait une telle obscurité). Par conséquent, nous avons écrit notre propre interface. Chaque fois que nous voyons ce qui a sauté, nous pouvons installer le script. Dans le script, tous les compteurs agrégés nous sont envoyés, qui nous sont envoyés. Nous pouvons voir où le compteur a augmenté, ou le temps de réponse au compteur a augmenté, ou le nombre de compteurs a augmenté.

Il peut être vu lorsque les performances diminuent. Nous commençons à creuser de cette façon. Avant PHP 7, nous utilisions XHProf, puis il a cessé de construire avec nous. Par conséquent, nous sommes passés à Xdebug. Xdebug nous poussons uniquement lorsque le problème est visible.

Pavel Murzakov, Badoo


C'est une croyance commune que XHProf ne va pas être construit en PHP 7. C'est vrai, mais seulement en partie. Si vous prenez XHProf depuis l'assistant, ce ne sera vraiment pas le cas. Mais si sur GitHub vous passez à une branche appelée Experimental (ou quelque chose comme ça), alors tout fonctionne bien pour PHP 7, prêt pour la production. Vérifié.

Mikhail Buylov, Mamba


Non, j'ai changé. Ça n'a pas marché pour moi.

Pavel Murzakov, Badoo


Je veux ajouter quelque chose sur Pinba. Vous êtes devenus des prophètes dans une certaine mesure. Nous aussi, à un moment donné, nous avons perdu de la productivité. Nous avons créé Pinba2 , qui est très rapide. Il peut être utilisé en remplacement de Pinba.

Semyon Kataev, Avito


Tout est modeste avec nous. Nous venons de prendre la direction de la performance dans le travail: nous collectons des métriques, telles que le temps de réponse. Nous utilisons StatsD. Nous n'utilisons pas encore de profileurs sur une base régulière, mais je sais avec certitude que certaines équipes les utilisent dans leurs microservices écrits en PHP. À mon avis, même quelqu'un relaie New Relic. Mais dans le cadre de la principale application monolithique, nous ne nous en approchons pour l'instant que.

Pavel Murzakov, Badoo


L'histoire du fer est surveillée à Grafana, Zabbix. Quant à la partie PHP, nous avons Pinba, nous avons un tas de minuteries; Nous construisons des graphiques pratiques sur eux. Nous utilisons XHProf, en production nous le pilotons pour une partie des demandes. Nous avons toujours de nouveaux profils XHProf disponibles. Nous avons liveprof: c'est notre outil, vous pouvez le lire, y compris dans mon article . Tout se passe automatiquement, il suffit de regarder. Nous utilisons phpspy. Ça ne commence pas toujours chez nous: quand quelqu'un veut voir quelque chose, il monte dans la voiture, enlève son profil. En principe, comme c'est le cas avec Perf.

Semyon Kataev, Avito


XHProf a la même histoire. Nous l'avons utilisé il y a longtemps: c'était une initiative personnelle d'un couple de développeurs et, en fait, n'a pas décollé. Il a cessé de collectionner. Nous collectons un tas de métriques à partir d'appels de routeurs, de contrôleurs, de divers modèles. Environ 60 à 70% du réseau interne du centre de données est occupé par des paquets UDP avec des métriques. Pour le moment, cela nous suffit. Nous allons maintenant chercher de nouveaux endroits pour l'optimisation.

Depuis que nous avons atteint le point de fer: quelqu'un est-il systématiquement engagé dans la planification des capacités de votre entreprise? Comment se construit ce processus?

Semyon Kataev, Avito


Une application monolithique fonctionne au moins 65 LXC pendant au moins cinq ans. Nous optimisons le code, l'améliorons: il a suffisamment de ressources. Notre principale planification de capacité va à Kubernetes, où environ 400 microservices plus ou moins vivants sont écrits en PHP / Go. Nous coupons lentement des morceaux du monolithe, mais il continue de croître. Nous ne pouvons pas l'arrêter.

En général, PHP est un langage sympa. Il implémente rapidement la logique métier.

Pavel Murzakov, Badoo


Tout d'abord, les ITOps et les équipes de surveillance s'assurent qu'il y a suffisamment de ressources. Si nous commençons à approcher la valeur seuil, les collègues le remarquent. Ils sont probablement principalement responsables de la planification des capacités mondiales. La partie PHP a la principale ressource CPU, nous la suivons donc nous-mêmes.

Nous nous mettons la barre: il ne faut pas "manger" plus de 60% du cluster. 60%, et non 95%, parce que nous avons l'hypertreading, qui en plus évacue plus du processeur que vous ne pouvez le faire sans lui. Pour cela, nous payons par le fait qu'après 50% de notre consommation CPU nous pouvons croître de façon imprévisible, car les noyaux hyper-lisibles ne sont pas tout à fait honnêtes.

Mikhail Buylov, Mamba


Nous faisons un déploiement et constatons que quelque chose a échoué avec nous - une telle planification des capacités. A l'oeil! Nous avons une certaine marge de productivité qui nous permet de le faire. Nous essayons de nous y tenir.

De plus, nous effectuons une optimisation post factum. Quand nous voyons que quelque chose est tombé, nous reculons si tout est complètement mauvais. Mais cela ne se produit pratiquement pas.

Ou nous voyons juste que "ici n'est pas optimal, maintenant nous allons tout réparer rapidement et tout fonctionnera comme il se doit".

On ne s'en soucie pas particulièrement: c'est très difficile, et l'échappement ne sera pas très gros.

Vous parlez de microservices. Comment interagissent-ils? Est-ce REST ou utilisez-vous des protocoles binaires?

Semyon Kataev, Avito


Kafka est utilisé pour envoyer des événements entre les services, JSON-RPC est utilisé pour assurer l'interaction entre les services, mais pas complet, mais sa version simplifiée, dont nous ne pouvons pas nous débarrasser. Il existe des implémentations plus rapides: le même protobuf, gRPC. C'est dans nos plans, mais certainement pas une priorité. Avec plus de 400 microservices, il est difficile de les porter tous vers le nouveau protocole. Il y a des tonnes d'autres endroits à optimiser. Nous ne sommes définitivement pas à la hauteur maintenant.

Pavel Murzakov, Badoo


En tant que tels, nous n'avons pas de microservices. Il y a des services, il y a aussi Kafka, son propre protocole en plus de Google protobuf. Probablement, nous utiliserions gRPC, car il est cool, il prend en charge toutes les langues, la possibilité de lier très facilement différentes pièces. Mais quand nous en avions besoin, gRPC n'était pas encore là. Mais il y avait un protobuf, et nous l'avons pris. En plus de cela, différentes choses ont été ajoutées afin que ce ne soit pas seulement la sérialisation, mais un protocole complet.

Mikhail Buylov, Mamba


Nous n'avons pas non plus de microservices. Il existe des services principalement écrits en C. Nous utilisons JSON-RPC parce que c'est pratique. Vous venez d'ouvrir le socket lorsque vous déboguez votre code et avez rapidement écrit ce que vous vouliez. Quelque chose vous est revenu. Protobuf est plus difficile car vous devez utiliser des outils supplémentaires. Il y a un petit frais généraux, mais nous pensons que vous devez payer pour plus de commodité, et ce n'est pas un gros prix.

Vous avez d'énormes bases de données. Lorsque vous devez changer le circuit de l'un d'eux, comment procédez-vous? Une sorte de migrations? Si ces migrations prennent plusieurs jours, comment cela affecte-t-il les performances?

Mikhail Buylov, Mamba


Nous avons de grandes tables, monolithiques. Il y a un éclat. Le fragment change assez rapidement, car il y a plusieurs modifications parallèles à la fois. Une grande table avec des profils a changé environ trois heures. Nous utilisons des outils Perkonovskie qui ne le font ni lire ni écrire. De plus, nous déployons pour modifier afin que le code prenne en charge les deux états. Après alter, nous déployons également: le déploiement est plus rapide que l'application de tout schéma.

Pavel Murzakov, Badoo


Nous avons le plus grand stockage (nous l'appelons "spots") - c'est une énorme base de données fragmentée. Si nous prenons la table «Utilisateur», alors elle a beaucoup d'éclats. Je ne vous dirai pas exactement combien de tables seront sur un serveur: l'idée est qu'il y en a beaucoup de petites. Quand on change de circuit, en fait, on fait juste un alter. Sur chaque petite table, ça arrive vite. Il existe d'autres référentiels - il existe déjà d'autres approches. S'il existe une énorme base, il existe des outils perconiens.

En général, nous utilisons différentes choses selon les besoins. Le changement le plus fréquent est un changement dans cette énorme base de tache fragmentée, dans laquelle nous avons déjà un processus construit. Tout fonctionne très simplement.

Semyon Kataev, Avito


La même application monolithique qui dessert la majeure partie du trafic est déployée cinq à six fois par jour. Presque toutes les deux heures.

Pour ce qui est de travailler avec la base de données, il s'agit d'un problème distinct. Il y a des migrations, elles roulent automatiquement. Ceci est une revue DBA. Il existe une option pour ignorer la migration et effectuer un roulement manuel. La migration sera automatiquement mise en scène lors du test du code. Mais en production, s'il y a une sorte de migration douteuse qui utilise un tas de ressources, le DBA la démarrera manuellement.

Le code doit être tel qu'il fonctionne avec les anciennes et nouvelles structures de base de données. Nous effectuons souvent plusieurs déplacements pour déployer des fonctionnalités. Pour deux ou trois déploiements, il est possible d'obtenir l'état souhaité. De même, il existe d'énormes bases de données, des bases de données fragmentées. Si nous comptons pour tous les microservices, il y a certainement 100 à 150 déploiements par jour.

Je voudrais savoir quel est le temps de réponse standard pour vous que vous suivez? Quand comprenez-vous ce dont vous avez besoin pour optimiser davantage, ou quel est le temps de terminer? Y a-t-il une valeur «moyenne hospitalière»?

Pavel Murzakov, Badoo


Non. Dépend du point final. Nous regardons tout séparément. Essayer de comprendre à quel point c'est critique. Certains points d'extrémité sont généralement demandés en arrière-plan. Cela n'affecte en rien l'utilisateur, même si le temps de réponse est de 20 s. Cela se passera en arrière-plan, il n'y a pas de différence. L'essentiel est que certaines choses importantes soient faites rapidement. Peut-être que 200 ms sont encore corrects, mais une petite augmentation compte déjà.

Mikhail Buylov, Mamba


Nous passons du rendu HTML aux requêtes API. Ici, en fait, l'API répond beaucoup plus rapidement que la grande réponse HTML lourde. Par conséquent, il est difficile de distinguer, par exemple, une valeur de 100 ms. Nous nous sommes concentrés sur 200 ms. Puis est arrivé PHP 7 - et nous avons commencé à nous concentrer sur 100 ms. Il s'agit de la «moyenne de l'hôpital». Il s'agit d'une métrique très vague, ce qui suggère qu'il est au moins temps d'y regarder. Et donc nous nous concentrons plutôt sur le déploiement et avons sauté le temps de réponse après.

Semyon Kataev, Avito


Nous avons fait un croquis de l'une des équipes de performance. Des collègues ont mesuré combien une entreprise gagne davantage en accélérant le chargement des pages dans divers scénarios. Nous avons calculé combien plus d'acheteurs, de transactions, d'appels, de transitions, etc. se produisent. D'après ces données, on peut comprendre qu'à un moment donné, l'accélération cesse de faire sens. Par exemple, si le temps de réponse d'une des pages de 90 ms était accéléré à 70 ms, cela donnait + 2% d'acheteurs. Et si vous accélérez de 70 à 60 ms, il y a déjà plus 0,1% d'acheteurs, ce qui est généralement inclus dans l'erreur. Tout comme avec les gars, tout dépend beaucoup de la page avec laquelle nous travaillons. En général, Avito 75e centile - environ 75 ms. À mon avis, c'est lent. Nous recherchons maintenant des endroits à optimiser. Avant la transition vers les microservices, tout s'est passé beaucoup plus rapidement pour nous, et nous essayons d'optimiser les performances.



Et l'éternelle question: le fer ou l'optimisation? Comment comprendre s'il vaut la peine d'acheter du matériel ou vaut-il mieux investir dans l'optimisation? Où est la frontière?

Semyon Kataev, Avito


Mon avis: un vrai programmeur c'est l'optimisation. Il me semble que dans les grandes entreprises comme Badoo, la mienne, Yandex, il existe de nombreux développeurs de différents niveaux. Il y a à la fois des développeurs / stagiaires juniors et des développeurs de premier plan. Il me semble que le nombre de places pour l'optimisation / révision y est toujours ajouté. Le fer est la dernière étape. Pour un monolithe sur 65 LXC, nous n'avons pas ajouté de fer depuis très longtemps. Utilisation du processeur - 20%. Nous envisageons déjà de les transférer dans le cluster Kubernetes.

Pavel Murzakov, Badoo


J'aime vraiment la position de Semyon. Mais j'ai un point de vue complètement opposé. Tout d'abord, je regardais le fer. Est-il possible de faire tomber du fer et sera-t-il moins cher? Si c'est le cas, il est plus facile de résoudre le problème avec le fer. Le développeur peut faire autre chose, utile pour le moment. Le temps du développeur coûte de l'argent. Le fer coûte aussi de l'argent, vous devez donc comparer.

Lequel de ceux-ci est le plus important n'est pas clair. Si les deux coûtent le même prix, le matériel gagne, car le développeur sera en mesure de faire quelque chose à ce stade. Plus précisément, en termes de backend PHP, nous ne pouvons pas le faire. L'optimisation nous coûte beaucoup moins cher que l'achat de fer.

Sur le point de s'arrêter. En termes de planification, nous avons une sorte de bar. Si nous réduisons la consommation du processeur en dessous, nous nous arrêtons. D'un autre côté, il y a aussi la qualité de service. Si nous voyons que le temps de réponse ne nous convient pas quelque part, alors nous devons optimiser.

Mikhail Buylov, Mamba


Il me semble que tout dépend de la taille de l'équipe et du projet. Plus le projet est petit, plus il est facile d'acheter du matériel, car le salaire du développeur est constant et le code qui fonctionne, les utilisateurs qui travaillent avec lui, sont très différents. S'il y a peu d'utilisateurs, il est plus facile d'acheter du matériel et de confier au développeur le travail de développement du projet. S'il y a beaucoup d'utilisateurs, un développeur peut compenser la majeure partie du coût des serveurs.

Semyon Kataev, Avito


Tout dépend vraiment de l'échelle. Si vous avez un millier de serveurs et que l'optimisation conduit au fait que vous n'avez pas besoin d'un autre millier de serveurs, il est clairement préférable d'optimiser. Si vous avez un serveur, vous pouvez acheter en toute sécurité deux ou trois serveurs supplémentaires et obtenir un score d'optimisation. Si la commande est petite, démarrez les serveurs achetés. Si l'équipe est nombreuse et que vous avez deux ou trois centres de données, acheter six centres de données n'est déjà pas si bon marché, ni si rapide.

Puisque nous avons un mitap PHP, cette phrase devrait sonner: pourquoi avons-nous besoin de PHP, car nous avons de tels problèmes tout le temps? Réécrivons Go, C, C #, Rust, Node.js!
Pensez-vous que l'approche de réécriture est généralement justifiée? Y a-t-il des problèmes pour la solution desquels cela vaut la peine de le faire et d'investir en ce moment?

Semyon Kataev, Avito


En général, PHP est un très bon langage. Cela vous permet vraiment de résoudre des problèmes commerciaux. Il est assez rapide. Tous les problèmes de performances sont des problèmes d'erreurs, de bogues, de code hérité (du code sous-coupé, des choses non optimales qui auraient tourné dans une autre langue de la même manière). En les portant brut sur Golang, Java, Python, vous obtenez les mêmes performances. Tout le problème est qu'il y a beaucoup d'héritage.

À mon avis, l'introduction d'une nouvelle langue est logique afin d'élargir la pile et les possibilités d'emploi. Il est maintenant assez difficile de trouver de bons développeurs PHP. Si nous introduisons Golang dans le techradar, nous pouvons engager des gaufres. Il y a peu de shniks PHP et peu de gophers sur le marché, et ensemble il y en a déjà beaucoup. Par exemple, nous avons eu une expérience. Nous avons pris des développeurs C # qui sont prêts à apprendre de nouveaux langages - nous avons simplement élargi la pile d'embauche. Si nous disons aux gens que nous allons leur apprendre à écrire en PHP, ils disent que c'est mieux de ne pas le faire. Et si nous leur proposons d'apprendre à écrire en PHP, Go et promettons toujours la possibilité d'écrire en Python, alors les gens sont plus disposés à répondre. Pour moi, c'est une extension des opportunités d'emploi. Dans d'autres langages, il y a des choses qui manquent vraiment en PHP. Mais en général, PHP est super suffisant pour résoudre des problèmes commerciaux et mettre en œuvre de grands projets.

Pavel Murzakov, Badoo


Je suis probablement tout à fait d'accord avec Semyon. La réécriture n'a tout simplement pas de sens. PHP est un langage assez productif. Si vous le comparez avec d'autres langages scriptés non compilés, il sera probablement presque le plus rapide. Réécrire dans certaines langues comme Go et d'autres? Ce sont d'autres langues, elles ont d'autres problèmes. C’est encore plus difficile de les écrire: pas si vite et il y a beaucoup de nuances.

Néanmoins, il y a des choses qui sont difficiles ou incommodes à écrire en PHP. Certaines choses multi-processus et multi-threads sont mieux écrites dans une autre langue. Un exemple de tâche où la non-utilisation de PHP est justifiée est, en principe, tout stockage. S'il s'agit d'un service qui stocke beaucoup en mémoire, alors PHP n'est probablement pas le meilleur langage, car il a une surcharge de mémoire très importante en raison de la frappe dynamique. Il s'avère que vous enregistrez un entier de 4 octets et que 50 octets sont consommés. Bien sûr, j'exagère, mais cette surcharge est toujours très importante. Si vous avez une sorte de stockage, il est préférable de l'écrire dans un autre langage compilé avec une saisie statique. Tout comme certaines choses qui nécessitent une exécution multi-thread.

Mikhail Buylov, Mamba


Pourquoi PHP n'est-il pas considéré comme très rapide? Parce que c'est dynamique. La traduction Go est une solution au problème de la conversion du code de la frappe dynamique en statique. Pour cette raison, tout se passe plus rapidement. Spécifiquement pour Go, dans mon plan, il y a des tâches d'un flux de données spécifique. Par exemple, s'il existe une sorte de flux de données qui doit être converti dans des formats plus pratiques, c'est l'idéal. Élevé par un démon, il reçoit un flux de données en entrée, il en émet un autre. Peu de mémoire mange. PHP consomme beaucoup de mémoire dans ce cas: vous devez vous assurer soigneusement qu'il est nettoyé.

Transfer to Go est un transfert vers des microservices, car vous n'aurez pas supprimé tout le code. Vous ne le prendrez pas et ne le réécrirez pas dans son intégralité. La traduction vers des microservices est une tâche plus profonde que la traduction d'une langue à une autre. Il faut d'abord le résoudre, puis réfléchir à la langue à écrire. La partie la plus difficile est d'apprendre à microservices.

Semyon Kataev, Avito


Il n'est pas nécessaire d'utiliser Go dans les microservices. De nombreux services sont écrits en PHP et ont un temps de réponse acceptable. L'équipe qui les accompagne a décidé par eux-mêmes qu'ils avaient besoin d'écrire très rapidement la logique métier et d'introduire des fonctionnalités. Ils font en fait parfois plus vite que les gaufres.

Nous avons tendance à embaucher des gaufres, traduisez en Go. Mais nous avons encore la plupart du code écrit en PHP, et il en sera ainsi pendant au moins quelques années de plus. Il n'y a pas de vraie course, nous n'avons pas décidé que Go est meilleur ou pire. Six versions sont déployées quotidiennement dans le monolithe. Notre chat «Avito Deploy» a une liste de tâches qui sont déployées. Au moins 20 tâches sont déployées par jour dans chaque version: au moins cinq ou six versions par jour, soit environ 80 tâches que les gens ont effectuées sur ces tâches. Tout cela se fait en PHP.

? -, ?

,


C'est très difficile. Il y a un moment psychologique: j'ai lancé une nouvelle fonctionnalité - vous avez terminé. Lancement d'une nouvelle fonctionnalité gigantesque - vous êtes super jeune! Lorsqu'un gestionnaire ou développeur dit qu'il a supprimé une fonctionnalité (déclassée), il ne reçoit pas une telle reconnaissance. Son travail n'est pas visible. Par exemple, une équipe peut recevoir un bonus pour la mise en œuvre réussie de nouvelles fonctionnalités, mais je n'ai vu aucun prix pour des fonctionnalités mortes ou expérimentales. Et le résultat de cela peut être vraiment colossal.

Un tas de fonctionnalités héritées que personne n'utilise déjà ralentit vraiment le développement. Il y a des centaines de cas où une nouvelle personne entre dans une entreprise et refactorise un code mort qui n'est jamais appelé parce qu'il ne sait pas qu'il s'agit d'un code mort.

Nous essayons en quelque sorte de négocier avec les gestionnaires, de découvrir par golog de quel type de fonctionnalité il s'agissait, avec les analystes, nous considérons combien d'argent cela rapporte, qui en a besoin, et seulement après cela, nous essayons de le réduire. C'est un processus compliqué.

Mikhail Buylov, Mamba


Nous coupons le code mort quand nous y arrivons. Et il est loin d'être toujours possible de le couper rapidement. D'abord, vous écrivez un code, puis un autre, au-dessus d'un troisième, puis en dessous il s'avère que cette fonctionnalité n'est pas nécessaire. Elle tire un nombre sauvage de dépendances, qui doivent également être corrigées. Ce n'est pas toujours possible et les gestionnaires doivent le signaler.

Le manager définit la tâche, vous l'évaluez. Vous dites: "Vous savez, mec, je vais le faire pendant six mois. Êtes-vous prêt à tolérer six mois? » Il dit: «Non, réfléchissons à ce qui doit être coupé, à ce qui peut être laissé. Ce qui est fondamentalement nécessaire et ce qui est nécessaire pour jouer. » Voilà comment ça se passe.

Pavel Murzakov, Badoo


Lorsqu'un développeur reçoit une fonctionnalité, il évalue sa difficulté en termes de développement, sa difficulté en termes de performances. S'il voit que l'un ou l'autre, il clarifie avec le chef de produit si cela est vraiment nécessaire, si nous pouvons retirer quelque chose quelque part. Parfois, il arrive que les changements ne soient pas critiques, et les gestionnaires font rapidement des concessions lorsqu'ils découvrent que cette chose est compliquée ou mange des ressources. Cela se produit simplement: vous dites "Supprimons-le" - et c'est tout.

Il arrive qu'une fonctionnalité quitte, et après cela, nous remarquons qu'elle ne fonctionnera pas aussi bien que nous le souhaiterions. Et puis, encore une fois, vous pouvez parler avec le gestionnaire. Souvent, tout se termine avec succès.

Il n'y a pas de processus intégré pour supprimer des fonctionnalités. Cela se fait de façon sporadique. Nous voyons qu'il y a une fonctionnalité, nous arrivons et proposons de la désactiver. Nous l'éteignons, regardons ce qu'il donne et le coupons. Une autre chose est le code mort. Nous avons une extension spéciale, même une infrastructure entière, pour la détection de code mort. Nous voyons ce code mort. Nous essayons de le couper lentement. Une autre question est de savoir si elle est vraiment morte et que la requête n'y entre jamais, alors cela n'affecte en rien les performances. Il affecte la prise en charge. Les gens le lisent constamment, bien qu'ils ne le lisent peut-être pas. Il n'y a pas de lien particulier avec les performances.

15 Badoo PHP Meetup. , : SuperJob, ManyChat, , Badoo FunCorp .

, , YouTube-. , - .

, .

Source: https://habr.com/ru/post/undefined/


All Articles