banner
Centro de Noticias
Nuestras ofertas son apreciadas tanto a nivel nacional como internacional.

Descarga de memoria transparente: más memoria a una fracción del coste y la potencia

Mar 05, 2024

Estamos siendo testigos de un crecimiento masivo en las necesidades de memoria de las aplicaciones emergentes, como el aprendizaje automático, junto con la desaceleración del escalamiento de los dispositivos DRAM y grandes fluctuaciones en el costo de la DRAM. Esto ha hecho que la DRAM sea prohibitivamente costosa como única solución de capacidad de memoria a la escala de Meta.

Pero las tecnologías alternativas, como las unidades de estado sólido (SSD) conectadas a NVMe, ofrecen mayor capacidad que la DRAM a una fracción del costo y la energía. Descargar de forma transparente la memoria más fría a tecnologías de memoria más baratas a través de técnicas de kernel o hipervisor ofrece un enfoque prometedor para frenar el apetito por la DRAM. Sin embargo, el desafío clave implica desarrollar una solución sólida a escala de centro de datos. Una solución de este tipo debe poder hacer frente a diversas cargas de trabajo y la gran variación de rendimiento de diferentes dispositivos de descarga, como memoria comprimida, SSD y NVM.

La descarga de memoria transparente (TMO) es la solución de Meta para entornos de centros de datos heterogéneos. Introduce un nuevo mecanismo del kernel de Linux que mide el trabajo perdido debido a la escasez de recursos en CPU, memoria y E/S en tiempo real. Guiado por esta información y sin ningún conocimiento previo de la aplicación, TMO ajusta automáticamente la cantidad de memoria a descargar en un dispositivo heterogéneo, como una memoria comprimida o un SSD. Lo hace según las características de rendimiento del dispositivo y la sensibilidad de la aplicación a accesos más lentos a la memoria. TMO identifica de manera integral oportunidades de descarga no solo de los contenedores de aplicaciones sino también de los contenedores sidecar que brindan funciones a nivel de infraestructura.

TMO ha estado funcionando en producción durante más de un año y ha ahorrado entre un 20 y un 32 por ciento de la memoria total en millones de servidores de nuestra amplia flota de centros de datos. Hemos incorporado con éxito los componentes del sistema operativo de TMO al kernel de Linux.

En los últimos años, se han implementado con éxito en nuestros centros de datos una gran cantidad de tecnologías de memoria no DRAM más baratas, como las SSD NVMe, o están en camino. Además, las tecnologías emergentes de bus de memoria que no son DDR, como Compute Express Link (CXL), proporcionan una semántica de acceso similar a la memoria y un rendimiento cercano al DDR. La jerarquía de almacenamiento de memoria que se muestra en la Figura 1 ilustra cómo se comparan varias tecnologías entre sí. La confluencia de estas tendencias ofrece nuevas oportunidades para clasificar la memoria en niveles que eran imposibles en el pasado.

Con la organización de la memoria en niveles, los datos a los que se accede con menos frecuencia se migran a una memoria más lenta. La aplicación en sí, una biblioteca de espacio de usuario, el kernel o el hipervisor pueden impulsar el proceso de migración. Nuestro trabajo de TMO se centra en la migración o intercambio impulsado por el kernel. ¿Por qué? Porque se puede aplicar de forma transparente a muchas aplicaciones sin necesidad de modificar la aplicación. A pesar de su simplicidad conceptual, el intercambio impulsado por el kernel para aplicaciones de centros de datos sensibles a la latencia es un desafío a hiperescala. Creamos TMO, una solución transparente de descarga de memoria para entornos en contenedores.

TMO consta de los siguientes componentes:

El creciente costo de la DRAM como fracción del costo del servidor motivó nuestro trabajo en TMO. La Figura 2 muestra el costo relativo de DRAM, memoria comprimida y almacenamiento SSD. Estimamos el costo de la DRAM comprimida en función de una relación de compresión 3x representativa del promedio de nuestras cargas de trabajo de producción. Esperamos que el costo de la DRAM crezca, alcanzando el 33 por ciento de nuestro gasto en infraestructura. Si bien no se muestra a continuación, el consumo de energía de DRAM sigue una tendencia similar, que esperamos alcance el 38 por ciento de la energía de nuestra infraestructura de servidores. Esto hace que la DRAM comprimida sea una buena opción para descargar memoria.

