Escalado horizontal de aplicaciones PHP. Conceptos básicos de escalado

A medida que crece la popularidad de una aplicación web, su soporte inevitablemente comienza a requerir cada vez más recursos. Al principio, la carga puede (y sin duda debería) abordarse optimizando los algoritmos y/o la arquitectura de la propia aplicación. Sin embargo, ¿qué hacer si ya se ha optimizado todo lo que se podía optimizar, pero la aplicación aún no puede soportar la carga?

Mejoramiento

Lo primero que debes hacer es sentarte y pensar si ya has conseguido optimizarlo todo:
  • ¿Son óptimas las consultas a bases de datos (análisis EXPLICAR, uso de índices)?
  • ¿Los datos se almacenan correctamente (SQL vs NoSQL)?
  • ¿Se utiliza el almacenamiento en caché?
  • ¿Hay solicitudes innecesarias al sistema de archivos o base de datos?
  • ¿Son óptimos los algoritmos de procesamiento de datos?
  • ¿La configuración del entorno es óptima: Apache/Nginx, MySQL/PostgreSQL, PHP/Python?
Se podría escribir un artículo separado sobre cada uno de estos puntos, por lo que una consideración detallada de ellos en el marco de este artículo es claramente redundante. Solo es importante comprender que antes de comenzar a escalar una aplicación, es muy recomendable optimizar su funcionamiento tanto como sea posible; después de todo, tal vez entonces no sea necesario escalar.

Escalada

Y entonces, digamos que la optimización ya se ha realizado, pero la aplicación aún no puede soportar la carga. En este caso, la solución al problema obviamente puede ser distribuirlo entre varios hosts para aumentar el rendimiento general de la aplicación aumentando los recursos disponibles. Este enfoque tiene el nombre oficial: "escalar" la aplicación. Más precisamente, la "escalabilidad" se refiere a la capacidad de un sistema para aumentar su rendimiento a medida que aumenta la cantidad de recursos que se le asignan. Hay dos métodos de escala: vertical y horizontal. El escalado vertical implica un aumento en el rendimiento de la aplicación al agregar recursos (procesador, memoria, disco) dentro de un solo nodo (host). El escalado horizontal es típico de aplicaciones distribuidas e implica un aumento en el rendimiento de la aplicación al agregar otro nodo (host).

Está claro que la forma más sencilla sería simplemente actualizar el hardware (procesador, memoria, disco), es decir, escalado vertical. Además, este enfoque no requiere ninguna modificación en la aplicación. Sin embargo, el escalado vertical alcanza muy rápidamente su límite, después de lo cual el desarrollador y el administrador no tienen más remedio que pasar al escalado horizontal de la aplicación.

Arquitectura de aplicaciones

La mayoría de las aplicaciones web están a priori distribuidas, ya que en su arquitectura se pueden distinguir al menos tres capas: servidor web, lógica de negocio (aplicación), datos (base de datos, estática).

Cada una de estas capas se puede escalar. Por lo tanto, si en su sistema la aplicación y la base de datos residen en el mismo host, el primer paso, por supuesto, debería ser distribuirlas entre diferentes hosts.

Embotellamiento

Al comenzar a escalar el sistema, el primer paso es determinar qué capa es el "cuello de botella", es decir, funciona más lento que el resto del sistema. Para empezar, puede utilizar utilidades banales como top (htop) para estimar el consumo de procesador/memoria y df, iostat para estimar el consumo de disco. Sin embargo, es aconsejable asignar un host separado con emulación de carga de combate (usando o JMeter), en el que será posible perfilar el funcionamiento de la aplicación usando utilidades como xdebug, etc. Para identificar consultas específicas a la base de datos, puede utilizar utilidades como pgFouine (está claro que es mejor hacerlo basándose en los registros del servidor de producción).

Generalmente depende de la arquitectura de la aplicación, pero los candidatos más probables para un cuello de botella en general son la base de datos y el código. Si su aplicación funciona con una gran cantidad de datos de usuario, lo más probable es que el cuello de botella sea el almacenamiento estático.

Escalado de base de datos

Como se mencionó anteriormente, la base de datos suele ser el cuello de botella en las aplicaciones modernas. Los problemas que surgen generalmente se dividen en dos clases: rendimiento y la necesidad de almacenar una gran cantidad de datos.

Puede reducir la carga de la base de datos distribuyéndola entre varios hosts. Al mismo tiempo, se agudiza el problema de la sincronización entre ellos, que puede solucionarse implementando un esquema maestro/esclavo con replicación síncrona o asíncrona. En el caso de PostgreSQL, puede implementar la replicación sincrónica usando Slony-I, la replicación asincrónica usando PgPool-II o WAL (9.0). El problema de separar las solicitudes de lectura y escritura, así como de equilibrar la carga entre los esclavos existentes, se puede resolver configurando una capa especial de acceso a la base de datos (PgPool-II).

El problema de almacenar grandes cantidades de datos cuando se utilizan DBMS relacionales se puede resolver utilizando el mecanismo de partición ("particionamiento" en PostgreSQL) o implementando bases de datos en sistemas de archivos distribuidos como Hadoop DFS.

Sin embargo, para almacenar grandes cantidades de datos, la mejor solución es la fragmentación de datos, que es un beneficio incorporado en la mayoría de las bases de datos NoSQL (por ejemplo, MongoDB).

Además, las bases de datos NoSQL generalmente funcionan más rápido que sus hermanos SQL debido a la ausencia de gastos generales para el análisis/optimización de consultas, la verificación de la integridad de la estructura de datos, etc. El tema de comparar bases de datos relacionales y NoSQL también es bastante extenso y lo merece.

