¿Hierro u optimización? Badoo, Avito y Mamba: sobre el rendimiento de PHP

El problema de rendimiento de PHP para Badoo es uno de los más importantes. La calidad del backend de PHP depende directamente de la cantidad de recursos que gastamos en desarrollo y operación, la velocidad del servicio y la impresión que causa en los usuarios.

Por lo tanto, en el tema de la tercera reunión de la comunidad de desarrolladores de PHP en nuestra oficina, realizamos el rendimiento del backend e invitamos a colegas de Avito y Mamba a discutir.



Leí en la transcripción de la escena, en la que tuve la suerte de ser moderador: cómo se organiza la infraestructura de las tres compañías, cómo medimos la productividad y en qué métricas nos enfocamos, qué herramientas usamos, cómo hacemos una elección entre hardware y optimización.

Y el 15 de febrero, ven al próximo Badoo PHP Meetup : discute Legacy.



Hemos descifrado solo la parte de la discusión, que nos pareció la más interesante. La versión completa está disponible en video.

Expertos:

  • Semyon Kataev, Jefe de Unidad de Desarrollo en Core Services Avito
  • Pavel Murzakov pmurzakov, PHP Timlid en Badoo
  • Mikhail Buylov mipxtx, Director de TI de Mamba


Cuente una historia sobre la optimización de su práctica: el gran éxito o el gran fracaso es algo interesante para compartir.

Mikhail Buylov, Mamba


Tengo una parábola

Aproximadamente una vez cada seis meses observamos las métricas y buscamos lo que se ralentiza, no funciona bien, lo que debe optimizarse. Una vez que notamos nuestro contenedor de dependencia de Symfony, que creció a 52,000 líneas. Decidimos que él, el sinvergüenza, tenía la culpa de todo: 20 ms de gastos generales por cada solicitud. Lo aserramos Lo redujimos. De alguna manera tratamos de separarlo, pero nada ayudó.

Y luego resultó que tenemos anti-spam que necesita ir a 20 bases de datos para cumplir con todas las solicitudes necesarias.

Las soluciones que vienen primero no siempre son las correctas. Observe mejor los rastros, registros y puntos de referencia de sus solicitudes, y no se rompa directamente. Aquí hay una historia.

Pavel Murzakov, Badoo


Tenemos un ecosistema bastante grande en PHP, por lo que periódicamente hacemos la optimización. Estamos creciendo, estamos alcanzando cierto nivel en la CPU, entendemos que necesitamos comprar hardware u optimizarlo. Considere los argumentos a favor y en contra de cada opción y decida. Muy a menudo, a favor de la optimización, porque el hierro necesita mucho.

En uno de estos puntos, identificamos a todo un grupo que se dedicaba a buscar varias cosas no óptimas en los scripts PHP y a optimizarlo. Esto sucedió literalmente "gota a gota": aquí encontraron un porcentaje, allí encontraron un porcentaje, varias personas encontraron un porcentaje en un mes. En algún momento, nuestro sishnik estaba cercaeinstein_man. Decidió ver qué podía hacer: fue por la noche, lanzó Perf, encontró un par de problemas en las extensiones de PHP y aceleró todo en un par de noches en un 13%.

Semyon Kataev, Avito


Tengo dos historias Uno sobre el archivo, el otro sobre el súper desarrollador.

Sobre el fracaso. Tenemos muchos microservicios, incluido PHP. Todos trabajan en Kubernetes. Trabajé en uno de estos microservicios. Hubo una utilización significativa de la CPU: pasaron una semana optimizando y encontrando problemas. Resultó que uno de los desarrolladores agregó Xdebug a las imágenes base para calcular las pruebas de cobertura de código en su (otro) servicio, ¡después de lo cual todos los microservicios en producción trabajaron con Xdebug durante un cuarto! Después de un cuarto, descubrimos esto, arreglamos imágenes básicas y comenzamos a atrapar regalos inesperados: volví a lanzar mi servicio y comenzó a funcionar más rápido. En cada implementación, nuestra imagen de servicio se reconstruye y ahora sin Xdebug.

Historia del éxito. Tenemos muchos microservicios, y se hicieron cada vez más. En esta situación, el número de llamadas RPC se convierte en un problema. Por ejemplo, en una tarjeta de anuncio, y esta es una de las páginas más frecuentes en Avito, alrededor de 30 microservicios están involucrados en el procesamiento de una página. Además, todo esto no se hizo de manera muy explícita: parece que está llamando a algún tipo de abstracción, y bajo este se realizan cinco llamadas RPC a otros servicios de forma secuencial.

