Estou tentando configurar o MD RAID1 (usando o mdadm) com a --write-mostly
opção para que um volume de rede (EBS) e uma unidade local sejam espelhos um do outro (a ideia é que a unidade local seja efêmera para minha instância, mas tenha melhor desempenho).
Para testar essa ideia, obtenho uma estimativa de desempenho básica da minha unidade usando os dois scripts a seguir.
fio -name=RandWrite -group_reporting -allow_file_create=0 \
-direct=1 -iodepth=128 -rw=randwrite -ioengine=io_uring -bs=32k \
-time_based=1 -ramp_time=10 -runtime 10 -numjobs=8 \
-randrepeat=0 -norandommap=1 -filename=$BENCHMARK_TARGET
# Read performance
fio -name=RandRead -group_reporting -allow_file_create=0 \
-direct=1 -iodepth=128 -rw=randread -ioengine=io_uring -bs=32k \
-time_based=1 -ramp_time=10 -runtime 10 -numjobs=8 \
-randrepeat=0 -norandommap=1 -filename=$BENCHMARK_TARGET
Resultados:
- Unidade de rede: 117 MiB/s de gravação, 117 MiB/s de leitura
- Unidade local: 862 MiB/s de gravação, 665 MiB/s de leitura
O problema surge quando introduzo o mdadm. Mesmo ao usar um trivial no-mirror "RAID1", o desempenho de gravação é severamente pior ao usar a unidade de rede.
mdadm --build /dev/md0 --verbose --level=1 --force --raid-devices=1 "$TARGET"
# mdadm --detail /dev/md0
/dev/md0:
Version :
Creation Time : Mon Sep 30 14:22:41 2024
Raid Level : raid1
Array Size : 10485760 (10.00 GiB 10.74 GB)
Used Dev Size : 10485760 (10.00 GiB 10.74 GB)
Raid Devices : 1
Total Devices : 1
State : clean
Active Devices : 1
Working Devices : 1
Failed Devices : 0
Spare Devices : 0
Consistency Policy : resync
Number Major Minor RaidDevice State
0 8 16 0 active sync /dev/sdb
- Matriz RAID1 de 0 espelhos apoiada por unidade de rede: 69,9 MiB/s de gravação, 118 MiB/s de leitura
- Matriz RAID1 de 0 espelhos apoiada por unidade local: 868 MiB/s de gravação, 665 MiB/s de leitura
Como podemos ver aqui, o desempenho de gravação não mudou muito para a unidade local (MD-raid vs. acesso raw), mas é severamente prejudicado ao usar a unidade de rede via MD-raid. Por que isso acontece?
Sem saber a implementação exata do mdadm, vou escrever meu palpite sobre isso.
Acho que na configuração RAID 1, o subsistema RAID espera que ambas as unidades reconheçam as operações de gravação antes de processar os próximos eventos de arquivo. E então pode haver atrasos adicionais introduzidos pela incompatibilidade de desempenho entre as unidades, o que contribuiria para a velocidade de gravação de 69,9 MiB/s vs 117 MiB/s.
Não acho que seja viável criar matrizes RAID com dispositivos onde a velocidade de acesso é muito diferente. RAID não foi projetado para esse caso de uso.
Talvez você queira considerar um sistema de arquivos de cluster como GFS2 ou OCFS2, pois eles podem ser mais adequados para seu caso de uso.
Até onde posso perceber, esse é um modo de falha causado pela sobrecarga do módulo do kernel MD com IOPS.
Quando modifico meus scripts para usar iodepth=64 numjobs=1, não vejo perda de desempenho nas unidades brutas, e o impacto no desempenho de gravação do RAID1 desaparece.
Aqui estão os scripts finais:
E aqui estão os resultados líquidos:
numjobs=8
numjobs=1
Estou supondo que muitos IOPS combinados com a unidade mais lenta levam a um comprimento de fila excessivo, o que então leva a algum tipo de contenção de bloqueio no módulo do kernel. Mas não sei detalhes suficientes para ter certeza. O que aprendi é que precisarei de um benchmark mais preciso para decidir adequadamente se essa abordagem é viável para meu caso de uso.
Você provavelmente está preso ao MD write bitmap. Você pode tentar desabilitá-lo (via
--bitmap=none
during creation ou mais tarde com--grow
), mas certifique-se de entender que um desligamento impuro em um array sem bitmap significa uma ressincronização completa após a reinicialização.