Posso configurar meu sistema Linux para um cache mais agressivo do sistema de arquivos?

119

Não estou preocupado com o uso da RAM (como eu tenho o suficiente) nem com a perda de dados em caso de um desligamento acidental (como minha energia é suportada, o sistema é confiável e os dados não são críticos). Mas eu faço muito processamento de arquivos e poderia usar algum aumento de desempenho.

É por isso que eu gostaria de configurar o sistema para usar mais RAM para o cache de leitura e gravação do sistema de arquivos, para buscar previamente os arquivos de forma agressiva (por exemplo, leia com antecedência o arquivo inteiro acessado por um aplicativo, caso o arquivo seja de tamanho normal ou pelo menos leia antes um grande pedaço) e libere os buffers de gravação com menos frequência. Como conseguir isso (pode ser possível)?

Eu uso sistemas de arquivos ext3 e ntfs (eu uso muito ntfs!) Com o XUbuntu 11.10 x86.

Ivan
fonte
6
Se você tem muita RAM, se preocupa muito com o desempenho e não se preocupa com a perda de dados, basta copiar todos os dados para um disco RAM e servi-los a partir daí, descartando todas as atualizações em caso de falha / desligamento. Se isso não funcionar para você, talvez seja necessário qualificar "o suficiente" para RAM ou quão críticos os dados não são.
James Youngman
11
@ Nils, o computador é um laptop, então, acredito, o controlador é bastante comum.
Ivan
11
Uma maneira de melhorar muito o desempenho é pular a durabilidade dos dados. Simplesmente desative a sincronização com o disco, mesmo que alguns aplicativos solicitem sincronização. Isso causará perda de dados se o seu dispositivo de armazenamento sofrer perda de eletricidade. Se você quiser fazer isso de qualquer maneira, basta executar sudo mount -o ro,nobarrier /path/to/mountpointou ajustar /etc/fstabpara incluir nobarrierqualquer sistema de arquivos que você esteja disposto a sacrificar para melhorar o desempenho. No entanto, se o seu dispositivo de armazenamento tiver bateria interna, como a série SSD Intel 320, o uso nobarriernão causará perda de dados.
Mikko Rantalainen
11
O uso de nobarrier não é mais recomendado no Red Hat Enterprise Linux 6, pois o impacto negativo no desempenho das barreiras de gravação é insignificante (aproximadamente 3%). Os benefícios das barreiras de gravação geralmente superam os benefícios de desempenho de desativá-las. Além disso, a opção nobarrier nunca deve ser usada no armazenamento configurado em máquinas virtuais. access.redhat.com/documentation/pt-BR/Red_Hat_Enterprise_Linux/…
Ivailo Bardarov 20/17
11
Dois pontos - 1) Existem distribuições linux baseadas no Debian ou Ubuntu, como o Puppy Linux e o AntiX Linux, e muitas outras que colocam todo o sistema operacional em partições ramdisk em camadas (por exemplo, AUFS ou overlayfs) e o gerenciam de forma transparente. Muito rápido! - 2) Descobrimos no design do mundo real de um sistema muito grande que jogar mais cache nele pode REDUZIR O DESEMPENHO. À medida que as velocidades de armazenamento aumentam (ou seja, SSD), o tamanho ideal do cache necessário diminui. No entanto, não há como saber qual é esse tamanho sem a experimentação em seu sistema específico. Se o aumento não estiver funcionando, tente reduzi-lo.
DocSalvager 23/08

Respostas:

107

Melhorar o desempenho do cache de disco em geral é mais do que apenas aumentar o tamanho do cache do sistema de arquivos, a menos que todo o sistema caiba na RAM. Nesse caso, você deve usar a unidade de RAM ( tmpfsé bom porque permite voltar ao disco, se você precisar da RAM em algum caso) para armazenamento em tempo de execução (e talvez um script initrd para copiar o sistema do armazenamento para a unidade RAM na inicialização).