Con los años, la tarjeta de anuncio ha sido muy degradada. Un desarrollador fuerte luchó por un cuarto, optimizó y sacó todas las llamadas de RPC. Cuando pudo hacer esto, los paralelizó a través de la solicitud múltiple de Guzzle, y en lugar de 30 solicitudes síncronas consecutivas, recibió las mismas 30 solicitudes, pero paralelas, lo que aceleró enormemente el trabajo. Después de esta refactorización, el tiempo de respuesta de la tarjeta es igual al tiempo de respuesta máximo de cualquiera de los servicios. Pero necesitaba un trimestre entero para optimizar / reescribir el código de visualización de la tarjeta de anuncio.

Díganos, ¿cuál es el tamaño de su clúster de PHP, cómo está configurado?

Mikhail Buylov, Mamba


Tenemos alrededor de 15,000 RPS. Un grupo de 80 servidores FPM comprados hace varios años. En cada clúster, FPM (hasta 50 niños como máximo) se inicia en estática. Cargó alrededor de diez en el pico en horario estelar. El tiempo de respuesta promedio es de 100 ms, e intentamos mantenerlo (cuando excede los 100 ms, comenzamos la búsqueda de piezas de frenado).

Tenemos nuestro propio sistema de monitoreo de desempeño. Dispersamos muchos contadores en el código, alrededor de 120 por solicitud. Monitoreamos muchos eventos que ocurren dentro del código en PHP.

Pavel Murzakov, Badoo


Todo es estándar con nosotros: nginx, PHP-FPM. Aproximadamente 600 servidores con FPM. Si hablar sobre PHP, entonces, probablemente, hay alrededor de 300 servidores más para diversos fines, como script, back-office y otros.

De las características de configuración, hay dos. En primer lugar, tenemos un proxy BMA: este es un proxy para dispositivos móviles. Es decir, antes de que una solicitud llegue a nginx, llega a un proxy especial que mantiene una conexión persistente y envía solicitudes a nginx. La segunda característica: a veces es necesario desactivar el opcache de la CLI (lo tenemos activado en las máquinas de secuencias de comandos). Una vez que no lo apagamos y perdimos el 30% de la CPU en esto. Después de darse cuenta de su error, se sorprendieron de cuánto puede ahorrar con una configuración.

Tenemos parches PHP, pero casi no están relacionados con el rendimiento.

Hay un punto con el bloqueo APCu competitivo: cuando necesita escribir mucho en la misma clave. La arquitectura interna de APCu está construida de tal manera que hay un bloqueo global de teclas, y durante la grabación intensiva, comienzan los frenos. Por lo tanto, tenemos una extensión personalizada allí que resuelve este problema. Esto solo se relaciona en parte con el rendimiento, ya que afecta el tiempo de respuesta, pero no el consumo de CPU.

Semyon Kataev, Avito


Tenemos alrededor de 2 millones de solicitudes por minuto (~ 33 kRPS). Una aplicación monolítica escrita en PHP se ha escrito durante más de 11 años. Está en una fase de rápido crecimiento. Cuando la compañía comenzó, había 65 LXC en 65 servidores físicos. En cada contenedor con la aplicación, se ejecuta PHP-FPM, nginx y software auxiliar para métricas y registros. Nada especial.

Con los años, nunca hemos agregado hierro para un monolito. Estamos aumentando la asistencia, la cantidad de anuncios, la cantidad de transacciones de usuarios, y constantemente optimizamos, mejoramos el código, optimizamos el software. El consumo de CPU y memoria ha disminuido en los últimos años: 65 contenedores para un monolito ahora son suficientes para nosotros.

¿Cómo se mide el rendimiento? ¿Qué herramienta mides el tiempo de respuesta del cliente?

Mikhail Buylov, Mamba


Tenemos un sistema de recopilación de registros. Registra dos indicadores: el tiempo desde el inicio de FPM hasta la función de apagado y hasta el final del script. La segunda métrica es necesaria para ver qué sucede después de la función de apagado.

