Por que o mdadm escreve inutilmente lento quando montado de forma síncrona?

6

Eu tenho um array mdadm de 6 discos raid6. Eu gostaria de testar as gravações para:

root@ubuntu:~# cat /proc/mdstat 
Personalities : [raid6] [raid5] [raid4] 
md0 : active raid6 sda[0] sdf[5] sde[4] sdd[3] sdc[2] sdb[1]
      1953545984 blocks level 6, 64k chunk, algorithm 2 [6/6] [UUUUUU]

Os benchmarks podem ser imprecisos devido ao cache - por exemplo, observe que a velocidade de gravação é maior do que deveria:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.276026 s, 380 MB/s

Agora, podemos desativar cada cache de disco com bastante facilidade:

root@ubuntu:~# hdparm -W0 /dev/sd*

/dev/sda:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdb:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdc:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdd:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sde:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdf:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

Mas ainda há cache do Linux:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00566339 s, 1.9 GB/s

Para desativar o cache do Linux, podemos montar o sistema de arquivos de forma síncrona:

mount -o remount,sync /mnt/raid6

Mas depois disso, as gravações tornam-se caminho mais lentas do que deveriam ser:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 23.3311 s, 449 kB/s

É como se o mdadm exigisse montagens assíncronas para funcionar. O que está acontecendo aqui?

    
por chrishiestand 23.03.2011 / 09:37

3 respostas

1

O desempenho é drasticamente pior porque a escrita síncrona força a computação de paridade para martelar os discos.

Em geral, a paridade de computação e escrita é um processo relativamente lento, especialmente com o RAID 6 - no seu caso, o md tem que fragmentar os dados em quatro blocos e depois calcular dois fragmentos de paridade para cada faixa. Para melhorar o desempenho, as implementações RAID (incluindo md) armazenarão faixas recentemente usadas na memória para comparar os dados a serem gravados com os dados existentes e recompilar rapidamente a paridade na gravação. Se novos dados forem gravados em uma faixa em cache, ela poderá comparar, fragmentar e recompilar a paridade sem nunca tocar no disco e, em seguida, liberá-lo posteriormente. Você criou uma situação em que o md sempre erra o cache. Nesse caso, ele precisa ler a faixa do disco, comparar os dados, fragmentar os novos dados, recalcular a paridade e, em seguida, liberar a nova faixa diretamente no disco. O que exigiria zero leituras e gravações de / para disco em uma ocorrência de cache se torna seis leituras e seis gravações para cada faixa gravada.

Com certeza, a diferença de desempenho que você observou é enorme (1,9 GB / s contra 449KB / s), mas acho que tudo é contabilizado em quanto trabalho a MD está fazendo para manter a integridade dos dados.

Esse acerto de desempenho pode ser agravado pela maneira como você tem os discos organizados ... se você tiver todos eles em um controlador, muito mais leitura e escrita farão com que o desempenho fique parado.

    
por 15.04.2011 / 22:20
1

Citação do questionador:

But there is still Linux caching:

root@ubuntu:/mnt/raid6# dd if=/dev/zero of=delme bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00566339 s, 1.9 GB/s

To disable Linux caching, we can mount the filesystem synchronously:

mount -o remount,sync /mnt/raid6

Isso não está certo ... a sincronização simplesmente não desativa o cache como você quer em um benchmark. Isso faz com que cada resultado de gravação seja um comando "sync", o que significa liberar o cache até o disco.

Aqui está um servidor aqui, para explicar melhor:

$ dd if=/dev/zero of=testfile bs=1M count=500
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.183744 s, 2.9 GB/s

$ dd if=/dev/zero of=testfile bs=1M count=500 conv=fdatasync
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 5.22062 s, 100 MB/s

conv = fdatasync significa simplesmente flush após a gravação e informa o tempo incluindo o flush. Alternativamente, você pode fazer:

$ time ( dd if=/dev/zero of=testfile bs=1M count=500 ; sync )
500+0 records in
500+0 records out
524288000 bytes (524 MB) copied, 0.202687 s, 2.6 GB/s

real    0m2.950s
user    0m0.007s
sys     0m0.339s

E, em seguida, calcule MB / s a partir do tempo real de 2,95 em vez dos 0,2s acima. Mas isso é mais feio e mais trabalhoso, já que as estatísticas impressas por dd não incluem a sincronização.

Se você usou "sync", você iria liberar cada gravação ... talvez isso signifique cada bloco, o que seria muito lento. "sync" só deve ser usado em sistemas muito restritos, por exemplo. bancos de dados onde a perda de uma única transação devido a uma falha de disco é inaceitável (por exemplo, se eu transferir um bilhão de dólares da minha conta bancária para o seu e o sistema falhar, e de repente você tem o dinheiro, mas eu também). p>

Aqui está outra explicação com opções adicionais, uma sobre a qual li há muito tempo. link

E mais uma observação: Seu benchmark que você está fazendo dessa maneira é totalmente válido na minha opinião, embora não seja válido nas opiniões de muitos outros. Mas não é um teste da vida real. É uma única gravação seqüencial encadeada. Se o seu caso de uso da vida real é assim, por exemplo. enviando alguns arquivos grandes pela rede, então pode ser um bom benchmark. Se o seu caso de uso é diferente, por exemplo. um servidor ftp com 500 pessoas carregando arquivos pequenos ao mesmo tempo, então não é muito bom.

E também, você deve usar um arquivo gerado aleatoriamente na RAM para obter melhores resultados. Alguns sistemas de arquivos são muito inteligentes quando você os alimenta com zeros. por exemplo. no Linux usando o sistema de arquivos de ram tmpfs que é montado em / dev /. (e em alguns sistemas / dev / random ou / dev / urandom é lento, então use o outro ... Eu esqueci qual, mas em ambos eles serão muito menos do que a RAM, então não use diretamente)

dd if=/dev/random of=/dev/shm/randfile bs=1M count=500
dd if=/dev/shm/randfile bs=1M count=500 conv=fdatasync
    
por 04.05.2012 / 15:36
0

Você pode nos dizer como seus 6 discos são criados? Parece-me que faziam parte do SAN / DAS quaisquer metas - que provavelmente consistem nos mesmos discos físicos (portanto, se todos os 6 residirem no mesmo disco, isso degradará o desempenho em comparação com um único disco por 6).

Dê uma olhada neste link para anwerleaks.com.

Então, como você configurou seu bitmap?

    
por 15.04.2011 / 22:11