Você não disse se o seu dispositivo de armazenamento é SSD ou HDD. Aqui está o que eu descobri que funciona para mim (no meu caso, sdaé um HDD montado em /homee sdbum SSD montado em /).

Primeiro, otimize a parte carregar-coisas-de-armazenamento-para-cache:

Aqui está minha configuração para o HDD (verifique se o AHCI + NCQ está ativado no BIOS se você tiver alternado):

echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda

É importante notar que o gabinete do disco rígido é alto fifo_expire_async(geralmente gravado) e longo slice_syncpara permitir que um único processo obtenha alto rendimento (definido slice_synccomo número menor se você encontrar situações em que vários processos aguardam alguns dados do disco em paralelo). A slice_idleé sempre um compromisso para HDDs mas defini-lo em algum lugar na faixa de 3-20 deve ser aprovado de acordo com o uso do disco e firmware disco. Prefiro segmentar valores baixos, mas defini-lo muito baixo destruirá sua taxa de transferência. A quantumconfiguração parece afetar muito a taxa de transferência, mas tente manter isso o mais baixo possível para manter a latência em nível sensato. Definir quantummuito baixo destruirá a taxa de transferência. Os valores no intervalo de 3 a 8 parecem funcionar bem com os HDDs. A pior latência para uma leitura é ( quantum* slice_sync) + ( slice_async_rq*slice_async) ms se eu entendi o comportamento do kernel corretamente. O assíncrono é usado principalmente por gravações e, como você deseja adiar a gravação no disco, defina números ambos slice_async_rqe slice_asyncmuito baixos. No entanto, definir slice_async_rqum valor muito baixo pode interromper as leituras, porque as gravações não podem mais ser adiadas após a leitura. Minha configuração vai tentar gravar dados em disco, no máximo, após 10 segundos após os dados terem sido passados ao kernel, mas desde que você pode tolerar a perda de dados sobre a perda de poder também definidos fifo_expire_asyncpara 3600000dizer que uma hora é bom para o atraso no disco. Apenas mantenha o nível slice_asyncbaixo, pois, caso contrário, você poderá obter alta latência de leitura.

O hdparmcomando é necessário para impedir que o AAM destrua grande parte do desempenho que o AHCI + NCQ permite. Se o seu disco emitir muito ruído, pule-o.

Aqui está minha configuração para SSD (Intel 320 series):

echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync

Aqui vale a pena observar os valores baixos para diferentes configurações de fatia. A configuração mais importante para um SSD é a slice_idleque deve ser definida como 0-1. A configuração para zero move todas as decisões de pedido para o NCQ nativo, enquanto a configuração para 1 permite que o kernel solicite solicitações (mas se o NCQ estiver ativo, o hardware poderá substituir parcialmente a solicitação do kernel). Teste os dois valores para ver se você consegue ver a diferença. Para Intel 320 series, parece que a criação slide_idlede 0dá o melhor rendimento, mas defini-lo como 1dá melhor (menor) latência total.

Para mais informações sobre esses ajustáveis, consulte http://www.linux-mag.com/id/7572/ .

Agora que configuramos o kernel para carregar coisas do disco para o cache com desempenho razoável, é hora de ajustar o comportamento do cache:

De acordo com os benchmarks que fiz, não me incomodaria em definir a leitura antecipada blockdev. As configurações padrão do kernel estão bem.

Defina o sistema para preferir trocar dados do arquivo pelo código do aplicativo (isso não importa se você possui RAM suficiente para manter todo o sistema de arquivos e todo o código do aplicativo e toda a memória virtual alocada pelos aplicativos na RAM). Isso reduz a latência para trocar entre aplicativos diferentes por latência para acessar arquivos grandes a partir de um único aplicativo:

echo 15 > /proc/sys/vm/swappiness

Se você preferir manter os aplicativos quase sempre na RAM, poderá configurá-lo como 1. Se você definir como zero, o kernel não será trocado, a menos que seja absolutamente necessário para evitar o OOM. Se você estava com pouca memória e trabalhando com arquivos grandes (por exemplo, edição de vídeo em HD), pode fazer sentido definir isso próximo a 100.