Medimos JS. Esto, de hecho, es más o menos métrico; los canales de red a menudo se violan. Como resultado, la carga en algún lugar del interior de Rusia comienza a disminuir. Por lo tanto, nos vemos así: "Oh, saltó, significa que en algún lugar algo se cayó". Además, la publicidad de terceros distorsiona mucho la métrica. Y, lo más importante, vienen los spammers, y esto generalmente es algún tipo de aleatoriedad.

Semyon Kataev, Avito


Por cierto, solíamos usar Pinba de Badoo de manera muy activa . Me gusta ella ahora. La mayoría de las métricas fueron recopiladas por él, pero luego cambiaron al protocolo StatsD. Ahora estamos tomando medidas desde diferentes puntos: desde el frente, desde los servidores frente a la aplicación, desde nginx y desde la propia aplicación PHP. Tenemos un equipo de rendimiento dedicado. Comenzó con el desempeño del frente, pero luego cambió a retroceso. Desde el frente, recopila no solo JS, CSS y otras estadísticas, sino también el tiempo de respuesta del servidor. En primer lugar, nos centramos en el tiempo de respuesta de la aplicación.

Pavel Murzakov, Badoo


Todo es similar a lo que nos dijeron los muchachos. Usando el clásico Pinba para PHP, medimos el tiempo de ejecución de un script PHP en términos de PHP. Pero también tenemos, por ejemplo, Pinba para nginx, que mide el tiempo de respuesta desde el punto de vista de nginx. También recopilamos métricas en el cliente.

Que estamos mirando Por un lado, el tiempo de respuesta. No está relacionado con la planificación de recursos. Si es malo, necesita ser mejorado, porque es, de hecho, la calidad del servicio. Otra cosa es que necesita planificar de alguna manera el hierro. Nuestros equipos de ITOps y monitoreo monitorean todo el hardware. Hay algunas barras en la red, en el disco. Hay algunos valores después de los cuales se produce la alerta, y estamos haciendo algo. Como ha demostrado la práctica, generalmente optimizamos para la CPU: nos encontramos con ella.

Semyon Kataev, Avito


En nosotros, la aplicación PHP se mide a sí misma y en register_shutdown_function () arroja métricas. Cada LXC tiene un servidor StatsD, que recopila estas métricas y las envía a través de los recopiladores al clúster Graphite (incluido ClickHouse), donde se almacenan los datos. Este es un autodiagnóstico.

También en cada contenedor hay nginx, es decir, nginx + PHP-FPM. Con nginx, recopilamos métricas externas relacionadas con el tiempo de ejecución de una aplicación PHP. También se enfrentan a servidores separados (los llamamos avi-http) nginx, que realiza un enrutamiento básico, que también recopila métricas de nivel superior, como el tiempo de respuesta, la cantidad de 500 códigos de respuesta y otros.

¿Qué herramientas tienes para una pista de rendimiento? ¿Qué usas con más frecuencia?

Mikhail Buylov, Mamba


Escribimos nuestra propia herramienta. Cuando Pinba acaba de salir, en 2012, hace mucho tiempo, era un módulo para MySQL que recibió algo como esto a través de UDP. Fue difícil sacar los gráficos; no estaba muy optimizado para el rendimiento. Y no se nos ocurrió nada mejor que escribir nuestra propia cosa llamada Better Than Pinba. Es solo un servidor de contador que los acepta desde un cliente PHP.

Dispersamos muchos temporizadores en el código: cada vez que queremos medir algo, establecemos el inicio y la parada del temporizador en el código. El módulo mismo calculará el tiempo de ejecución del contador, agregará los contadores acumulados en un paquete y los enviará al demonio. La interfaz en sí extraerá todo lo que necesita y creará gráficos conectados en el contador deseado.

Uno de los problemas de Pinba era la falta de su propia interfaz: era necesario transferir datos a RRD (entonces había tanta oscuridad). Por lo tanto, escribimos nuestra propia interfaz. Cada vez que vemos lo que saltó, podemos instalar el script. En el script, todos los contadores agregados nos son enviados, los cuales nos son enviados. Podemos ver dónde creció el contador, o si aumentó el tiempo de respuesta en el contador, o si aumentó el número de contadores.

Se puede ver cuando el rendimiento cae. Estamos empezando a cavar de esta manera. Antes de PHP 7, usamos XHProf, luego dejó de construir con nosotros. Por lo tanto, cambiamos a Xdebug. Xdebug solo tocamos cuando el problema es visible.

Pavel Murzakov, Badoo


