Por que o meu NVMe é máis lento que un SSD?

Por que o meu NVMe é máis lento que un SSD?
Neste artigo, analizaremos algúns dos matices do subsistema de E/S e o seu impacto no rendemento.

Hai un par de semanas atopeime cunha pregunta por que NVMe nun servidor é máis lento que SATA noutro. Observei as características dos servidores e decateime de que era unha pregunta trampa: NVMe era do segmento de usuarios e SSD era do segmento de servidores.

Obviamente, non é correcto comparar produtos de diferentes segmentos en diferentes ambientes, pero esta non é unha resposta técnica exhaustiva. Estudiaremos os conceptos básicos, realizaremos experimentos e daremos resposta á pregunta formulada.

Que é fsync e onde se usa

Para acelerar o traballo coas unidades, os datos son almacenados no búfer, é dicir, almacénanse na memoria volátil ata que se presenta unha oportunidade conveniente para gardar o contido do búfer na unidade. Os criterios de oportunidade están determinados polo sistema operativo e as características da unidade. En caso de falla de enerxía, perderanse todos os datos do búfer.

Hai unha serie de tarefas nas que debes asegurarte de que os cambios no ficheiro están escritos na unidade e non se atopan nun búfer intermedio. Esta garantía pódese obter mediante a chamada ao sistema fsync compatible con POSIX. A chamada fsync obriga a escribir desde o búfer á unidade.

Demostramos o efecto dos búfers cun exemplo artificial en forma de programa C curto.

#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;
}

Os comentarios explican ben a secuencia de accións do programa. O texto "a resposta á pregunta principal da vida, o universo e todo iso" será almacenado polo sistema operativo, e se reinicias o servidor premendo o botón Restablecer durante os "cálculos", o ficheiro estará baleiro. No noso exemplo, a perda de texto non é un problema, polo que non é necesario fsync. As bases de datos non comparten este optimismo.

As bases de datos son programas complexos que traballan con moitos ficheiros ao mesmo tempo, polo que queren estar seguros de que os datos que escriben se almacenarán na unidade, xa que disto depende a coherencia dos datos dentro da base de datos. As bases de datos están deseñadas para rexistrar todas as transaccións completadas e estar preparados para un corte de enerxía en calquera momento. Este comportamento obrígache a usar fsync constantemente en grandes cantidades.

O que afecta o uso frecuente de fsync

Coa E/S normal, o sistema operativo tenta optimizar a comunicación do disco, xa que as unidades externas son as máis lentas da xerarquía de memoria. Polo tanto, o sistema operativo tenta escribir tantos datos como sexa posible nun acceso á unidade.

Demostramos o impacto do uso de fsync cun exemplo específico. Temos os seguintes SSD como suxeitos de proba:

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

As probas realízanse nun Intel® Xeon® W-2255 con Ubuntu 20.04. Para probar discos, úsase sysbench 1.0.18. Os discos teñen unha única partición formatada como ext4. A preparación para a proba é crear ficheiros de 100 GB:

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

Probas de execució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

Os resultados das probas preséntanse na táboa.

Proba
Intel® S4500
Samsung 970 EVO+

Ler sen fsync, MiB/s
5734.89
9028.86

Escribir sen fsync, MiB/s
3823.26
6019.24

Lectura con fsync, MiB/s
37.76
3.27

Gravación con fsync, MiB/s
25.17
2.18

É fácil ver que NVMe do segmento de clientes lidera con confianza cando o propio sistema operativo decide como traballar cos discos e perde cando se usa fsync. Isto suscita dúas preguntas:

  1. Por que a velocidade de lectura supera o ancho de banda físico da ligazón na proba sen fsync?
  2. Por que un SSD do segmento de servidor é mellor para xestionar un gran número de solicitudes de sincronización?

A resposta á primeira pregunta é sinxela: sysbench xera ficheiros con cero. Así, a proba levouse a cabo sobre 100 gigabytes de ceros. Dado que os datos son moi uniformes e previsibles, varias optimizacións do sistema operativo entran en xogo e aceleran significativamente a execución.

Se cuestionas todos os resultados de sysbench, podes 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

Proba
Intel® S4500
Samsung 970 EVO+

Ler sen fsync, MiB/s
45.5
178

Escribir sen fsync, MiB/s
30.4
119

Lectura con fsync, MiB/s
32.6
20.9

Gravación con fsync, MiB/s
21.7
13.9

A tendencia á baixada do rendemento en NVMe cando se usa fsync é claramente visible. Podes pasar á segunda pregunta.

Optimización ou farol

Antes dixemos que os datos se almacenan nun buffer, pero non especificamos en cal, xa que non era importante. Aínda agora non afondaremos nas complejidades dos sistemas operativos e sinalaremos dous tipos xerais de búfers:

  • programa;
  • hardware.

O búfer de software fai referencia aos búfers que hai no sistema operativo e o búfer de hardware refírese á memoria volátil do controlador de disco. A chamada ao sistema fsync envía un comando á unidade para escribir datos do seu búfer ao almacenamento principal, pero non ten forma de controlar a execución correcta do comando.

Dado que o SSD funciona mellor, pódense facer dúas suposicións:

  • o disco está deseñado para unha carga dun plan similar;
  • o disco "enfada" e ignora o comando.

Pódese notar un comportamento deshonesto da unidade se realiza unha proba cunha falla de enerxía. Podes comprobar isto cun guión. comprobador de discos.pl, que estaba establecido o ano 2005.

Este script require dúas máquinas físicas: "servidor" e "cliente". O cliente escribe unha pequena cantidade de datos na unidade en proba, chama a fsync e envía ao servidor información sobre o que se escribiu.

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

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

Despois de executar o script, é necesario desactivar o "cliente" e non devolver a enerxía durante varios minutos. É importante desconectar o suxeito da proba da electricidade e non só realizar un apagado duro. Despois dun tempo, o servidor pódese conectar e cargar no SO. Despois de iniciar o sistema operativo, cómpre comezar de novo comprobador de discos.pl, pero cun argumento comprobar.

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

Ao final da comprobación, verá o número de erros. Se son 0, entón o disco pasou a proba. Para excluír unha combinación de circunstancias que teña éxito para o disco, o experimento pódese repetir varias veces.

O noso S4500 non mostrou erros de perda de enerxía, o que significa que está listo para cargas con moitas chamadas fsync.

Conclusión

Ao elixir discos ou configuracións preparadas enteiras, debes ter en conta as especificidades das tarefas que hai que resolver. A primeira vista, parece obvio que NVMe, é dicir, un SSD cunha interface PCIe, é máis rápido que un SSD SATA "clásico". Porén, como hoxe entendemos, en condicións concretas e con determinadas tarefas pode que non sexa así.

Como probas os compoñentes do servidor cando alugas a un provedor de IaaS?
Agardámoste nos comentarios.

Por que o meu NVMe é máis lento que un SSD?

Fonte: www.habr.com

Engadir un comentario