Por otra parte, cabe destacar la experiencia de Facebook, que utiliza MySQL sin selecciones JOIN. Esta estrategia les permite escalar la base de datos mucho más fácilmente, mientras transfieren la carga de la base de datos al código, que, como se describirá a continuación, escala más fácilmente que la base de datos.

Escalado de código

La dificultad para escalar el código depende de cuántos recursos compartidos necesitan los hosts para ejecutar su aplicación. ¿Serán solo sesiones o requerirán archivos y caché compartidos? En cualquier caso, el primer paso es ejecutar copias de la aplicación en varios hosts con el mismo entorno.

A continuación, debe configurar el equilibrio de carga/solicitud entre estos hosts. Esto se puede hacer tanto a nivel de TCP (haproxy) como a nivel de HTTP (nginx) o DNS.

El siguiente paso es asegurarse de que los archivos estáticos, el caché y las sesiones de aplicaciones web estén disponibles en cada host. Para las sesiones, puede utilizar un servidor que se ejecute en la red (por ejemplo, Memcached). Es bastante razonable utilizar el mismo Memcached como servidor de caché, pero, por supuesto, en un host diferente.

Los archivos estáticos se pueden montar desde un almacenamiento de archivos compartido a través de NFS/CIFS o utilizando un sistema de archivos distribuido (HDFS, GlusterFS, Ceph).

También puede almacenar archivos en una base de datos (por ejemplo, Mongo GridFS), resolviendo así los problemas de disponibilidad y escalabilidad (teniendo en cuenta que para las bases de datos NoSQL el problema de escalabilidad se resuelve debido a la fragmentación).

Por otra parte, cabe señalar el problema de la implementación en varios hosts. ¿Cómo puedo asegurarme de que el usuario, al hacer clic en “Actualizar”, no vea diferentes versiones de la aplicación? La solución más sencilla, en mi opinión, sería excluir los hosts no actualizados de la configuración del equilibrador de carga (servidor web) y activarlos secuencialmente a medida que se actualizan. También puede vincular usuarios a hosts específicos mediante cookie o IP. Si la actualización requiere cambios significativos en la base de datos, la forma más sencilla es cerrar temporalmente el proyecto por completo.

escalado FS

Si es necesario almacenar una gran cantidad de datos estáticos, se pueden identificar dos problemas: falta de espacio y velocidad de acceso a los datos. Como ya se escribió anteriormente, el problema de la falta de espacio se puede resolver al menos de tres maneras: un sistema de archivos distribuido, almacenando datos en una base de datos con soporte de fragmentación y organizando la fragmentación "manualmente" a nivel de código.

Debe entenderse que distribuir estática tampoco es la tarea más fácil cuando se trata de cargas elevadas. Por tanto, es bastante razonable tener muchos servidores dedicados a distribuir archivos estáticos. Además, si tenemos un almacenamiento de datos compartido (sistema de archivos distribuido o base de datos), al guardar un archivo, podemos guardar su nombre sin tener en cuenta el host, y sustituir el nombre del host aleatoriamente al generar la página (equilibrando aleatoriamente la carga entre servidores web que distribuyen archivos estáticos). En el caso de que la fragmentación se implemente manualmente (es decir, la lógica en el código es responsable de elegir el host al que se cargarán los datos), la información sobre el host de carga debe calcularse en función del archivo mismo o generarse en función. en datos de terceros (información sobre el usuario, cantidad de espacio en los discos de almacenamiento) y se guarda junto con el nombre del archivo en la base de datos.

Escucha

Está claro que un sistema grande y complejo requiere un seguimiento constante. La solución, en mi opinión, es estándar aquí: zabbix, que monitorea la carga/operación de los nodos del sistema y monitorea los demonios para realizar copias de seguridad.

Conclusión

Lo anterior analiza brevemente muchas opciones para resolver los problemas de escalar una aplicación web. Cada uno de ellos tiene sus propias ventajas y desventajas. No existe una receta sobre cómo hacer todo bien y a la vez; para cada tarea hay muchas soluciones con sus pros y sus contras. Cuál elegir depende de ti.

La capacidad de escalar un sistema de información, tanto horizontal como verticalmente, es uno de los factores más importantes a los que se debe prestar atención al elegir un medio para automatizar las actividades de cualquier organización. Si la solución elegida no se puede escalar, o cada etapa del crecimiento empresarial generará dificultades con el mantenimiento y desarrollo de dicho producto de software, entonces ni siquiera debería comenzar a utilizarla. Desarrollamos LETOGRAF EDMS teniendo en cuenta los altos requisitos de escala.

La necesidad de escalamiento horizontal o vertical surge en relación con la creación de sistemas de TI corporativos de alta carga que emplean a miles o incluso decenas de miles de usuarios. Sin embargo, no todos los EDMS pueden soportar el funcionamiento simultáneo de una gran cantidad de usuarios. Solo si el EDMS a nivel arquitectónico contiene la capacidad de aumentar el número de usuarios sin pérdida de rendimiento, solo en este caso el escalado será exitoso. El sistema LETOGRAF que creamos fue diseñado para ser idealmente escalable tanto horizontal como verticalmente. Esto se logra tanto a través de la arquitectura del propio sistema y el código de la aplicación que desarrollamos, como a través de la funcionalidad del DBMS InterSystems Caché, sobre el cual se construye nuestro EDMS.