Esta es una creencia común de que XHProf no se construirá en PHP 7. Esto es cierto, pero solo en parte. Si toma XHProf del asistente, realmente no lo hará. Pero si en GitHub cambia a una rama llamada Experimental (o algo así), entonces todo funciona bien para PHP 7, listo para la producción. Comprobado.

Mikhail Buylov, Mamba


No, me cambié. No funcionó para mí.

Pavel Murzakov, Badoo


Quiero agregar sobre Pinba. Te has convertido en profetas hasta cierto punto. También nosotros, en algún momento, perdimos productividad. Hicimos Pinba2 , que es muy rápido. Se puede usar como reemplazo de Pinba.

Semyon Kataev, Avito


Todo es modesto con nosotros. Acabamos de tomar la dirección del rendimiento en el trabajo: recopilamos métricas, como el tiempo de respuesta. Usamos StatsD. Todavía no usamos perfiladores de forma regular, pero estoy seguro de que algunos equipos los usan en sus microservicios escritos en PHP. En mi opinión, incluso alguien transmite New Relic. Pero en el contexto de la aplicación monolítica principal, hasta ahora solo nos estamos acercando a esto.

Pavel Murzakov, Badoo


La historia del hierro se controla en Grafana, Zabbix. En cuanto a la parte de PHP, tenemos Pinba, tenemos un montón de temporizadores; Construimos gráficos convenientes en ellos. Usamos XHProf, en producción lo manejamos para una parte de las solicitudes. Siempre tenemos nuevos perfiles XHProf disponibles. Tenemos liveprof: esta es nuestra herramienta, puedes leer sobre ella, incluso en mi artículo . Todo sucede automáticamente, solo tienes que mirar. Usamos phpspy. No siempre se inicia con nosotros: cuando alguien quiere ver algo, entra al auto y se quita el perfil. En principio, como es el caso con Perf.

Semyon Kataev, Avito


XHProf tiene la misma historia. Una vez lo usamos hace mucho tiempo: fue una iniciativa personal de un par de desarrolladores y, de hecho, no despegó. Él dejó de coleccionar. Recopilamos un montón de métricas de llamadas de enrutadores, controladores, varios modelos. Alrededor del 60-70% de la red interna del centro de datos está ocupada por paquetes UDP con métricas. Por el momento, esto es suficiente para nosotros. Ahora buscaremos nuevos lugares para la optimización.

Desde que hemos llegado al punto del hierro: ¿hay alguien sistemáticamente involucrado en la planificación de capacidad en su empresa? ¿Cómo se construye este proceso?

Semyon Kataev, Avito


Una aplicación monolítica ejecuta al menos 65 LXC durante al menos cinco años. Optimizamos el código, lo mejoramos: tiene suficientes recursos. Nuestra planificación de capacidad principal se dirige a Kubernetes, donde se escriben alrededor de 400 microservicios más o menos vivos en PHP / Go. Poco a poco estamos cortando piezas del monolito, pero todavía está creciendo. No podemos detenerlo.

En general, PHP es un lenguaje genial. Implementa rápidamente la lógica empresarial.

Pavel Murzakov, Badoo


En primer lugar, ITOps y los equipos de monitoreo se aseguran de que haya suficientes recursos. Si comenzamos a acercarnos al valor umbral, los colegas lo notan. Probablemente son los principales responsables de la planificación de la capacidad global. La parte PHP tiene el recurso principal de la CPU, por lo que lo seguimos nosotros mismos.

Nos fijamos el listón: no debemos "comer" más del 60% del grupo. 60%, y no 95%, porque tenemos hypertreading, que además extrae más del procesador de lo que puede exprimir sin él. Por esto, pagamos por el hecho de que después del 50% de nuestro consumo de CPU podemos crecer de una manera impredecible, porque los núcleos hiper leídos no son del todo honestos.

Mikhail Buylov, Mamba


Realizamos un despliegue y vemos que algo ha fallado con nosotros, como la planificación de la capacidad. A simple vista! Tenemos un cierto margen de productividad que nos permite hacer esto. Tratamos de mantenerlo.

Además, hacemos una optimización post factum. Cuando vemos que algo se ha caído, retrocedemos si todo está completamente mal. Pero esto prácticamente no sucede.

O simplemente vemos que "aquí no es óptimo, ahora arreglaremos todo rápidamente y todo funcionará como debería".