Además de la DRAM comprimida, también equipamos todos nuestros servidores de producción con SSD NVMe de gran capacidad. A nivel de sistema, los SSD NVMe contribuyen a menos del 3 por ciento del costo del servidor (aproximadamente 3 veces menos que la memoria comprimida en nuestra generación actual de servidores). Además, la Figura 2 muestra que, con isocapacidad respecto a DRAM, SSD permanece por debajo del 1 por ciento del costo del servidor a lo largo de generaciones, ¡aproximadamente 10 veces menos que la memoria comprimida en costo por byte! Estas tendencias hacen que las SSD NVMe sean mucho más rentables en comparación con la memoria comprimida.

Si bien son más baratas que la DRAM, la memoria comprimida y las SSD NVMe tienen peores características de rendimiento. Afortunadamente, los patrones típicos de acceso a la memoria funcionan a nuestro favor y brindan oportunidades sustanciales para descargar a medios más lentos. La Figura 3 muestra la memoria de la aplicación "fría": el porcentaje de páginas a las que no se accedió en los últimos cinco minutos. Dicha memoria se puede descargar en memoria comprimida o SSD sin afectar el rendimiento de la aplicación. En general, la memoria fría representa en promedio alrededor del 35 por ciento de la memoria total de nuestra flota. Sin embargo, varía enormemente según las aplicaciones, oscilando entre el 19 y el 62 por ciento. Esto resalta la importancia de un método de descarga que sea sólido frente al comportamiento diverso de las aplicaciones.

Además de la frecuencia de acceso, una solución de descarga debe tener en cuenta qué tipo de memoria descargar. La memoria a la que acceden las aplicaciones consta de dos categorías principales: anónima y respaldada por archivos. Las aplicaciones asignan directamente la memoria anónima en forma de páginas de montón o pila. La memoria caché de páginas del kernel asigna memoria respaldada por archivos para almacenar datos del sistema de archivos utilizados con frecuencia en nombre de la aplicación. Nuestras cargas de trabajo demuestran una variedad de combinaciones de archivos y anónimas. Algunas cargas de trabajo utilizan casi exclusivamente memoria anónima. La huella de otros está dominada por el caché de la página. Esto requiere que nuestra solución de descarga funcione igualmente bien para páginas anónimas y de archivos.

TMO comprende múltiples piezas en el espacio de usuario y el kernel. Un agente de espacio de usuario llamado Senpai reside en el centro de la operación de descarga. En un bucle de control alrededor de la presión de memoria observada, activa el algoritmo de recuperación del kernel para identificar las páginas de memoria menos utilizadas y moverlas al backend de descarga. Un componente del kernel llamado PSI (Pressure Stall Information) cuantifica e informa la presión de la memoria. El algoritmo de recuperación se dirige hacia aplicaciones específicas a través del controlador de memoria cgroup2 del kernel.

PSI

Históricamente, los administradores de sistemas han utilizado métricas como las tasas de error de página para determinar el estado de la memoria de una carga de trabajo. Sin embargo, esto presenta limitaciones. Por un lado, las tasas de fallas pueden elevarse cuando las cargas de trabajo comienzan en un caché frío o cuando los conjuntos de trabajo cambian. En segundo lugar, el impacto que tiene una determinada tasa de fallas en la carga de trabajo depende en gran medida de la velocidad del back-end de almacenamiento. Lo que podría constituir una desaceleración significativa en un disco duro rotativo podría no ser un evento en una unidad flash decente.

PSI define la presión de la memoria de manera que capture el verdadero impacto que tiene una escasez de memoria en la carga de trabajo. Para lograr esto, rastrea los estados de las tareas que ocurren específicamente debido a la falta de memoria; por ejemplo, un hilo que se detiene debido a una falla de una página reclamada recientemente, o un hilo que tiene que ingresar a la recuperación para satisfacer una solicitud de asignación. Luego, PSI agrega el estado de todos los hilos dentro del contenedor y a nivel del sistema en dos indicadores de presión: algo y lleno. Algunos representan la condición en la que uno o más subprocesos se detiene. Completo representa la condición en la que todos los subprocesos que no están inactivos se detienen simultáneamente y ningún subproceso puede trabajar activamente para lograr lo que la aplicación realmente se esfuerza por lograr. Finalmente, PSI mide el tiempo que los contenedores y el sistema pasan en estos estados agregados y lo reporta como un porcentaje del tiempo del reloj de pared.