Caché DBMS es un moderno entorno y sistema de gestión de bases de datos para el desarrollo rápido de aplicaciones. Este DBMS se basa en tecnología que proporciona velocidad y alto rendimiento, escalabilidad y confiabilidad. Al mismo tiempo, los requisitos de hardware del sistema siguen siendo bastante modestos.

El DBMS Caché mantiene un alto rendimiento incluso cuando se trabaja con grandes cantidades de datos y una gran cantidad de servidores en sistemas distribuidos. En este caso, se accede a los datos a través de objetos, consultas SQL de alto rendimiento y mediante el procesamiento directo de estructuras de datos multidimensionales.

Escalado vertical

El escalado vertical implica aumentar la potencia del servidor y sus capacidades asociadas con el subsistema de disco. LETOGRAF admite una arquitectura de procesador moderna, que le permite procesar grandes cantidades de datos en múltiples subprocesos. Al mismo tiempo, los datos en sí en el EDMS están organizados de tal manera que se pueden distribuir fácilmente a través del sistema de almacenamiento en diferentes discos. Este enfoque le permite distribuir uniformemente la carga en el almacenamiento de datos y minimizarla al leer datos directamente desde la base de datos, lo que significa que se puede evitar una caída en el rendimiento del sistema incluso cuando una gran cantidad de usuarios trabajan simultáneamente.

Incluso en la etapa de desarrollo de la plataforma, entendimos que el escalamiento vertical es una de las capacidades clave del sistema, cuya necesidad solo aumentará con el tiempo. Desarrollamos el sistema de tal manera que los procesos de trabajo de cada usuario se separaron en procesos del sistema separados que no se cruzan entre sí debido al hecho de que las bases de datos comparten efectivamente el acceso a la información. Al mismo tiempo, la cantidad de bloqueos de datos en LETOGRAF EDMS se minimiza y no hay cuellos de botella ni al leer ni al escribir datos.

La arquitectura de EDMS LETOGRAF le permite distribuir datos entre varios servidores físicos o virtuales. Gracias a esta distribución, cada usuario se ejecuta en un proceso aislado y los datos requeridos se almacenan en caché de manera eficiente utilizando tecnologías Caché DBMS. El tiempo de bloqueo de datos se minimiza: todas las transacciones están estructuradas de tal manera que ponen los datos en modo de acceso exclusivo sólo por un tiempo muy corto. Al mismo tiempo, incluso datos tan cargados en términos de número de accesos al disco, como registros, índices, datos de objetos, flujos, registros de acciones del usuario, se distribuyen de tal manera que la carga promedio en el subsistema permanece uniforme y no provoca retrasos. Este enfoque le permite escalar verticalmente el sistema de manera efectiva, distribuyendo la carga entre servidores o discos virtuales.

Escalado horizontal

El escalado horizontal es la distribución de sesiones de usuario entre diferentes servidores (incluso la carga de servidores de aplicaciones y la capacidad de conectar servidores de aplicaciones adicionales), así como la distribución de datos entre diferentes servidores de bases de datos, lo que garantiza un alto rendimiento del sistema sin reducir la tolerancia a fallos. Para el escalado horizontal, el sistema LETOGRAF ofrece varias posibilidades.

En primer lugar, se trata de escalamiento de carga gracias al Enterprise Cache Protocol (ECP, protocolo de caché distribuida), el protocolo utilizado en el DBMS InterSystems Caché. La ventaja de ECP es su enfoque innovador para el almacenamiento en caché de datos. Según este protocolo, los procesos de usuario que se ejecutan en servidores de aplicaciones (o clientes ECP) ​​del DBMS y atienden consultas obtienen acceso a una caché local de datos utilizados recientemente. Y sólo si estos datos no son suficientes, el cliente ECP accede a la base de datos. ECP realiza una gestión automática de la caché: los datos a los que se accede con más frecuencia se almacenan en la caché y los datos actualizados con frecuencia se replican periódicamente, lo que garantiza la integridad y corrección de los datos en todos los clientes de ECP en todo momento. En este caso, el algoritmo interno de InterSystems Caché supone que las bases de datos están sincronizadas entre el cliente ECP y el servidor ECP.

De hecho, el uso de tecnologías Caché DBMS le permite escalar fácil y rápidamente la carga entre servidores de aplicaciones, asegurando así la conexión de una gran cantidad de usuarios a un servidor de base de datos mediante el uso del protocolo ECP.

Dado que la información solicitada por un usuario en particular se puede utilizar en varios clientes ECP, es necesario bloquear los datos por un corto período de tiempo y realizar transacciones rápidamente sin realizar cálculos internos. Y lo implementamos con éxito. Esta tecnología nos permite escalar eficazmente el sistema en una situación en la que se utilizan un servidor de base de datos y varios servidores que ejecutan procesos de usuario. La característica tecnológica de Caché DBMS es que mantiene la exactitud de las transacciones dentro de un servidor ECP, independientemente de la cantidad de clientes ECP conectados a él. En el caso de que tengamos un servidor ECP y muchos clientes ECP, este problema se resuelve perfectamente, porque todas las transacciones se realizan en un servidor de base de datos.

La experiencia demuestra que incluso en sistemas muy cargados siempre es posible dividir claramente los datos entre los servidores de bases de datos en función de determinadas características. Por ejemplo, si varias organizaciones se unen en un holding, es poco probable que los usuarios de una unidad estructural necesiten alguna vez datos relacionados con otra unidad. Esto permite, a nivel de algoritmo, separar y almacenar dichos datos en diferentes servidores de bases de datos, aumentando así la posibilidad de escalado horizontal.

EDMS LETOGRAF implementa un mecanismo de fragmentación, gracias al cual nosotros, en el nivel de configuración del sistema (sin el uso de programación), hacemos posible describir las reglas y principios de distribución de los datos en diferentes servidores de bases de datos. A pesar de que, desde el punto de vista de la estructura de la base de datos, la información almacenada en cada servidor es la misma, la información en sí difiere fundamentalmente según la organización o cualquier otra característica que sea importante para una tarea en particular. Utilizando la tecnología de fragmentación, es posible lograr que en el 95-99% de los casos, los usuarios trabajen solo con su "porción de datos" y no haya necesidad de acceder a diferentes servidores de bases de datos dentro de una sesión.

Las capacidades de escalado de LETOGRAF EDMS también se ven afectadas por el hecho de que los datos se pueden procesar de manera diferente. Por ejemplo, se pueden realizar cambios en los documentos (incluso aquellos creados hace varios años), pero las entradas solo se pueden agregar al registro de actividad del usuario (no se puede eliminar ni cambiar ninguna entrada). Los mecanismos utilizados en LETOGRAF EDMS permiten aumentar aún más el rendimiento del sistema y mejorar la escala manteniendo dichos registros en servidores de bases de datos separados, tanto en el caso de configuraciones de un solo servidor como de múltiples servidores. Este enfoque tiene como objetivo reducir la carga en los servidores de bases de datos principales.

Una situación similar surge con el contenido (“contenido de información” del EDMS). Dado que el sistema LETOGRAF trabaja con un gran volumen de contenido (terabytes de datos, millones de archivos y documentos), es razonable suponer que el contenido que ingresa al sistema no debe dañarse bajo ninguna circunstancia. Por lo tanto, también trasladamos el almacenamiento de archivos a servidores de bases de datos separados y así proporcionamos un escalado horizontal adicional.

software de interfaz

LETOGRAF EDMS utiliza Apache y HAProxy como interfaz. HAProxy es responsable del equilibrio de carga entre los servidores web Apache. HAProxy, como lo ha demostrado la experiencia del sistema, se ha consolidado como la solución más efectiva que puede brindar soporte a una gran cantidad de usuarios y el control necesario sobre la tolerancia a fallas.

Cuando un usuario abre un navegador y se conecta al sistema, HAProxy lo "distribuye" a uno de los servidores de aplicaciones. Además, todas las solicitudes que provengan de este usuario se enviarán al mismo servidor de aplicaciones en el mismo proceso.

Probamos diferentes sistemas y las pruebas demostraron que HAProxy es el equilibrador de carga más eficaz, ya que garantiza una distribución uniforme de los usuarios en las ranuras libres de los servidores de aplicaciones. HAProxy tiene todos los mecanismos necesarios para monitorear el estado de cada servidor de aplicaciones y no distribuir tráfico nuevo a un servidor de aplicaciones que haya fallado por algún motivo. Además, HAProxy proporciona además una serie de capacidades en términos de almacenamiento en caché de datos estáticos (inmutables durante el trabajo del usuario), por ejemplo, estilos, iconos, etc., que le permiten organizar la interfaz.

Ejemplo de implementación de proyecto

La arquitectura LETOGRAF le permite lograr resultados significativos al reducir el tiempo de respuesta y aumentar el rendimiento del sistema. Como parte de uno de nuestros proyectos, se almacenan 23,5 TB de datos en el EDMS. De estos, 14,7 TB (63%) son flujos ("archivos adjuntos a tarjetas"), 3,5 TB (15%) son formularios de informes, como tablas de informes, que se generan en modo asíncrono y se pueden iniciar en cualquier horario, y en la solicitud del usuario y representan una tabla resumen, cualquier dato en el que se puede detallar hasta el objeto. Otros 1,6 TB (7%) son el registro de transacciones del usuario y el resto (16%) son datos e índices de la tarjeta.

En este sistema trabajan más de 11 mil usuarios, 2 mil de ellos trabajan simultáneamente, y en los días pico el número de empleados que trabajan simultáneamente en el EDMS supera los 3 mil. El número de entradas de registro ya superó los 5,5 mil millones y el número de tarjetas de registro. casi ha alcanzado los 500 millones.

En este proyecto se instala como servidor de base de datos un clúster tolerante a fallos de dos servidores físicos con tres instalaciones DBMS, así como un servidor de respaldo. Diez servidores de aplicaciones (y uno de respaldo) procesan las sesiones de los usuarios y proporcionan informes asincrónicos. 2 servidores HAProxy actúan como equilibradores. En caso de problemas con uno de los servidores, su dirección IP se transfiere automáticamente a otro servidor. También hay un servidor de indexación de archivos y un servidor de reconocimiento (que proporciona reconocimiento de texto de documentos en papel escaneados al colocar imágenes electrónicas en el sistema).

Reanudar

EDMS LETOGRAF proporciona una gran cantidad de mecanismos de escalado diferentes. Ofrecemos una especie de pastel, que se basa en un servidor (físico o virtual) en el que está instalado el sistema operativo. Encima se encuentra el DBMS InterSystems Caché, dentro del cual se encuentra el código de la plataforma. Y ya encima están las configuraciones del sistema LETOGRAF, gracias a las cuales el EDMS está completamente configurado. Y ese pastel se coloca en cada servidor. Los servidores están conectados entre sí de cierta manera debido a las configuraciones seleccionadas. Y la última capa es HAProxy, que distribuye las solicitudes de los usuarios entre servidores. Esta arquitectura nos permite soportar la escalabilidad y proporcionar todos los mecanismos de monitoreo necesarios. Como resultado, los usuarios finales reciben un EDMS de ejecución rápida y los especialistas de TI reciben un sistema unificado que es fácil de administrar y mantener, sin una gran cantidad de componentes que, en el caso de aplicaciones altamente cargadas, deben monitorearse y administrarse constantemente. . Además, dependiendo de las necesidades cambiantes de la organización, LETOGRAF EDMS se puede reconfigurar fácilmente agregando nuevos servidores o capacidades de disco.


Este material es una publicación privada de un miembro de la comunidad Club.CNews.
Los editores de CNews no son responsables de su contenido.

Imaginemos que hemos creado un sitio web. El proceso fue emocionante y fue fantástico ver aumentar el número de visitantes.

Pero en algún momento, el tráfico comienza a crecer muy lentamente, alguien publicó un enlace a su aplicación en Reddit o Hacker News, algo sucedió con el código fuente del proyecto en GitHub y, en general, todo pareció ir en su contra.

Además de eso, su servidor falló y no puede manejar la carga cada vez mayor. En lugar de adquirir nuevos clientes y/o visitantes habituales, te quedas sin nada y, además, con una página vacía.

Todos sus esfuerzos por reanudar el trabajo son en vano: incluso después de reiniciar, el servidor no puede hacer frente al flujo de visitantes. ¡Estás perdiendo tráfico!

Nadie puede prever los problemas de tráfico. Muy pocas personas se involucran en una planificación a largo plazo cuando trabajan en un proyecto potencialmente de alto rendimiento para cumplir con un plazo fijo.

¿Cómo entonces puedes evitar todos estos problemas? Para hacer esto, es necesario resolver dos problemas: optimización y escalada.

Mejoramiento

El primer paso es actualizar a la última versión de PHP (la versión actual 5.5, usa OpCache), indexar la base de datos y almacenar en caché el contenido estático (rara vez cambia páginas como Acerca de, Preguntas frecuentes, etc.).

La optimización afecta más que solo el almacenamiento en caché de recursos estáticos. También es posible instalar un servidor adicional que no sea Apache (por ejemplo, Nginx) diseñado específicamente para procesar contenido estático.

La idea es esta: colocas Nginx frente a tu servidor Apache (Ngiz será el servidor frontend y Apache el backend) y le asignas la tarea de interceptar solicitudes de recursos estáticos (es decir, *.jpg, *.png, *.mp4, *.html...) y su servicio SIN ENVIAR una solicitud a Apache.

Este esquema se llama proxy inverso (a menudo se menciona junto con la técnica de equilibrio de carga, que se describe a continuación).

Escalada

Hay dos tipos de escala: horizontal y vertical.

Decimos que un sitio es escalable cuando puede manejar una mayor carga sin necesidad de cambios de software.

Escalado vertical

Imagine que tiene un servidor web que sirve una aplicación web. Este servidor tiene las siguientes especificaciones: 4 GB de RAM, CPU i5 y disco duro de 1 TB.

Hace bien su trabajo, pero para manejar mejor el creciente tráfico, decide reemplazar los 4 GB de RAM por 16 GB, instalar una nueva CPU i7 y agregar almacenamiento híbrido PCIe SSD/HDD.

El servidor ahora se ha vuelto más potente y puede soportar cargas mayores. Esto es lo que se llama escalamiento vertical o “ escalando en profundidad"- mejoras las características del coche para hacerlo más potente.

Esto está bien ilustrado en la siguiente imagen:

Escalado horizontal

Por otro lado, tenemos la oportunidad de escalar horizontalmente. En el ejemplo anterior, es poco probable que el costo de actualizar el hardware sea menor que el costo inicial de comprar una computadora servidor.

Esto es muy costoso desde el punto de vista financiero y, a menudo, no produce el efecto que esperamos; la mayoría de los problemas de escalamiento se relacionan con la ejecución paralela de tareas.

Si la cantidad de núcleos del procesador no es suficiente para ejecutar los subprocesos disponibles, entonces no importa qué tan potente sea la CPU: el servidor seguirá funcionando lentamente y hará esperar a los visitantes.

El escalado horizontal implica la construcción de grupos de máquinas (a menudo de muy baja potencia) unidas entre sí para servir a un sitio web.

En este caso, se utiliza un equilibrador de carga: una máquina o programa que determina a qué clúster se debe enviar la siguiente solicitud entrante.

Y las máquinas del clúster comparten automáticamente la tarea entre ellas. En este caso, el rendimiento de su sitio aumenta en un orden de magnitud en comparación con el escalado vertical. Esto también se conoce como " amplitud de escala».

Hay dos tipos de balanceadores de carga: hardware y software. Se instala un equilibrador de software en una máquina normal y acepta todo el tráfico entrante y lo redirige al controlador adecuado. Por ejemplo, Nginx puede actuar como equilibrador de carga de software.

Acepta solicitudes de archivos estáticos y los entrega él mismo sin sobrecargar a Apache. Otro software de equilibrio suave popular es Squid, que uso en mi empresa. Proporciona control total sobre todos los problemas posibles a través de una interfaz muy fácil de usar.

Los equilibradores de hardware son una máquina especial independiente que realiza exclusivamente la tarea de equilibrar y en la que, por regla general, no está instalado ningún otro software. Los modelos más populares están diseñados para manejar grandes cantidades de tráfico.

Al escalar horizontalmente, sucede lo siguiente:


Tenga en cuenta que los dos métodos de escalamiento descritos no son mutuamente excluyentes: puede mejorar las características de hardware de las máquinas (también llamadas nodos) utilizadas en un sistema de clúster de escalamiento horizontal.