No nos molestamos especialmente: es muy difícil y el escape no será muy grande.

Estás hablando de microservicios. ¿Cómo interactúan? ¿Es REST o está utilizando protocolos binarios?

Semyon Kataev, Avito


Kafka se utiliza para enviar eventos entre servicios, JSON-RPC se utiliza para garantizar la interacción entre los servicios, pero no es completa, sino su versión simplificada, de la que no podemos deshacernos. Hay implementaciones más rápidas: el mismo protobuf, gRPC. Esto está en nuestros planes, pero ciertamente no es una prioridad. Con más de 400 microservicios, es difícil portarlos todos al nuevo protocolo. Hay toneladas de otros lugares para optimizar. Definitivamente no estamos a la altura ahora.

Pavel Murzakov, Badoo


Nosotros como tales no tenemos microservicios. Hay servicios, también está Kafka, su propio protocolo sobre el protobuf de Google. Probablemente, usaríamos gRPC, porque es genial, tiene soporte para todos los idiomas, la capacidad de unir fácilmente diferentes piezas. Pero cuando lo necesitábamos, el gRPC aún no estaba allí. Pero había un protobuf, y lo tomamos. Además, se agregaron diferentes cosas para que no se tratara solo de serialización, sino de un protocolo completo.

Mikhail Buylov, Mamba


Tampoco tenemos microservicios. Hay servicios escritos principalmente en C. Utilizamos JSON-RPC porque es conveniente. Acaba de abrir el socket cuando depura su código y rápidamente escribió lo que quería. Algo ha vuelto a ti. Protobuf es más difícil porque necesitas usar algunas herramientas adicionales. Hay una pequeña sobrecarga, pero creemos que debe pagar por conveniencia, y este no es un gran precio.

Tienes grandes bases de datos. Cuando necesita cambiar el circuito en uno de ellos, ¿cómo lo hace? ¿Algún tipo de migraciones? Si estas migraciones tardan varios días, ¿cómo afecta esto al rendimiento?

Mikhail Buylov, Mamba


Disponemos de mesas grandes, monolíticas. Hay un fragmento El fragmento se altera bastante rápido, porque hay muchos cambios paralelos a la vez. Una mesa grande con perfiles alteró unas tres horas. Utilizamos herramientas Perkonovskie que no lo tienen para leer y escribir. Además, implementamos la modificación para que el código sea compatible con ambos estados. Después de alterar, también implementamos: la implementación es más rápida que la aplicación de cualquier esquema.

Pavel Murzakov, Badoo


Tenemos el almacenamiento más grande (lo llamamos "puntos"): esta es una gran base de datos fragmentada. Si tomamos la tabla "Usuario", entonces ella tiene muchos fragmentos. No le diré exactamente cuántas tablas habrá en un servidor: la idea es que hay muchas pequeñas. Cuando cambiamos el circuito, de hecho, solo hacemos un cambio. En cada mesa pequeña, sucede rápidamente. Hay otros repositorios, ya hay otros enfoques. Si hay una base enorme, hay herramientas perconianas.

En general, utilizamos diferentes cosas según las necesidades. El cambio más frecuente es un cambio en esta enorme base puntual fragmentada, en la que ya tenemos un proceso construido. Todo funciona de manera muy simple.

Semyon Kataev, Avito


La misma aplicación monolítica que sirve a la mayoría del tráfico se implementa de cinco a seis veces al día. Casi cada dos horas.

En términos de trabajar con la base de datos, este es un tema aparte. Hay migraciones, se mueven automáticamente. Esta es una revisión de DBA. Hay una opción para omitir la migración y rodar manualmente. La migración pasará automáticamente a la fase de prueba al probar el código. Pero en la producción, si hay algún tipo de migración dudosa que utiliza muchos recursos, el DBA lo iniciará manualmente.

El código debe ser tal que funcione con las estructuras de bases de datos antiguas y nuevas. A menudo hacemos múltiples viajes para implementar funciones. Para dos o tres despliegues, es posible obtener el estado deseado. Del mismo modo, hay grandes bases de datos, bases de datos fragmentadas. Si contamos para todos los microservicios, definitivamente hay entre 100 y 150 implementaciones por día.

Me gustaría saber cuál es el tiempo de respuesta estándar para usted que está siguiendo. ¿Cuándo comprende lo que necesita para optimizar aún más, o cuál es el momento de terminar? ¿Existe un valor de "promedio hospitalario"?

Pavel Murzakov, Badoo


No. Depende del punto final. Nos fijamos en todo por separado. Tratando de entender cuán crítico es esto. Algunos puntos finales generalmente se solicitan en segundo plano. Esto no afecta al usuario de ninguna manera, incluso si el tiempo de respuesta es de 20 s. Esto sucederá en el fondo, no hay diferencia. Lo principal es que algunas cosas importantes se hagan rápidamente. Quizás 200 ms todavía está bien, pero un pequeño aumento ya importa.

Mikhail Buylov, Mamba


Estamos cambiando de renderizado HTML a solicitudes API. Aquí, de hecho, la API responde mucho más rápido que la respuesta HTML grande y pesada. Por lo tanto, es difícil distinguir, por ejemplo, un valor de 100 ms. Nos centramos en 200 ms. Luego sucedió PHP 7, y comenzamos a centrarnos en 100 ms. Este es el "promedio para el hospital". Esta es una métrica muy vaga, lo que sugiere que es hora de al menos mirar allí. Y, por lo tanto, nos enfocamos en la implementación y saltamos el tiempo de respuesta después de eso.

Semyon Kataev, Avito


Hicimos un boceto de uno de los equipos de rendimiento. Los colegas midieron cuánto más gana una empresa al acelerar la carga de la página en varios escenarios. Calculamos cuánto más compradores, transacciones, llamadas, transiciones, etc. están sucediendo. Según estos datos, se puede entender que en algún momento, la aceleración deja de tener sentido. Por ejemplo, si el tiempo de respuesta de una de las páginas de 90 ms se aceleró a 70 ms, esto dio + 2% de compradores. Y si acelera de 70 ms a 60 ms, entonces ya hay más 0.1% de compradores, que generalmente se incluye en el error. Al igual que con los chicos, todo depende mucho de la página con la que estamos trabajando. En general, el percentil 75 de Avito, unos 75 ms. En mi opinión, esto es lento. Ahora estamos buscando lugares para optimizar. Antes de la transición a los microservicios, todo sucedió mucho más rápido para nosotros y estamos tratando de optimizar el rendimiento.



Y la eterna pregunta: ¿hierro u optimización? ¿Cómo entender si vale la pena comprar hardware o si es mejor invertir en optimización? Donde esta la frontera

Semyon Kataev, Avito


Mi opinión: un verdadero programador es la optimización. Me parece que en grandes empresas como Badoo, la mía, Yandex, hay muchos desarrolladores de diferentes niveles. Hay desarrolladores junior / pasantes y desarrolladores líderes. Me parece que el número de lugares para la optimización / revisión siempre se agrega allí. El hierro es el último paso. Para un monolito en 65 LXC, no hemos agregado hierro durante mucho tiempo. Utilización de la CPU: 20%. Ya estamos pensando en transferirlos al clúster de Kubernetes.

Pavel Murzakov, Badoo


Realmente me gusta la posición de Semyon. Pero tengo un punto de vista completamente opuesto. En primer lugar, miraría el hierro. ¿Es posible soltar hierro y será más barato? Si es así, entonces es más fácil resolver el problema con el hierro. El desarrollador puede hacer algo más, útil en este momento. El tiempo del desarrollador cuesta dinero. El hierro también cuesta dinero, por lo que debe comparar.

Cuál de estos es más importante no está claro. Si ambos cuestan lo mismo, entonces el hardware gana, porque el desarrollador podrá hacer algo en este momento. Específicamente, en términos del backend de PHP, no podemos hacer esto. La optimización nos cuesta mucho más barato que comprar hierro.

A punto de parar. En términos de planificación, tenemos algún tipo de barra. Si reducimos el consumo de CPU por debajo, entonces nos detenemos. Por otro lado, también existe la calidad del servicio. Si vemos que el tiempo de respuesta no nos conviene en algún lugar, entonces debemos optimizarlo.

Mikhail Buylov, Mamba


Me parece que todo depende del tamaño del equipo y del proyecto. Cuanto más pequeño es el proyecto, más fácil es comprar hardware, porque el salario del desarrollador es constante y el código que funciona, los usuarios que trabajan con él, son muy diferentes. Si hay pocos usuarios, entonces es más fácil comprar hardware y confiar al desarrollador el trabajo para desarrollar el proyecto. Si hay muchos usuarios, un desarrollador puede compensar la mayor parte del costo de los servidores.

