¿Por qué mi NVMe es más lento que un SSD?

¿Por qué mi NVMe es más lento que un SSD?
En este artículo, analizaremos algunos aspectos del subsistema de entrada y salida y su impacto en el rendimiento.

Hace un par de semanas me encontré con la pregunta de por qué el NVMe en un servidor era más lento que el SATA en otro. Revisé las especificaciones de los servidores y entendí que era una pregunta engañosa: el NVMe era del segmento del consumidor, mientras que el SSD era del segmento empresarial.

Es evidente que comparar productos de diferentes segmentos en entornos distintos no es apropiado, pero esto no es una respuesta técnica exhaustiva. Estudiaremos los fundamentos, realizaremos experimentos y daremos respuesta a la pregunta planteada.

¿Qué es fsync y dónde se utiliza?

Para acelerar el trabajo con los dispositivos de almacenamiento, los datos se almacenan en un búfer, es decir, se guardan en memoria volátil hasta que se presenta una oportunidad adecuada para escribir el contenido del búfer en el dispositivo. Los criterios para definir una 'oportunidad adecuada' son determinados por el sistema operativo y las características del dispositivo. En caso de fallos de energía, todos los datos en el búfer se perderán.

Existen varias tareas en las que es necesario asegurarse de que los cambios en un archivo se hayan escrito en el dispositivo y no estén solo en un búfer intermedio. Esta certeza se puede obtener utilizando la llamada del sistema compatible con POSIX, fsync. La llamada a fsync inicia una escritura forzada del búfer en el dispositivo.

Demostraremos el impacto de los búferes con un ejemplo artificial en forma de un breve programa en C.

#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(void) {
    /* Открываем файл answer.txt на запись, если его нет -- создаём */
    int fd = open("answer.txt", O_WRONLY | O_CREAT);
    /* Записываем первый набор данных */
    write(fd, "Answer to the Ultimate Question of Life, The Universe, and Everything: ", 71);
    /* Делаем вид, что проводим вычисления в течение 10 секунд */
    sleep(10);
    /* Записываем результат вычислений */
    write(fd, "42n", 3); 

    return 0;
}

Los comentarios explican bien la secuencia de acciones en el programa. El texto 'la respuesta a la pregunta fundamental de la vida, el universo y todo lo demás' se almacenará en búfer por el sistema operativo, y si reinicias el servidor presionando el botón de Reinicio durante los 'cálculos', el archivo quedará vacío. En nuestro ejemplo, la pérdida de texto no es un problema, por lo que fsync no es necesario. Las bases de datos no comparten ese optimismo.

Las bases de datos son programas complejos que trabajan simultáneamente con muchos archivos, por lo que necesitan estar seguros de que los datos que escriben se guardarán en el dispositivo, ya que esto afecta la consistencia de los datos dentro de la base de datos. Las bases de datos están diseñadas para registrar todas las transacciones completadas y estar preparadas para un corte de energía en cualquier momento. Este comportamiento obliga a usar fsync de manera constante en grandes cantidades.

¿A qué afecta el uso frecuente de fsync?

En las operaciones de entrada/salida normales, el sistema operativo intenta optimizar la comunicación con los discos, ya que en la jerarquía de memoria, los almacenamiento externos son los más lentos. Por lo tanto, el sistema operativo intenta escribir la mayor cantidad de datos posible en una sola operación de acceso al almacenamiento.

Demostraremos el efecto del uso de fsync con un ejemplo concreto. Los discos de estado sólido que utilizaremos son los siguientes:

  • Intel® DC SSD S4500 de 480 GB, conectado por SATA 3.2, 6 Gb/s;
  • Samsung 970 EVO Plus de 500GB, conectado por PCIe 3.0 x4, ~31 Gb/s.

Las pruebas se realizan en un Intel® Xeon® W-2255 bajo el sistema operativo Ubuntu 20.04. Para probar los discos, se utiliza sysbench 1.0.18. Se ha creado una partición en los discos, formateada como ext4. La preparación para la prueba consiste en crear archivos de 100 GB:

sysbench --test=fileio --file-total-size=100G prepare

Inicio de las pruebas:

# Без fsync
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=0 run

# С fsync после каждой записи
sysbench --num-threads=16 --test=fileio --file-test-mode=rndrw --file-fsync-freq=1 run

Los resultados de las pruebas se presentan en la tabla.

Prueba
Intel® S4500
Samsung 970 EVO+