En este artículo nos centraremos en el escalado horizontal, ya que en la mayoría de los casos es preferible (más barato y eficiente), aunque es más difícil de implementar desde un punto de vista técnico.

Dificultades con la separación de datos.

Hay varios puntos difíciles que surgen al escalar aplicaciones PHP. El cuello de botella aquí es la base de datos (hablaremos más sobre esto en la Parte 2 de esta serie).

Además, surgen problemas con la administración de los datos de la sesión, ya que al iniciar sesión en una máquina, no estará autorizado si el equilibrador lo transfiere a otra computadora la próxima vez que lo solicite. Hay varias formas de resolver este problema: puede transferir datos locales entre máquinas o utilizar un equilibrador de carga persistente.

Balanceador de carga persistente

Un equilibrador de carga persistente recuerda dónde se procesó la solicitud anterior de un cliente en particular y, en la siguiente solicitud, envía la solicitud allí.

Por ejemplo, si visité nuestro sitio e inicié sesión allí, el equilibrador de carga me redirigirá, digamos, al Servidor1, me recordará allí y la próxima vez que haga clic, seré redirigido nuevamente al Servidor1. Todo esto sucede de forma completamente transparente para mí.

Pero ¿qué pasa si el Servidor1 falla? Naturalmente, todos los datos de la sesión se perderán y tendré que iniciar sesión nuevamente en un nuevo servidor. Esto resulta muy desagradable para el usuario. Además, esto supone una carga adicional para el equilibrador de carga: no sólo necesitará redirigir a miles de personas a otros servidores, sino también recordar dónde las redirigió.

Esto se convierte en otro cuello de botella. ¿Qué pasa si el único equilibrador de carga falla y se pierde toda la información sobre la ubicación de los clientes en los servidores? ¿Quién gestionará el equilibrio? Es una situación complicada, ¿no?

Intercambio de datos locales

Compartir datos de sesión dentro de un clúster definitivamente parece una buena solución, pero requiere cambios en la arquitectura de la aplicación, aunque vale la pena porque el cuello de botella se vuelve amplio. El fallo de un servidor deja de tener un efecto fatal en todo el sistema.

Se sabe que los datos de la sesión se almacenan en la matriz PHP súper global $_SESSION. Además, no es ningún secreto que esta matriz $_SESSION está almacenada en el disco duro.

En consecuencia, dado que el disco pertenece a una u otra máquina, otras no tienen acceso a él. Entonces, ¿cómo se puede organizar el acceso compartido para varias computadoras?

Tenga en cuenta que los controladores de sesión en PHP se pueden anular; puede definir su propia clase/función para administrar las sesiones.

Usando la base de datos

Al utilizar nuestro propio controlador de sesión, podemos estar seguros de que toda la información de la sesión se almacena en la base de datos. La base de datos debe estar en un servidor independiente (o en su propio clúster). En este caso, los servidores cargados uniformemente solo procesarán la lógica empresarial.

Si bien este enfoque funciona bastante bien, si hay mucho tráfico, la base de datos no solo se vuelve vulnerable (si la pierdes, lo pierdes todo), sino que estará sujeta a mucho acceso debido a la necesidad de escribir y leer sesiones. datos.

Esto se convierte en otro cuello de botella en nuestro sistema. En este caso, puede aplicar escalado de amplitud, lo cual es problemático cuando se utilizan bases de datos tradicionales como MySQL, Postgre y similares (este problema se tratará en la segunda parte de la serie).

Usando un sistema de archivos compartido

Puede configurar un sistema de archivos de red al que todos los servidores accederán y trabajarán con los datos de la sesión. No deberías hacer eso. Este es un enfoque completamente ineficaz, con una alta probabilidad de pérdida de datos y todo funciona muy lentamente.

Este es otro peligro potencial, incluso más peligroso que el caso de la base de datos descrito anteriormente. Activar el sistema de archivos compartido es muy simple: cambie el valor de session.save_path en el archivo php.ini, pero se recomienda encarecidamente utilizar otro método.

Si aún desea implementar la opción del sistema de archivos compartido, existe una solución mucho mejor: GlusterFS.

Memcached

Puede utilizar memcached para almacenar datos de sesión en la RAM. Este es un método muy inseguro, ya que los datos de la sesión se sobrescribirán tan pronto como se agote el espacio libre en el disco.

No hay persistencia: los datos de inicio de sesión se almacenarán mientras el servidor Memcached esté en ejecución y haya espacio libre para almacenar estos datos.

Quizás se pregunte: ¿no es la RAM específica de cada máquina? ¿Cómo aplicar este método a un clúster? Memcached tiene la capacidad de combinar prácticamente toda la RAM disponible de varias máquinas en un único almacenamiento:

Cuantas más máquinas tenga, mayor será el tamaño del almacenamiento compartido creado. No es necesario que asigne memoria manualmente dentro del almacenamiento, pero puede controlar el proceso especificando cuánta memoria se puede asignar desde cada máquina para crear un espacio compartido.

De este modo, la cantidad de memoria necesaria queda a disposición de los ordenadores para sus propias necesidades. El resto se utiliza para almacenar datos de sesión para todo el clúster.

Además de las sesiones, el caché también puede contener cualquier otro dato que desees, lo principal es que haya suficiente espacio libre. Memcached es una solución excelente que se ha utilizado ampliamente.

Usar este método en aplicaciones PHP es muy fácil: sólo necesitas cambiar el valor en el archivo php.ini:

session.save_handler = memcache session.save_path = "tcp://path.to.memcached.server:puerto"

Clúster de Redis

Redis es un almacén de datos en memoria que no es SQL, como Memcached, pero es persistente y admite tipos de datos más complejos que solo cadenas de matrices PHP en forma de pares “clave => valor”.

Esta solución no admite clústeres, por lo que implementarla en un sistema de escalamiento horizontal no es tan simple como podría parecer a primera vista, pero es bastante factible. De hecho, la versión alfa de la versión del clúster ya está disponible y puedes usarla.

En comparación con soluciones como Memcached, Redis es un cruce entre una base de datos normal y Memcached.

Escalado vertical— ampliación: aumento del número de recursos disponibles para el software mediante el aumento de la potencia utilizada por los servidores.

— ampliación horizontal: aumentar el número de nodos combinados en un clúster de servidores cuando falta CPU, memoria o espacio en disco.

Ambas son soluciones de infraestructura que se requieren en diferentes situaciones cuando un proyecto web crece.

Escalado vertical y horizontal, escalado para web.

Por ejemplo, considere los servidores de bases de datos. Para aplicaciones grandes, este es siempre el componente más cargado del sistema.

Las capacidades de escalado de los servidores de bases de datos están determinadas por las soluciones de software utilizadas: la mayoría de las veces se trata de bases de datos relacionales (MySQL, Postgresql) o No SQL(, Casandra, etc.).

El escalado horizontal para servidores de bases de datos bajo cargas pesadas es mucho más económico

Un proyecto web normalmente se inicia en un servidor, cuyos recursos se agotan a medida que crece. En tal situación, hay 2 opciones:

  • mover el sitio a un servidor más potente
  • agregue otro servidor de bajo consumo y combine máquinas en un clúster

MySQL es el RDBMS más popular y, como cualquiera de ellos, requiere muchos recursos del servidor para ejecutarse bajo carga. La ampliación es posible principalmente hacia arriba. Hay fragmentación (que requiere cambios de código para configurar) y fragmentación, que puede ser difícil de soportar.

Escalado vertical

NoSQL se escala fácilmente y la segunda opción con, por ejemplo, MongoDB será mucho más rentable financieramente y no requerirá configuraciones ni soporte de mano de obra intensiva para la solución resultante. La fragmentación se realiza automáticamente.

Así, con MySQL necesitarás un servidor con una gran cantidad de CPU y RAM; dichos servidores tienen un coste importante;

Escalado horizontal
Con MongoDB puedes agregar otro servidor mediano y la solución resultante funcionará de manera estable, brindando tolerancia adicional a fallas.


Ampliación horizontal o es una etapa natural del desarrollo de infraestructura. Cualquier servidor tiene limitaciones, y cuando se alcanzan o cuando el coste de un servidor más potente resulta excesivamente alto, se añaden nuevas máquinas. La carga se distribuye entre ellos. También proporciona tolerancia a fallos.

Debe comenzar a agregar servidores de tamaño mediano y configurar clústeres cuando se hayan agotado las posibilidades de aumentar los recursos de una máquina o cuando la compra de un servidor más potente no sea rentable.

El ejemplo dado con bases de datos relacionales y NoSQL es una situación que ocurre con mayor frecuencia. Los servidores frontend y backend también son escalables.

Leer sobre el equilibrador

A finales de 2012, más del 50% de las aplicaciones que se ejecutaban en la plataforma x86 estaban virtualizadas. Sin embargo, sólo el 20% de las aplicaciones críticas para el negocio están virtualizadas.

¿Será porque los departamentos de TI no confían en las plataformas de virtualización? ¿Sienten que las plataformas de virtualización no son lo suficientemente estables para soportar aplicaciones de misión crítica?

Durante los últimos 10 años, VMware ha demostrado que la virtualización es una realidad y, de hecho, las aplicaciones virtualizadas suelen ser más estables cuando se ejecutan en una infraestructura administrada por VMware.

Entonces, si la confianza o la estabilidad no son un problema, ¿cuál es la razón por la cual los departamentos de TI aún no han virtualizado las aplicaciones restantes?

Ampliar
Escalamiento horizontal o escalamiento horizontal: agregar nuevos recursos a la infraestructura, por ejemplo, servidores en un clúster.

A medida que los precios siguen bajando y el rendimiento sigue aumentando, los servidores básicos y económicos son una solución ideal para el escalamiento horizontal y pueden ensamblarse en grandes clústeres para agrupar recursos informáticos.

Durante los últimos siete años, los arquitectos de infraestructura de VMware han estado orando por el escalamiento horizontal. Algunos pueden argumentar a favor de utilizar este enfoque en particular, pero también tiene sus propios matices y todo depende de los requisitos del negocio. La ventaja del escalado horizontal es que los servidores básicos son baratos y, si el servidor falla, afecta a una pequeña cantidad de máquinas virtuales. La desventaja son los mayores costos de las licencias de vSphere, los grandes requisitos de espacio del centro de datos y, por lo general, estos servidores básicos no tienen grandes recursos informáticos.

Aumentar proporcionalmente
El escalado vertical consiste en agregar recursos informáticos a un servidor ya utilizado. Normalmente se trata de procesadores o RAM.

Por lo general, estos servidores son bastante potentes y admiten 4 procesadores y 512 GB de memoria. Además, hay sistemas con 8 procesadores y 1 TB de memoria, y algunos tienen la suerte de ver incluso servidores de 16 procesadores con 4 TB de memoria. Y no, estos no son mainframes ni nada por el estilo, son servidores basados ​​en la arquitectura clásica x86.

