¿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, veremos algunos de los matices del subsistema de E/S y su impacto en el rendimiento.

Hace un par de semanas me encontré con la pregunta de por qué NVMe en un servidor es más lento que SATA en otro. Miré las características de los servidores y me di cuenta de que era una pregunta capciosa: NVMe era del segmento de usuarios y SSD era del segmento de servidores.

Obviamente, no es correcto comparar productos de diferentes segmentos en diferentes entornos, pero ésta no es una respuesta técnica exhaustiva. Estudiaremos los conceptos básicos, realizaremos experimentos y daremos respuesta a la pregunta planteada.

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

Para acelerar el trabajo con las unidades, los datos se almacenan en un búfer, es decir, se almacenan en una memoria volátil hasta que se presenta una oportunidad conveniente para guardar el contenido del búfer en la unidad. Los criterios de oportunidad están determinados por el sistema operativo y las características de la unidad. En caso de un corte de energía, se perderán todos los datos del búfer.

Hay una serie de tareas en las que debe asegurarse de que los cambios en el archivo se escriban en la unidad y no se encuentren en un búfer intermedio. Esta garantía se puede obtener utilizando la llamada al sistema fsync compatible con POSIX. La llamada fsync fuerza una escritura desde el búfer a la unidad.

Demostremos el efecto de los buffers con un ejemplo artificial en forma de un programa corto 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 del programa. El texto "la respuesta a la pregunta principal de la vida, el universo y todo eso" será almacenado en el sistema operativo, y si reinicia el servidor presionando el botón Restablecer durante los "cálculos", el archivo estará vacío. En nuestro ejemplo, la pérdida de texto no es un problema, por lo que no es necesario fsync. Las bases de datos no comparten este optimismo.

Las bases de datos son programas complejos que trabajan con muchos archivos al mismo tiempo, por lo que quieren estar seguros de que los datos que escriben se almacenarán en el disco, ya que de esto depende la coherencia 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 listas para un corte de energía en cualquier momento. Este comportamiento le obliga a utilizar fsync constantemente en grandes cantidades.

¿Qué afecta el uso frecuente de fsync?

Con E/S normal, el sistema operativo intenta optimizar la comunicación del disco, ya que las unidades externas son las más lentas en la jerarquía de memoria. Por lo tanto, el sistema operativo intenta escribir la mayor cantidad de datos posible en un solo acceso a la unidad.

Demostremos el impacto del uso de fsync con un ejemplo específico. Tenemos los siguientes SSD como sujetos de prueba:

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

Las pruebas se realizan en un Intel® Xeon® W-2255 con Ubuntu 20.04. Para probar discos, se utiliza sysbench 1.0.18. Los discos tienen una única partición formateada como ext4. La preparación para la prueba consiste en crear archivos de 100 GB:

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

Pruebas en ejecución:

# Без 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 la prueba se presentan en la tabla.

Prueba
Intel® S4500
Samsung 970 EVO+

Leer sin fsync, MiB/s
5734.89
9028.86

Escribir sin fsync, MiB/s
3823.26
6019.24

Lectura con fsync, MiB/s
37.76
3.27

Grabación con fsync, MiB/s
25.17
2.18

Es fácil ver que NVMe del segmento de clientes lidera con confianza cuando el propio sistema operativo decide cómo trabajar con los discos, y pierde cuando se usa fsync. Esto plantea dos preguntas:

  1. ¿Por qué la velocidad de lectura excede el ancho de banda físico del enlace en la prueba sin fsync?
  2. ¿Por qué un SSD de segmento de servidor es mejor para manejar una gran cantidad de solicitudes de sincronización?

La respuesta a la primera pregunta es simple: sysbench genera archivos con ceros. Así, la prueba se realizó sobre 100 gigabytes de ceros. Dado que los datos son muy uniformes y predecibles, entran en juego varias optimizaciones del sistema operativo que aceleran significativamente la ejecución.

Si cuestiona todos los resultados de sysbench, puede usar 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+

Leer sin fsync, MiB/s
45.5
178

Escribir sin fsync, MiB/s
30.4
119

Lectura con fsync, MiB/s
32.6
20.9

Grabación con fsync, MiB/s
21.7
13.9

La tendencia hacia la caída del rendimiento en NVMe cuando se usa fsync es claramente visible. Puedes pasar a la segunda pregunta.

Optimización o farol

Antes dijimos que los datos se almacenan en un buffer, pero no especificamos en cuál, ya que no era importante. Incluso ahora no profundizaremos en las complejidades de los sistemas operativos y destacaremos dos tipos generales de buffers:

  • programa;
  • hardware.

El búfer de software se refiere a los búferes que se encuentran en el sistema operativo y el búfer de hardware se refiere a la memoria volátil del controlador de disco. La llamada al sistema fsync envía un comando a la unidad para escribir datos desde su búfer al almacenamiento principal, pero no tiene forma de controlar la ejecución correcta del comando.

Dado que el SSD funciona mejor, se pueden hacer dos suposiciones:

  • el disco está diseñado para una carga de plan similar;
  • el disco "farolea" e ignora el comando.

Se puede notar un comportamiento deshonesto de la unidad si realiza una prueba con un corte de energía. Puedes comprobar esto con un script. diskchecker.pl, который был creado en el año 2005.

Este script requiere dos máquinas físicas: "servidor" y "cliente". El cliente escribe una pequeña cantidad de datos en la unidad bajo prueba, llama a fsync y envía al servidor información sobre lo que se escribió.

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

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

Después de ejecutar el script, es necesario desactivar el "cliente" y no devolver la energía durante varios minutos. Es importante desconectar el sujeto de prueba de la electricidad y no simplemente realizar un apagado forzado. Después de un tiempo, el servidor se puede conectar y cargar en el sistema operativo. Después de iniciar el sistema operativo, debe comenzar de nuevo diskchecker.pl, pero con un argumento verificar.

./diskchecker.pl -s <server[:port]> verify <file>

Al final de la verificación, verá la cantidad de errores. Si son 0, entonces el disco pasó la prueba. Para excluir una combinación de circunstancias que sea exitosa para el disco, el experimento se puede repetir varias veces.

Nuestro S4500 no mostró errores de pérdida de energía, lo que significa que está listo para cargas con muchas llamadas fsync.

Conclusión

Al elegir discos o configuraciones completas ya preparadas, se deben tener en cuenta las características específicas de las tareas que deben resolverse. A primera vista, parece obvio que NVMe, es decir, un SSD con interfaz PCIe, es más rápido que un SSD SATA "clásico". Sin embargo, como hemos comprendido hoy, en condiciones específicas y con determinadas tareas esto puede no ser así.

¿Cómo se prueban los componentes del servidor cuando se alquila a un proveedor de IaaS?
Te esperamos en los comentarios.

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

Fuente: habr.com

Añadir un comentario