Hoje em dia (2017) prefiro não ter nenhuma troca se você tiver RAM suficiente. Não ter troca normalmente perderá de 200 a 1000 MB de RAM em uma máquina desktop de longa duração. Estou disposto a sacrificar muito para evitar a latência do pior cenário possível (trocar o código do aplicativo quando a RAM estiver cheia). Na prática, isso significa que prefiro o OOM Killer à troca. Se você permitir / precisar de trocas, também poderá aumentar /proc/sys/vm/watermark_scale_factor, para evitar alguma latência. Eu sugeriria valores entre 100 e 500. Você pode considerar essa configuração como negociando o uso da CPU por uma menor latência de troca. O padrão é 10 e o máximo possível é 1000. Um valor mais alto deve (de acordo com a documentação do kernel ) resultar em maior uso da CPU para kswapdprocessos e menor latência geral de troca.

Em seguida, diga ao kernel para preferir manter a hierarquia de diretórios na memória sobre o conteúdo do arquivo, caso alguma RAM precise ser liberada (novamente, se tudo couber na RAM, essa configuração não faz nada):

echo 10 > /proc/sys/vm/vfs_cache_pressure

Configuração vfs_cache_pressurevalor baixo faz sentido porque, na maioria dos casos, o kernel precisa conhecer a estrutura de diretórios antes de poder usar o conteúdo do arquivo no cache e liberá-lo muito cedo fará com que o cache de arquivos seja praticamente inútil. Considere descer até 1 com essa configuração se você tiver muitos arquivos pequenos (meu sistema tem fotos com cerca de 150 mil e 10 megapixels e conta como sistema "muitos arquivos pequenos"). Nunca defina como zero ou a estrutura de diretórios será sempre mantida na memória, mesmo que o sistema esteja ficando sem memória. Definir esse valor como grande só é sensato se você tiver apenas alguns arquivos grandes que estão sendo relidos constantemente (novamente, a edição de vídeo em HD sem RAM suficiente seria um exemplo). A documentação oficial do kernel diz que "

Exceção: se você possui uma quantidade realmente grande de arquivos e diretórios e raramente toca / lê / lista todos os arquivos com configuração vfs_cache_pressuresuperior a 100 podem ser sábios. Isso se aplica apenas se você não tiver RAM suficiente e não puder manter toda a estrutura de diretórios na RAM e ainda tiver RAM suficiente para processos e cache de arquivos normais (por exemplo, servidor de arquivos para toda a empresa com muito conteúdo de arquivo). Se você sente que precisa aumentar vfs_cache_pressureacima de 100, está executando sem RAM suficiente. Aumentar vfs_cache_pressurepode ajudar, mas a única solução real é obter mais RAM. A vfs_cache_pressuredefinição de um número alto sacrifica o desempenho médio por ter um desempenho geral mais estável (ou seja, você pode evitar um comportamento realmente ruim no pior dos casos, mas precisa lidar com um desempenho geral pior).

Por fim, diga ao kernel para usar até 99% da RAM como cache para gravações e instrua o kernel a usar até 50% da RAM antes de desacelerar o processo que está gravando (o padrão dirty_background_ratioé 10). Aviso: eu pessoalmente não faria isso, mas você afirmou ter RAM suficiente e está disposto a perder os dados.

echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio

E diga que 1h de atraso de gravação é bom mesmo para começar a escrever coisas no disco (novamente, eu não faria isso):

echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs

Se você colocar tudo isso /etc/rc.locale incluir o seguinte no final, tudo ficará em cache assim que possível após a inicialização (faça isso apenas se o seu sistema de arquivos realmente se encaixar na RAM):