Por ejemplo, si se informa que la métrica completa de un contenedor es del 1 por ciento en una ventana de 10 segundos, significa que para una suma total de 100 ms durante ese período, la falta de memoria en el contenedor generó una fase improductiva simultánea para todos los hilos inactivos. Consideramos irrelevante la tasa de los eventos subyacentes. Esto podría ser el resultado de errores de 10 páginas en un disco duro giratorio o de 10.000 errores en un SSD.

Senpai se sitúa en la cima de las métricas de PSI. Utiliza la presión como retroalimentación para determinar con qué agresividad impulsar la recuperación de memoria del núcleo. Si el contenedor mide por debajo de un umbral de presión determinado, Senpai aumentará la tasa de recuperación. Si la presión cae por debajo, Senpai disminuirá. El umbral de presión se calibra de manera que la sobrecarga de paginación no afecte funcionalmente el rendimiento de la carga de trabajo.

Senpai activa el algoritmo de recuperación del kernel utilizando la interfaz del controlador de memoria cgroup2. Según la desviación del objetivo de presión, Senpai determina una cantidad de páginas para recuperar y luego le indica al núcleo que lo haga:

recuperación = current_mem * recuperación_ratio * max(0,1 – psi_some/psi_threshold)

Esto ocurre cada seis segundos, lo que da tiempo para que la actividad de recuperación se traduzca en presión de carga de trabajo en forma de fallas en el futuro.

Inicialmente, Senpai utilizó el archivo de control de límite de memoria cgroup2 para impulsar la recuperación. Calcularía el paso de reclamación y luego reduciría el límite vigente en esta cantidad. Sin embargo, esto generó varios problemas en la práctica. Por un lado, si el agente Senpai fallara, dejaría una restricción potencialmente devastadora en la carga de trabajo, lo que resultaría en una presión extrema e incluso muertes de OOM. Incluso sin fallar, Senpai a menudo era incapaz de aumentar el límite lo suficientemente rápido en una carga de trabajo en rápida expansión. Esto provocó picos de presión significativamente superiores a las tolerancias de la carga de trabajo. Para solucionar estos problemas, agregamos un archivo de control stateless memory.reclaim cgroup al kernel. Esta perilla permite a Senpai pedirle al kernel que recupere exactamente la cantidad de memoria calculada sin aplicar ningún límite, evitando así el riesgo de bloquear cargas de trabajo en expansión.

TMO tiene como objetivo descargar la memoria a niveles de presión tan bajos que no afecten la carga de trabajo. Sin embargo, aunque Linux felizmente desaloja el caché del sistema de archivos bajo presión, nos resultó reacio a mover la memoria anónima a un dispositivo de intercambio. Incluso cuando existen páginas de almacenamiento dinámico conocidas y la caché de archivos supera activamente los umbrales de presión de TMO, el espacio de intercambio configurado permanecería frustrantemente inactivo.

¿La razón de este comportamiento? El kernel evolucionó durante un período en el que el almacenamiento estaba formado por discos duros con ejes giratorios. La sobrecarga de búsqueda de estos dispositivos da como resultado un rendimiento bastante pobre cuando se trata de patrones de E/S semialeatorios producidos por el intercambio (y la paginación en general). Con el paso de los años, el tamaño de la memoria no hizo más que crecer. Al mismo tiempo, las tasas de IOP/s de disco permanecieron estancadas. Los intentos de localizar una parte importante de la carga de trabajo parecían cada vez más inútiles. Un sistema que intercambia activamente se ha asociado ampliamente con latencias y perturbaciones intolerables. Con el tiempo, Linux recurrió en su mayor parte al intercambio sólo cuando los niveles de presión se acercaban a condiciones de falta de memoria (OOM).

Sin embargo, la capacidad de IOP de las unidades flash contemporáneas (incluso las baratas) es un orden de magnitud mejor que la de los discos duros. Mientras que incluso los discos duros de alta gama operan en el rango de unos escasos cien IOP/s, las unidades flash básicas pueden manejar fácilmente cientos de miles de IOP/s. En esas unidades, paginar unos cuantos gigabytes de un lado a otro no es gran cosa.