Semyon Kataev, Avito


Todo realmente depende de la escala. Si tiene mil servidores y la optimización lleva al hecho de que no necesita otros mil servidores, entonces es claramente mejor optimizar. Si tiene un servidor, puede comprar con seguridad dos o tres servidores más y obtener un puntaje de optimización. Si el comando es pequeño, inicie los servidores comprados. Si el equipo es grande y tiene dos o tres centros de datos, comprar seis centros de datos ya no es tan barato, ni tan rápido.

Como tenemos un mitap de PHP, esta frase debería sonar: ¿por qué necesitamos PHP, ya que tenemos tales problemas todo el tiempo? ¡Reescribamos Go, C, C #, Rust, Node.js!
¿Crees que el enfoque de reescritura generalmente está justificado? ¿Hay algún problema para la solución que valga la pena hacer e invertir en este momento?

Semyon Kataev, Avito


En general, PHP es un muy buen lenguaje. Realmente le permite resolver problemas comerciales. El es lo suficientemente rápido. Todos los problemas de rendimiento son problemas de errores, errores, código heredado (algunos códigos recortados, cosas no óptimas que se habrían disparado en otro idioma de la misma manera). Al portarlos sin formato a Golang, Java, Python, obtienes el mismo rendimiento. Todo el problema es que hay mucho legado.

La introducción de un nuevo idioma, en mi opinión, tiene sentido para ampliar la pila y las oportunidades de empleo. Ahora es bastante difícil encontrar buenos desarrolladores de PHP. Si introducimos Golang en el techradar, entonces podemos contratar gophers. Hay pocos shniks PHP y pocos gophers en el mercado, y juntos ya hay muchos de ellos. Por ejemplo, tuvimos un experimento. Tomamos desarrolladores de C # que están listos para aprender nuevos lenguajes, simplemente ampliamos la pila de contratación. Si les decimos a las personas que les enseñaremos a escribir en PHP, dicen que es mejor no hacerlo. Y si les ofrecemos aprender a escribir en PHP, Go y aun así les prometemos la oportunidad de escribir en Python, la gente estará más dispuesta a responder. Para mí, esta es una extensión de las oportunidades de empleo. En otros idiomas, hay algunas cosas que realmente faltan en PHP. Pero en general, PHP es súper suficiente para resolver problemas de negocios e implementar grandes proyectos.

Pavel Murzakov, Badoo


Probablemente estoy completamente de acuerdo con Semyon. Reescribir simplemente no tiene sentido. PHP es un lenguaje bastante productivo. Si lo compara con otros lenguajes no compilados con script, entonces probablemente será casi el más rápido. ¿Reescribir en algunos idiomas como Go y otros? Estos son otros idiomas, tienen otros problemas. Todavía es más difícil escribir sobre ellos: no es tan rápido y hay muchos matices.

Sin embargo, hay cosas que son difíciles o inconvenientes de escribir en PHP. Algunas cosas multiproceso y multiproceso son mejores para escribir en otro idioma. Un ejemplo de una tarea donde la no utilización de PHP está justificada es, en principio, cualquier almacenamiento. Si este es un servicio que almacena mucho en la memoria, entonces PHP probablemente no sea el mejor lenguaje, porque tiene una sobrecarga de memoria muy grande debido a la escritura dinámica. Resulta que guardas un int de 4 bytes y se consumen 50 bytes. Por supuesto, exagero, pero aún así esta sobrecarga es muy grande. Si tiene algún tipo de almacenamiento, es mejor escribirlo en otro idioma compilado con escritura estática. Al igual que algunas cosas que requieren ejecución de subprocesos múltiples.

Mikhail Buylov, Mamba


¿Por qué se considera que PHP no es muy rápido? Porque es dinámico. La traducción Go es una solución al problema de traducir código de tipeo dinámico a estático. Debido a esto, todo sucede más rápido. Específicamente para Go, en mi plan hay tareas de un flujo de datos específico. Por ejemplo, si hay algún tipo de flujo de datos que necesita convertirse a formatos más convenientes, esto es lo ideal. Criado por un demonio, recibe un flujo de datos en la entrada, emite otro. Poco recuerdo come. PHP consume mucha memoria en este caso: debe asegurarse cuidadosamente de que se limpie.