La transición a la segunda ola de virtualización, que proporciona la flexibilidad que esta tecnología proporciona para aplicaciones críticas para el negocio, está ejerciendo una enorme presión sobre las infraestructuras de VMware que se utilizan hoy en día debido a los siguientes problemas:

  • Capacidades de escalamiento insuficientes. Las cargas de trabajo con uso intensivo de computación son un desafío debido a la cantidad limitada de recursos disponibles con servidores básicos de bajo costo.
  • Fiabilidad insuficiente. Los equipos básicos o el hardware que utilizan dichos componentes pueden ser menos confiables. El problema de confiabilidad se puede resolver usando funciones que discutiré en los siguientes artículos.
  • Aumento de la complejidad de la gestión y aumento de los costes operativos. Es más fácil administrar 100 servidores, no 1000 y, como resultado, 10 servidores son más fáciles de administrar que 100. Lo mismo se aplica a los costos operativos: 10 servidores son mucho más baratos de mantener que 100.
El escalado vertical es excelente para aplicaciones críticas para el negocio con sus enormes requisitos de recursos. ¡Hola Monster VM! Todas estas bases de datos críticas que consumen mucha energía, enormes sistemas ERP, sistemas de análisis de big data, aplicaciones JAVA, etc., se beneficiarán directamente del escalamiento vertical.

Con el lanzamiento de vSphere 5, la cantidad de recursos disponibles para una VM se ha multiplicado por 4.

Y con el lanzamiento de vSphere 5.1, las monstruosas máquinas virtuales pueden volverse aún más monstruosas.

Para que vSphere 5.1 pueda iniciar una máquina virtual monstruosa, el programador debe tener y programar subprocesos para que se ejecuten en 64 procesadores físicos. No hay muchos servidores que puedan admitir tantos núcleos, y hay incluso menos servidores que admitan 16 sockets y 160 núcleos.

Hay dos tipos de escalado vertical de servidor: sin pegamento y con pegamento. Estas palabras se traducen al ruso de la siguiente manera: sin integrar tecnologías y con integración de tecnologías, respectivamente.

Arquitectura sin pegamento
Esta arquitectura fue desarrollada por Intel y presentada en el Intel Xeon E7.

Se utiliza un bus QPI especialmente diseñado para la comunicación entre dispositivos de E/S, interfaces de red y procesadores.

En servidores con 4 procesadores, todos están conectados directamente entre sí a través de este bus. El procesador Glueless utiliza uno de los canales para conectar el procesador a las interfaces de E/S y los otros tres para conectarse a los procesadores vecinos.

En un servidor de 8 procesadores, cada procesador está conectado directamente a tres vecinos y, a través de otro procesador, a los otros cuatro.

Las ventajas de esta arquitectura:

  • No es necesario ningún desarrollo o especialización especial por parte del fabricante del servidor.
  • Cualquier fabricante de servidores puede producir servidores de 8 procesadores.
  • Se reduce el coste de los servidores tanto de 4 como de 8 procesadores
Defectos:
  • El costo total de propiedad aumenta a medida que se escala
  • Arquitectura limitada a 8 servidores de procesador.
  • Es difícil mantener la integridad de la caché a medida que aumentan los sockets
  • Crecimiento de la productividad no lineal
  • La relación precio-rendimiento está cayendo
  • Rendimiento subóptimo al utilizar máquinas virtuales grandes
  • Hasta el 65% del ancho de banda del bus se gasta en transmisiones conversacionales del protocolo QPI
¿Cuál es el motivo de la charlatanería del protocolo QPI? Para lograr la integridad de la caché del procesador, cada operación de lectura debe replicarse en todos los procesadores. Esto se puede comparar con un paquete de difusión en una red IP. Cada procesador debe verificar la línea de memoria solicitada y, si se utiliza la última versión de los datos, proporcionarla. Si los datos actuales están en otra caché, el protocolo QPI copia esta línea de memoria de la caché remota con demoras mínimas. Por lo tanto, replicar cada operación de lectura desperdicia ancho de banda del bus y ciclos de caché que podrían usarse para transferir datos útiles.

Las principales aplicaciones cuyo rendimiento se ve afectado por las deficiencias del protocolo QPI son las aplicaciones Java, las bases de datos de gran tamaño y las aplicaciones sensibles a la latencia.

El resultado del escalado vertical debe ser que no haya cuellos de botella; de lo contrario, la arquitectura perderá sentido. Por tanto, la linealidad de los aumentos de productividad debe corresponder a la linealidad de las adiciones de recursos.

Arquitectura pegada
Para resolver los problemas descritos anteriormente, los desarrolladores de hardware desarrollaron una arquitectura pegada. Esta arquitectura utiliza un controlador de nodo externo para organizar la interconexión de islas QPI - clústeres de procesadores.


Intel QPI ofrece una solución escalable especial: controladores de nodos externos (o XNC), cuya implementación práctica está siendo desarrollada por empresas OEM de terceros. El controlador de nodo externo, utilizado a partir del Intel Xeon E7-4800, con un controlador de memoria incorporado, también incluye el sistema Cache Coherent Non-Uniform Memory Access (ccNUMA), cuya tarea es monitorear la relevancia de los datos. en cada línea de la memoria caché del procesador.

Las latencias entre el procesador y la memoria en ccNUMA dependen de la ubicación de los dos componentes entre sí, lo que hace que los controladores XNC se conviertan en un componente crítico del servidor, y muy pocos fabricantes de servidores pueden diseñar servidores que se puedan ampliar.




Arriba