Uso do O_DIRECT no Linux

23

Se essa pergunta for muito programada, me avise. Gostaria de saber se há pessoas familiarizadas com o sinalizador O_DIRECT para a chamada de sistema open () no Linux 2.6? Linus menospreza seu uso, no entanto, a gravação de arquivos de alto desempenho parece indicar seu uso. Gostaria de saber alguma experiência e recomendações do mundo real.

Mais informações: A aplicação que estou usando não manter seu próprio cache, e ao fazer isso alcança uma média de 5x ou mais velocidade para cima. Ao gravar no arquivo, o conteúdo do cache deve ser gravado no cache do sistema de arquivos, o que parece redundante e preocupa o desempenho.

casualunixer
fonte

Respostas:

17

Ok, você pede experiências, isso torna a pergunta um pouco subjetiva e argumentativa, mas aceitável.

Linus disse que, referindo-se aos usos que as pessoas geralmente atribuem ao O_DIRECT, e para esses usos, o IMO Linus está mais correto. Mesmo que você direcione a E / S, não pode transferir dados de / para dispositivos diretamente para as instruções do programa, você precisa de um buffer que seja preenchido (pelo programa ou pelo dispositivo) e transferido através de uma chamada do sistema para a outra extremidade. Além disso, para torná-lo eficiente, não será necessário reler algo que você já leu, caso precise novamente. Então você precisa de algum tipo de cache ... e é exatamente isso que o kernel fornece sem O_DIRECT, um cache de página! Por que não usar isso? Ele também traz benefícios, se mais processos quiserem acessar o mesmo arquivo simultaneamente, seria um desastre com o O_DIRECT.

Dito isto, O_DIRECT tem seus usos: Se por algum motivo você precisar obter dados diretamente do dispositivo de bloco. Não tem nada a ver com desempenho.

As pessoas que usam o O_DIRECT para desempenho geralmente vêm de sistemas com algoritmos de cache de página incorretos, ou sem mecanismos de aconselhamento POSIX, ou mesmo pessoas repetindo sem pensar o que outras pessoas disseram. Para evitar esses problemas, O_DIRECT era uma solução. O Linux, OTOH, tem a filosofia de que você deve corrigir o problema subjacente real, e o problema subjacente foram os SOs que fizeram um trabalho ruim com o cache da página.

Eu usei O_DIRECT para uma implementação simples do gato para encontrar um erro de memória na minha máquina. Este é um uso válido para O_DIRECT. Isso não tinha nada a ver com desempenho.

Juliano
fonte
Obrigado pela informação, é apreciado. Atualizei minha pergunta com as condições específicas do aplicativo que levaram a essa pergunta. Se você tiver mais detalhes sobre os mecanismos de orientação do POSIX para gravar arquivos, isso também será apreciado.
precisa saber é o seguinte
4
o_direct também pode ser útil em um sistema em que o desenvolvedor deseja fornecer um mecanismo de armazenamento em cache na camada de aplicativos (pense em bancos de dados).
precisa saber é o seguinte
Não tem nada a ver com desempenho. Isso nem sempre é verdade, especialmente para acessar um dispositivo de alta velocidade em que a IO classifica a largura de banda da memória, ou mesmo apenas uma porcentagem significativa da largura de banda da memória. Nesse caso, pular a cópia extra para / do cache da página pode trazer benefícios significativos de desempenho.
Andrew Henle 14/10
13

Na verdade, O_DIRECT é necessário para evitar

  • poluição do cache - às vezes você sabe que não há sentido em sobrecarga com o cache, por exemplo, ao lidar com arquivos muito grandes, digamos 64 GiB quando há apenas 2 GiB de RAM. O arquivo torrent de 32 GiB, que um usuário decidiu verificar, não parece ser um bom candidato para o cache. É apenas uma atividade extra com sua própria sobrecarga. E isso pode fazer com que alguns dados realmente úteis sejam removidos do cache.
  • cache duplo - por exemplo, alguns RDBMSes (MySQL para mencionar) permite definir seu próprio cache. Os bancos de dados supostamente sabem melhor como armazenar em cache e o quê, do que a memória virtual do kernel, que não sabe nada sobre planejamento de SQL e assim por diante.