Transfer to Go es una transferencia a microservicios, porque no recortarás todo el código. No lo tomará ni lo reescribirá en su totalidad. La traducción a microservicios es una tarea más profunda que la traducción de un idioma a otro. Es necesario resolverlo primero, y luego pensar en qué idioma escribir. La parte más difícil es aprender a microservicios.

Semyon Kataev, Avito


No es necesario utilizar Go en microservicios. Muchos servicios están escritos en PHP y tienen un tiempo de respuesta aceptable. El equipo que los apoya decidió por sí mismos que necesitaban escribir la lógica empresarial muy rápidamente e introducir funciones. En realidad, a veces lo hacen más rápido que los gophers.

Tenemos una tendencia a contratar gophers, traducir a Go. Pero todavía tenemos la mayor parte del código escrito en PHP, por lo que será por al menos unos años más. No hay una carrera real, no decidimos que Go sea mejor o peor. Seis lanzamientos se implementan en el monolito diariamente. Nuestro chat "Avito Deploy" tiene una lista de tareas que se implementan. Se implementan al menos 20 tareas por día en cada versión: al menos cinco o seis versiones por día, aproximadamente 80 tareas que las personas han realizado en estas tareas. Todo esto se hace en PHP.

? -, ?

,


Es muy difícil. Hay un momento psicológico: lancé una nueva función, ya está. Lanzamos una nueva característica gigantesca: ¡eres súper joven! Cuando un gerente o desarrollador dice que eliminó una función (desmantelada), no recibe dicho reconocimiento. Su obra no es visible. Por ejemplo, un equipo puede recibir una bonificación por la implementación exitosa de nuevas características, pero no he visto ningún premio por funcionalidad muerta o experimental. Y el resultado de esto puede ser realmente colosal.

Un montón de características heredadas que nadie ya está usando realmente ralentiza el desarrollo. Hay cientos de casos en los que una nueva persona ingresa a una empresa y refactores de un código muerto que nunca se llama porque no sabe que es un código muerto.

Estamos tratando de negociar de alguna manera con los gerentes, descubrir por golog qué tipo de característica era, con los analistas consideramos cuánto dinero trae, quién lo necesita, y solo después de eso tratamos de reducirlo. Este es un proceso complicado.

Mikhail Buylov, Mamba


Cortamos el código muerto cuando llegamos a él. Y está lejos de ser siempre posible cortarlo rápidamente. Primero escribe un código, luego otro, encima de un tercero, y luego debajo de todo resulta que esta característica no es necesaria. Ella saca una gran cantidad de dependencias, que también deben repararse. Esto no siempre es posible, y los gerentes deben informarlo.

El gerente establece la tarea, usted la evalúa. Dices: "Sabes, hombre, haré esto durante seis meses. ¿Estás listo para tolerar medio año? Él dice: "No, pensemos qué se debe cortar, qué se puede dejar. Lo que es fundamentalmente necesario y lo que se necesita para jugar ". Así es como va.

Pavel Murzakov, Badoo


Cuando un desarrollador recibe una función, evalúa lo difícil que es en términos de desarrollo, lo difícil que es en términos de rendimiento. Si ve que uno u otro, aclara con el gerente de producto si esto es realmente necesario, si podemos eliminar algo en alguna parte. A veces sucede que los cambios no son críticos, y los gerentes hacen concesiones rápidamente cuando descubren que esto es complicado o está consumiendo recursos. Simplemente sucede: dices "eliminémoslo", y eso es todo.

Sucede que una característica se va, y después de eso notamos que no funcionará tan bien como nos gustaría. Y luego, nuevamente, puedes hablar con el gerente. A menudo todo termina con éxito.

No hay un proceso integrado para eliminar funciones. Esto se hace esporádicamente. Vemos que hay alguna característica, venimos y ofrecemos desactivarla. Lo apagamos, miramos lo que da y lo cortamos. Otra cosa es el código muerto. Tenemos una extensión especial, incluso una infraestructura completa, para la detección de código muerto. Vemos este código muerto. Estamos tratando de cortarlo lentamente. Otra pregunta es si está realmente muerta y la solicitud nunca ingresa, entonces no afecta el rendimiento de ninguna manera. Afecta la capacidad de soporte. La gente lo lee constantemente, aunque puede que no lo lean. No hay una conexión particular con el rendimiento.

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

, , YouTube-. , - .

, .

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


All Articles