(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

Ou uma alternativa um pouco mais simples, que pode funcionar melhor (somente cache /homee /usr, apenas faça isso se você /homee /usrrealmente couber na RAM):

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Mikko Rantalainen
fonte
3
Uma resposta bem informada e em geral muito melhor do que a aceita! Este é subestimado ... Eu acho que a maioria das pessoas quer apenas instruções simples sem se preocupar em entender o que eles realmente fazer ...
Vladimir Panteleev
2
@ Phpdevpad: Além disso, a pergunta dizia "Não estou preocupada com o uso da RAM" [...] "- não acho que nenhum dispositivo Maemo se qualifique.
Mikko Rantalainen
11
Noop ou prazo não é um agendador melhor para SSDs?
rep_movsd
11
@rep_movsd Eu tenho usado apenas unidades SSD Intel, mas pelo menos essas unidades ainda são lentas o suficiente para ter um melhor desempenho geral com agendadores mais inteligentes, como CFQ. Eu acho que se a sua unidade SSD puder lidar com mais de 100 mil IOPS aleatórios, usar noop ou prazo faria sentido, mesmo com CPU rápida. Com "CPU rápida", quero dizer algo que tenha pelo menos vários núcleos de 3GHz disponíveis apenas para E / S.
Mikko Rantalainen
11
Você também pode ler sobre esses ajustáveis ​​do vm nos documentos do kernel do vm .
Joeytwiddle
16

Em primeiro lugar, NÃO recomendo que você continue usando o NTFS, pois a implementação do NTFS no Linux seria um problema de desempenho e segurança a qualquer momento.

Há várias coisas que você pode fazer:

  • use alguns fs mais recentes, como ext4oubtrfs
  • tente alterar seu agendador io, por exemplo bfq
  • desativar troca
  • use algum pré-carregador automático como preload
  • use algo como systemdpré-carregar durante a inicialização
  • ... e algo mais

Talvez você queira experimentá-lo :-)

Felix Yan
fonte
11
Já mudei completamente do NTFS para o ext4 uma vez, deixando a única partição NTFS na partição do sistema Windows. Mas isso trouxe muitos inconvenientes para mim e voltei ao NTFS como a principal partição de dados (onde guardo todos os meus documentos, downloads, projetos, código fonte etc.) sistema de arquivos. Não desisto de repensar minha estrutura de partições e meu fluxo de trabalho (para usar menos Windows), mas desistir de NTFS agora não parece uma opção realista.
317 Ivan Ivan
Se você também precisar usar seus dados no Windows, o NTFS pode ser a única opção. (muitas outras opções disponíveis se você pode usar seu Windows apenas como um VM dentro linux)
Felix Yan
11
Um resumo do que esses supostos problemas são do NTFS teria sido útil.
Underscore_d
2
O NTFS no Linux é praticamente aceitável, exceto pelo desempenho. Considerando que a pergunta era especificamente sobre como melhorar o desempenho do sistema de arquivos, o NTFS deve ser a primeira coisa a ser executada.
Mikko Rantalainen
Embora o btrfssistema de arquivos tenha sido projetado recentemente, eu evitaria isso se fosse necessário desempenho. Fomos correndo sistemas idênticos com btrfse ext4sistemas de arquivos e ext4vitórias no mundo real com uma grande margem ( btrfsparece exigir cerca de tempo de CPU 4x as ext4necessidades para o mesmo nível de desempenho e causa mais operações de disco para um único comando lógico). Dependendo da carga de trabalho, sugiro ext4, jfsou xfspara qualquer trabalho que exija desempenho.
Mikko Rantalainen
8

Leia adiante:

Em sistemas de 32 bits:

blockdev --setra 8388607 /dev/sda

Em sistemas de 64 bits:

blockdev --setra 4294967295 /dev/sda

Escreva atrás do cache:

echo 100 > /proc/sys/vm/dirty_ratio

Isso utilizará até 100% de sua memória livre como cache de gravação.

Ou você pode usar todos os recursos e usar tmpfs. Isso é relevante apenas se você tiver RAM suficiente. Coloque isso /etc/fstab. Substitua 100G pela quantidade de RAM física.

tmpfs /mnt/tmpfs tmpfs size=100G,rw,nosuid,nodev 0 0

Então:

mkdir /mnt/tmpfs; mount -a

Então use / mnt / tmpfs.