TMO presenta un nuevo algoritmo de intercambio que aprovecha estas unidades sin hacer una regresión a las configuraciones heredadas que aún cuentan con medios rotativos. Logramos esto rastreando la tasa de fallas de caché del sistema de archivos en el sistema y realizando el intercambio en proporción directa. Eso significa que por cada página de archivo que debe leerse repetidamente desde el sistema de archivos, el kernel intenta intercambiar una página anónima. Al hacerlo, se deja espacio para la página de paliza. En caso de que se produzcan intercambios, la recuperación vuelve a colocar el caché del archivo.

Este circuito de retroalimentación encuentra un equilibrio que expulsa el recuerdo más frío general entre los dos grupos. Esto sirve a la carga de trabajo con la cantidad mínima de E/S de paginación agregada. Debido a que sólo cambia un tipo de actividad de paginación por otro, nunca funciona peor que el algoritmo anterior. En la práctica, comienza a realizar intercambio ante los primeros signos de problemas en la caché de archivos, utilizando así de manera efectiva el espacio de intercambio disponible en los niveles de presión subliminal de TMO.

TMO ha estado funcionando en producción durante más de un año y ha aportado importantes ahorros en el uso de memoria a la flota de Meta. Dividimos los ahorros de memoria de TMO en ahorros de aplicaciones, impuesto a la memoria del centro de datos e impuesto a la memoria de aplicaciones, respectivamente.

Ahorros de aplicaciones: la Figura 6 muestra los ahorros relativos de memoria logrados por TMO para ocho aplicaciones representativas que utilizan diferentes backends de descarga, ya sea memoria comprimida o SSD. Utilizando un back-end de memoria comprimida, TMO ahorra entre un 7 y un 12 por ciento de los gastos de los residentes.

memoria en cinco aplicaciones. Los datos de múltiples aplicaciones tienen poca compresibilidad, por lo que descargarlos a un SSD resulta mucho más efectivo. Específicamente, los modelos de aprendizaje automático utilizados para la predicción de anuncios suelen utilizar valores codificados en bytes cuantificados que exhiben una relación de compresión de 1,3 a 1,4 veces. Para esas aplicaciones, la Figura 8 muestra que la descarga a un SSD logra ahorros del 10 al 19 por ciento. En general, en back-ends de memoria comprimida y SSD, TMO logra ahorros significativos del 7 al 19 por ciento de la memoria total sin una degradación notable del rendimiento de las aplicaciones.

Ahorro en impuestos sobre la memoria de aplicaciones y centros de datos: TMO apunta además a la sobrecarga de memoria impuesta por los servicios de administración de aplicaciones y centros de datos que se ejecutan en cada host además de la carga de trabajo principal. A esto lo llamamos el impuesto a la memoria. La Figura 7 muestra los ahorros relativos al descargar este tipo de memoria en toda la flota de Meta. En lo que respecta al impuesto al centro de datos, TMO ahorra una media del 9 por ciento de la memoria total de un servidor. Los ahorros en impuestos de aplicación representan el 4 por ciento. En general, TMO logra un promedio del 13 por ciento de ahorro en impuestos sobre la memoria. Esto se suma al ahorro de carga de trabajo y representa una cantidad significativa de memoria a la escala de la flota de Meta.

Actualmente, elegimos manualmente el back-end de descarga entre la memoria comprimida y el intercambio respaldado por SSD dependiendo de la compresibilidad de la memoria de la aplicación, así como de su sensibilidad a la desaceleración del acceso a la memoria. Aunque podríamos desarrollar herramientas para automatizar el proceso, una solución más fundamental implica que el kernel administre una jerarquía de backends de descarga (por ejemplo, usar automáticamente zswap para páginas más cálidas y SSD para páginas más frías o menos comprimibles, así como plegar dispositivos NVM y CXL). en la jerarquía de la memoria en el futuro). El algoritmo de recuperación del kernel debería equilibrarse dinámicamente entre estos grupos de memoria. Estamos trabajando activamente en esta arquitectura.

Con las próximas tecnologías de bus como CXL, que proporcionan una semántica de acceso similar a la memoria, la descarga de memoria puede ayudar a descargar no sólo la memoria fría sino también la memoria caliente. Nos estamos centrando activamente en esa arquitectura para utilizar dispositivos CXL como back-end de descarga de memoria.