- o que não é bom, ao que parece. E O_DIRECTnão significa ser mais rápido, muitas vezes não é .

poige
fonte
10
posix_fadvisepode cuidar do problema de poluição do cache.
Psusi
Eu não acho que a memória virtual tenha algo a ver com isso, apenas mapeia o endereço da memória. Cache de buffer / cache de página é o que você quer dizer.
ArekBulski 26/10/2015
Os caches / cache fazem parte do subsistema VM no UNIX, pelo que sei, é por isso que usei esse termo. Obrigado pela edição. :)
poige 26/10/2015
6

Observe que o uso O_DIRECTpode falhar em kernels mais recentes com sistemas de arquivos mais recentes. Veja este relatório de erros, por exemplo. Portanto, o uso não é apenas duvidoso, como provavelmente não funcionará na próxima geração de distribuições Linux. Portanto, eu não apostaria o desempenho do meu código nele, mesmo que você prove que ele pode ter um benefício.

Peter Eisentraut
fonte
1
O relatório de bug discute o uso de sistemas de arquivos com a opção journal = data ativada. Esta opção é diretamente oposta ao sinalizador O_DIRECT. A maioria dos sistemas de arquivos ext3 e ext4 não possui esse sinalizador definido e, se houver, desativá-lo permitirá a abertura do arquivo com O_DIRECT.
precisa saber é o seguinte
3

Tem muito a ver com desempenho.

Um exemplo interessante está no mongodb usando o mecanismo mmap. O_DIRECT é melhor usado, como outros já declararam, onde é improvável que os dados sejam lidos por algum tempo. No mongodb, o diário do banco de dados é gravado usando O_DIRECT enquanto as gravações de dados e índices são tratadas pelo mecanismo de cache da página (pdflush) porque, embora O_DIRECT ofereça menos largura de banda, também significa menos latência e, portanto, reduz a perda de dados no caso de um interrupção inesperada (pânico do kernel, disco ou falha de energia). Observe que ainda há buffer antes que uma gravação O_DIRECT seja confirmada no armazenamento não volátil, isso apenas reduz a perda de dados.

Outro recurso importante do O_DIRECT é que ele fornece mais controle sobre a sequência de gravações. Novamente, não garante a ordem das gravações (a menos que você tenha um controlador de disco em cache não volátil e esteja usando o agendador fifo, mas eles têm suas próprias complicações). Portanto, embora o mysql use O_DIRECT para seus dados / índices, bem como para diários, ele pode esperar que o último seja normalmente comprometido primeiro.

Mas é importante lembrar que O_DIRECT quebra a justiça na alocação de recursos. Uma das razões pelas quais seu aplicativo é acelerado é que ele está diminuindo a velocidade de outras coisas.

symcbean
fonte
Você diz que isso tem muito a ver com desempenho, mas fornece um exemplo em que é usado para diminuir a latência ou solicitar gravações. Mas concordo que isso afeta o desempenho. Ponto justo sobre justiça.
ArekBulski 27/10/2015
Você pode fornecer mais referências explicando quando é injusto?
ACyclic
3

Em relação ao que o @Juliano já disse.

Faça uma verificação geral posix_fadvisese o problema real é o mau comportamento do algoritmo de cache do sistema de arquivos subjacente, você pode tentar dar conselhos sobre como usar o sistema de arquivos. Para fs bem implementados, deve aumentar o desempenho. (Aqui está o link para outro tópico que aborda considerações semelhantes /programming//a/3755818/544721 )

Grzegorz Wierzowiecki
fonte
1
Parece que posix_fadvise altera os algoritmos de readahead usados ​​pelo kernel. O fator crítico com o código na pergunta é o desempenho da gravação. O problema é que a gravação do buffer preenche os caches do Linux primeiro, que o kernel precisa despejar quando ficar sem memória. Isso é um desperdício de esforço, a saída nesse caso deve ser minimamente armazenada em buffer no caminho para o disco.
casualunixer