Ole Tange
fonte
5
Readahead de 3 GB ou 2 TB? realmente? Você sabe mesmo o que essas opções fazem?
Cobra_Fast
11
@Cobra_Fast Você sabe o que isso significa? Eu realmente não tenho idéia e estou interessado agora.
syss
3
@syss as configurações do readahead são salvas como número de "blocos" de memória, não bytes ou bits. O tamanho de um bloco é determinado no tempo de compilação do kernel (já que os blocos de leitura são blocos de memória) ou no tempo de criação do sistema de arquivos em alguns casos. Normalmente, porém, 1 bloco contém 512 ou 4096 bytes. Veja linux.die.net/man/8/blockdev
Cobra_Fast
6

Você pode definir o tamanho da leitura antecipada com blockdev --setra sectors /dev/sda1, em que setores é o tamanho desejado em setores de 512 bytes.

psusi
fonte
2

Minha configuração matadora é muito simples e muito eficaz:

echo "2000" > /proc/sys/vm/vfs_cache_pressure

A explicação da documentação do kernel :

vfs_cache_pressure

Controla a tendência do kernel de recuperar a memória usada para armazenar em cache objetos de diretório e inode.

No valor padrão de vfs_cache_pressure = 100, o kernel tentará recuperar dentries e inodes a uma taxa "razoável" em relação à recuperação de pagecache e swapcache. Diminuir vfs_cache_pressure faz com que o kernel prefira reter caches de dentry e inode. Quando vfs_cache_pressure = 0, o kernel nunca recuperará dentries e inodes devido à pressão da memória e isso pode facilmente levar a condições de falta de memória. Aumentar vfs_cache_pressure além de 100 faz com que o kernel prefira recuperar dentries e inodes.

vfs_cache_pressure em 2000, faz com que a maior parte da computação ocorra na RAM e em gravações de disco muito tardias.

slm
fonte
4
Definir vfs_cache_pressuremuito alto (eu consideraria 2000muito alto) causará acesso desnecessário ao disco, mesmo para coisas simples, como listagens de diretório que devem caber facilmente no cache. Quanta RAM você tem e o que está fazendo com o sistema? Como escrevi na minha resposta, o uso de alto valor para essa configuração faz sentido, por exemplo, na edição de vídeo HD com RAM limitada.
Mikko Rantalainen
2
Observe que a documentação referenciada continua: " Aumentar significativamente o vfs_cache_pressure além de 100 pode ter um impacto negativo no desempenho. O código de recuperação precisa levar vários bloqueios para encontrar objetos de diretório e inode disponíveis. Com vfs_cache_pressure = 1000, ele procurará objetos dez vezes mais disponíveis do que existem estão."
Mikko Rantalainen 14/0318
1

Não relacionado ao cache de gravação, mas relacionado a gravações:

  • Para um sistema ext4, você pode desativar completamente o registro no diário

    Isso reduzirá o número de gravações de disco para qualquer atualização específica, mas pode deixar o sistema de arquivos em um estado inconsistente após um desligamento inesperado, exigindo um fsck ou pior.

Para impedir que as leituras do disco disparem gravações em disco:

  • Montar com o relatime ou o noatime opção

    Quando você lê um arquivo, os metadados "hora do último acesso" para esse arquivo geralmente são atualizados. A noatimeopção desativará esse comportamento. Isso reduz gravações desnecessárias em disco, mas você não terá mais esses metadados. Algumas distribuições (por exemplo, Manjaro) adotaram isso como padrão em todas as partições (provavelmente para aumentar a vida útil dos SSDs de modelos anteriores).

    relatimeatualiza o tempo de acesso com menos frequência, de acordo com heurísticas que ajudam a dar suporte a aplicativos que usam o atime. Este é o padrão no Red Hat Enterprise Linux.

Outras opções:

  • Nos comentários acima, Mikko compartilhou a possibilidade de montar com a opção nobarrier . Ivailo, porém, citou a RedHat que é cautelosa. Você quer 3% a mais?
joeytwiddle
fonte