Lectura sin fsync, MiB/s
5734.89
9028.86

Escritura sin fsync, MiB/s
3823.26
6019.24

Lectura con fsync, MiB/s
37.76
3.27

Escritura con fsync, MiB/s
25.17
2.18

No es difícil notar que el NVMe del segmento de consumidores lidera con confianza cuando el sistema operativo decide cómo trabajar con los discos, y pierde cuando se utiliza fsync. De aquí surgen dos preguntas:

  1. ¿Por qué en la prueba sin fsync la velocidad de lectura excede la capacidad física del canal?
  2. ¿Por qué los SSD del segmento de servidores manejan mejor un gran número de solicitudes de fsync?

La respuesta a la primera pregunta es simple: sysbench genera archivos llenos de ceros. Por lo tanto, se realizó una prueba con 100 gigabytes de ceros. Dado que los datos son muy uniformes y predecibles, intervienen varias optimizaciones del sistema operativo, lo que acelera significativamente la ejecución.

Si se cuestionan todos los resultados de sysbench, se puede utilizar fio.

# Без fsync
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=0 --filename=/dev/sdb

# С fsync после каждой записи
fio --name=test1 --blocksize=16k --rw=randrw --iodepth=16 --runtime=60 --rwmixread=60 --fsync=1 --filename=/dev/sdb

Prueba
Intel® S4500
Samsung 970 EVO+

Lectura sin fsync, MiB/s
45.5
178

Escritura sin fsync, MiB/s
30.4
119

Lectura con fsync, MiB/s
32.6
20.9

Escritura con fsync, MiB/s
21.7
13.9

La tendencia a la caída del rendimiento del NVMe al usar fsync es bastante evidente. Podemos pasar a la respuesta a la segunda pregunta.

Optimización o engaño

Antes mencionamos que los datos se almacenan en un búfer, pero no especificamos en cuál, ya que no era relevante. No profundizaremos en los detalles de los sistemas operativos y señalaré dos tipos generales de búferes:

  • software;
  • hardware.

Se entiende por búfer de software a los búferes presentes en el sistema operativo, y por búfer de hardware a la memoria volátil del controlador del disco. La llamada del sistema fsync envía un comando al almacenamiento para escribir los datos de su búfer en el almacenamiento principal, pero no puede controlar la correcta ejecución de la orden.

Dado que los SSD muestran mejores resultados, se pueden hacer dos suposiciones:

  • el disco está diseñado para una carga de este tipo;
  • el disco "finge" e ignora el comando.

Se puede notar un comportamiento deshonesto del almacenamiento si se realiza una prueba con la pérdida de energía. Esto se puede verificar con el script diskchecker.pl, que fue se ha creado en 2005.

Este script requiere dos máquinas físicas: un "servidor" y un "cliente". El cliente escribe una pequeña cantidad de datos en el disco a probar, llama a fsync y envía al servidor la información sobre lo que se ha escrito.

# Запускается на сервере
./diskchecker.pl -l [port]

# Запускается на клиенте
./diskchecker.pl -s <server[:port]> create <file> <size_in_MB>

Después de iniciar el script, es necesario desconectar la alimentación del "cliente" y no volver a suministrarla durante varios minutos. Es importante desconectar específicamente el dispositivo que se está probando de la electricidad, y no simplemente realizar un apagado forzado. Después de cierto tiempo, se puede volver a conectar el servidor y cargar el sistema operativo. Una vez que el sistema operativo ha arrancado, se debe reiniciar diskchecker.pl, pero con el argumento verify.

.\/diskchecker.pl -s  verify

Al final de la verificación, verás la cantidad de errores. Si son 0, significa que el disco ha pasado la prueba. Para excluir la coincidencia afortunada para el disco, se puede repetir la experiencia varias veces.

Nuestro S4500 no mostró errores durante la pérdida de energía, así que se puede afirmar que está listo para cargas con un alto número de llamadas a fsync.

Conclusión

Al elegir discos o configuraciones completas, se debe tener en cuenta la especificidad de las tareas que se deben resolver. A primera vista parece obvio que NVMe, es decir, SSD con interfaz PCIe, es más rápido que el SSD SATA "clásico". Sin embargo, como hemos entendido hoy, en condiciones específicas y con ciertas tareas, esto puede no ser así.

¿Y cómo pruebas los componentes de los servidores al alquilarlos a un proveedor de IaaS?
Te esperamos en los comentarios.

¿Por qué mi NVMe es más lento que un SSD?

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster