Qual é a filosofia por trás do atraso na gravação de dados no disco?


72

No Linux, uma execução finalizada de um comando como cpou ddnão significa que os dados foram gravados no dispositivo. É necessário, por exemplo, chamar syncou chamar a função "Remover com segurança" ou "Ejetar" na unidade.

Qual é a filosofia por trás dessa abordagem? Por que os dados não são gravados de uma só vez? Não há perigo de que a gravação falhe devido a um erro de E / S?


16
Lembre-se de que as chamadas do sistema de leitura e gravação podem funcionar com um byte de cada vez, mas as unidades de disco podem apenas ler ou gravar blocos de tamanho fixo. A sobrecarga do byte em uma E / S de tempo seria intolerável sem buffer. Com o buffer, é suportável.
22815 Jonathan

Respostas:


47

Qual é a filosofia por trás dessa abordagem?

Eficiência (melhor uso das características do disco) e desempenho (permite que o aplicativo continue imediatamente após uma gravação).

Por que os dados não são gravados de uma só vez?

A principal vantagem é que o sistema operacional é livre para reordenar e mesclar operações de gravação contíguas para melhorar o uso da largura de banda (menos operações e menos buscas). Os discos rígidos têm melhor desempenho quando um pequeno número de operações grandes é solicitado, enquanto os aplicativos tendem a precisar de um grande número de operações pequenas. Outra otimização clara é que o sistema operacional também pode remover tudo, exceto a última gravação, quando o mesmo bloco é gravado várias vezes em um curto período de tempo, ou até mesmo remover algumas gravações todas juntas, se o arquivo afetado tiver sido removido nesse meio tempo.

Essas gravações assíncronas são feitas após o writeretorno da chamada do sistema. Essa é a segunda e mais visível vantagem do usuário. Gravações assíncronas aceleram os aplicativos, pois eles são livres para continuar seu trabalho sem aguardar que os dados estejam realmente em disco. O mesmo tipo de buffer / cache também é implementado para operações de leitura em que blocos de leitura recentes ou frequentemente são retidos na memória em vez de serem lidos novamente a partir do disco.

Não há risco de falha na gravação devido a um erro de E / S?

Não necessariamente. Isso depende do sistema de arquivos usado e da redundância em vigor. Um erro de E / S pode ser inofensivo se os dados puderem ser salvos em outro local. Sistemas de arquivos modernos como o ZFS recuperam automaticamente os blocos de disco defeituosos. Observe também que os erros de E / S não travam sistemas operacionais modernos. Se eles ocorrerem durante o acesso aos dados, eles são simplesmente relatados ao aplicativo afetado. Se eles ocorrerem durante o acesso aos metadados estruturais e colocarem o sistema de arquivos em risco, poderá ser remontado somente leitura ou tornado inacessível.

Também há um pequeno risco de perda de dados no caso de uma falha do sistema operacional, falta de energia ou falha de hardware. Esse é o motivo pelo qual aplicativos que precisam ter 100% de certeza de que os dados estão no disco (por exemplo, bancos de dados / aplicativos financeiros) estão fazendo gravações síncronas menos eficientes, mas mais seguras. Para reduzir o impacto no desempenho, muitos aplicativos ainda usam gravações assíncronas, mas eventualmente os sincronizam quando o usuário salva explicitamente um arquivo (por exemplo, vim, processadores de texto).

Por outro lado, uma grande maioria de usuários e aplicativos não precisa nem se importa com a segurança que as gravações síncronas fornecem. Se houver uma falha ou falta de energia, o único risco é perder na pior dos casos os últimos 30 segundos de dados. A menos que exista uma transação financeira envolvida ou algo semelhante que implique um custo muito superior a 30 segundos, o enorme ganho no desempenho (que não é uma ilusão, mas muito real) gravações assíncronas está permitindo superar em grande parte o risco.

Por fim, gravações síncronas não são suficientes para proteger os dados gravados. Se seu aplicativo realmente precisar garantir que seus dados não sejam perdidos, aconteça o que acontecer, a replicação de dados em vários discos e em várias localizações geográficas deve ser implementada para resistir a desastres como incêndio, inundação etc.


Além do custo, considere se algo foi feito que depende dos dados que foram salvos. Se estou digitando meu romance, salvando sequencialmente, e um corte de energia significa que perco 30 segundos de trabalho, independentemente do valor desses 30 segundos, pelo menos, me recupero para um estado que realmente ocorreu durante o processo de digitação , e posso reiniciar a partir daí. Por outro lado, se eu clicar em "salvar" e cruzar algo da minha lista de tarefas de papel na minha mesa, quando eu me recuperar, tenho uma inconsistência entre meu disco rígido e meu papel. Este é geralmente mais difícil para retomar a partir ...
Steve Jessop

11
... então, como um usuário normal, talvez eu queira sincronizar o sistema de arquivos antes de cruzar "terminar de escrever meu romance" da minha lista de tarefas, para ter certeza de que não acho que fiz algo que realmente falhe. E é por isso que bancos de dados e similares precisam de gravações síncronas: mesmo que percam dados, eles absolutamente devem manter a consistência.
21715 Steve Stoplin

11
@SteveJessop Concordo com seu exemplo, mas não esperaria que um usuário casual fosse sincronizado manualmente. Se o editor usado para escrever o romance precioso não chamar fsync ou semelhante quando o documento for salvo, é um bug a ser corrigido, por exemplo, bugs.launchpad.net/ubuntu/+source/libreoffice/+bug/817326 . Eu usaria o vi (vim) para escrever o meu, o vim chama fsync em save por padrão.
Jlliagre

59

Ele simplesmente fornece uma ilusão de velocidade para programas que não precisam esperar até que a gravação seja concluída. Monte seus sistemas de arquivos no modo de sincronização (que fornece suas gravações instantâneas) e veja como tudo está lento.

Às vezes, os arquivos existem apenas temporariamente ... um programa faz um pouco de trabalho e exclui o arquivo logo após o término do trabalho. Se você atrasou essas gravações, talvez nunca as tenha escrito antes.

Não há risco de falha na gravação devido a um erro de E / S?

Ah, absolutamente. Nesse caso, geralmente todo o sistema de arquivos entra no modo somente leitura e tudo é horrível. Mas isso raramente acontece, não faz sentido perder as vantagens de desempenho em geral.


Certos controladores de disco rígido têm bateria reserva, portanto, no caso de uma falta de energia, os dados não confirmados são preservados no controlador até que a energia seja restaurada. Isso permite o uso em aplicativos de banco de dados onde a perda de dados não é uma opção.
21815 strattonn

O Linux armazena dados ainda não gravados na RAM, não no HDD. O HDD também possui cache próprio.
Barafu Albino

Seria bastante conveniente se qualquer arquivo aberto por um processo fosse sincronizado quando o processo fosse fechado. Isso não afetaria o processo em si, mas seria simplificar shell scripts e similares (que agora têm de sincronizar um sistema de arquivos inteiro)
MSalters

14
Isso é mais que uma ilusão. Gravações assíncronas melhoram o desempenho geral dos aplicativos.
Jlliagre

4
@frostschutz: Além dos arquivos existentes apenas temporariamente, também há o fato de que algumas áreas dos arquivos são reescritas repetidamente.
Matthieu M.

26

A E / S em buffer e assíncrona estava em uso antes do Linux e mesmo antes do Unix. O Unix tinha, e todos os seus rebentos também.

Aqui está o que Ritchie e Thompson escreveram em seu artigo do CACM The UNIX Time-Sharing System :

Para o usuário, a leitura e a gravação de arquivos parecem ser síncronas e sem buffer. Isso ocorre imediatamente após o retorno de uma chamada de leitura, os dados estão disponíveis e, inversamente, após uma gravação, o espaço de trabalho do usuário pode ser reutilizado. De fato, o sistema mantém um mecanismo de buffer bastante complicado que reduz bastante o número de operações de E / S necessárias para acessar um arquivo.


Na sua pergunta, você também escreveu:

Não há risco de falha na gravação devido a um erro de E / S?

Sim, a gravação pode falhar e o programa talvez nunca saiba disso. Embora nunca seja uma coisa boa, os efeitos disso podem ser minimizados nos casos em que um erro de E / S gera pânico no sistema (em alguns SOs isso é configurável - em vez de entrar em pânico, o sistema pode continuar em execução, mas o sistema de arquivos afetado é somente leitura desmontada ou montada). Os usuários podem ser notificados de que os dados nesse sistema de arquivos são suspeitos. E uma unidade de disco pode ser monitorada proativamente para ver se sua lista de defeitos crescentes está aumentando rapidamente, o que é uma indicação de que a unidade está falhando.

O BSD adicionou a fsyncchamada do sistema para que um programa pudesse ter certeza de que seus dados de arquivo foram completamente gravados no disco antes de continuar, e os sistemas Unix subsequentes forneceram opções para realizar gravações síncronas. O GNU dd tem uma opção conv=fsyncpara garantir que todos os dados foram gravados antes da saída do comando. É útil ao gravar em drives flash removíveis lentos, onde os dados armazenados em buffer podem levar alguns minutos para serem gravados.

Outra fonte de corrupção de arquivos é o desligamento repentino do sistema, por exemplo, por perda de energia. Praticamente todos os sistemas atuais suportam uma flag limpa / suja em seus sistemas de arquivos. O sinalizador é definido como limpo quando não há mais dados a serem gravados e o sistema de arquivos está prestes a ser desmontado, normalmente durante o desligamento do sistema ou por chamada manual umount. Os sistemas geralmente serão executados fsckapós a reinicialização se detectar que os sistemas de arquivos não foram desligados corretamente.


Suponha que copiamos músicas do disco rígido para uma unidade externa. Pode acontecer que a unidade externa esteja corrompida e a gravação falhe. Isso não faria com que um programa fosse executado com dados incorretos. E parece um exagero entrar em pânico em uma E / S com falha em um dispositivo externo.
Marmistrz

Bom ponto. Vou modificar minha resposta.
precisa saber é o seguinte

15

Muitas boas respostas, mas deixe-me acrescentar mais uma coisa ... Lembre-se de que o Unix é um sistema com vários processos e multiusuários; portanto, muitos usuários potencialmente estariam tentando realizar operações de arquivo (especialmente gravações) no (quase) mesmo tempo. Com discos rígidos lentos antigos - talvez montados na rede - isso não apenas levaria tempo (pelo qual os programas basicamente travam e os usuários precisam esperar), mas causa muito movimento da cabeça de leitura / gravação do disco para frente e para trás.

Em vez disso, os arquivos que aguardavam gravação foram mantidos na memória por um tempo e classificados depois de onde deveriam terminar no disco ... e quando o buffer estava cheio - ou o daemon de sincronização de disco aguardou o número necessário de segundos (acho que geralmente eram cerca de 30 segundos) - todo o buffer foi gravado no disco "em ordem", com a cabeça de gravação apenas tendo que fazer um movimento contínuo de varredura, gravando os arquivos no disco como foi ... em vez de pular por todo o lugar.

De acordo com os discos rápidos de hoje - para não mencionar os dispositivos de estado sólido - o ganho é muito menor ... espeicamente em um sistema linux doméstico, onde há apenas um usuário trabalhando por vez e apenas com alguns programas.

De qualquer forma, a combinação de antecipar leituras lendo (no cache / buffer) mais do que foi solicitado - e classificando dados aguardando para serem gravados, para que pudessem ser gravados em "um movimento" - foi realmente uma boa ideia tempo, especialmente em sistemas com muita leitura e escrita por muitos usuários.


2
O XFS nem decide onde colocar os dados até a gravação. A alocação atrasada fornece ao alocador muito mais informações para basear suas decisões. Quando um arquivo está sendo gravado pela primeira vez, não há como saber se ele será um arquivo de 4k ou um arquivo de 1G e ainda em crescimento. Se houver 10 G de espaço livre contíguo em algum lugar, colocar o arquivo 4k no início não é bom. Colocar o arquivo grande no início de um grande espaço livre reduz a fragmentação.
22615 Peter Cordes

13

Não é específico para o Linux e é chamado de cache de página (que o Linux faz muito bem). Veja também http://linuxatemyram.com/ ; portanto, se um arquivo for gravado, leia novamente alguns segundos depois, muitas vezes nenhuma E / S de disco é necessária.

A principal vantagem é que, em muitos sistemas, há muita RAM e algumas podem ser usadas como cache pelo kernel. Portanto, algumas operações de arquivos podem tirar proveito desse cache. Além disso, o tempo de E / S do disco é muito mais lento (normalmente milhares de vezes para SDD e quase um milhão de vezes mais lento para discos rígidos mecânicos) que a RAM.

O código do aplicativo pode dar dicas sobre esse cache: veja, por exemplo, posix_fadvise (2) e madvise (2)


8

Os pratos giratórios são mais lentos que a RAM. Usamos o cache de leituras / gravações para 'ocultar' esse fato.

O aspecto útil da gravação de E / S é que ela não exige que a E / S de disco aconteça imediatamente - ao contrário de uma leitura, na qual você não pode retornar dados ao usuário até que a leitura seja concluída no disco.

Assim, as gravações operam com uma restrição de tempo flexível - desde que nossa taxa de transferência sustentada não exceda a do nosso disco, podemos ocultar muitas das penalidades de desempenho em um cache de gravação.

E precisamos escrever em cache - os discos giratórios são muito lentos comparativamente. Mas, para fazer isso, os tipos modernos de RAID têm uma penalidade significativa na operação.

Um RAID 6, por exemplo, para concluir uma E / S de gravação deve:

  • Ler bloco de atualização
  • ler paridade1
  • paridade de leitura 2
  • escreva novo bloco
  • paridade de gravação 1
  • paridade de gravação 2

Assim, cada gravação é na verdade 6 operações de E / S - e, particularmente, quando você tem discos lentos como grandes unidades SATA, isso fica extremamente caro.

Mas há uma solução fácil e agradável - escreva coalescente. Se você pode criar uma gravação de 'faixa completa' em um buffer, não precisa ler a paridade do disco - você pode calculá-la com base no que tem na memória.

É muito desejável fazer isso, porque você não tem mais amplificação de gravação. Na verdade, você pode acabar com uma penalidade de gravação menor que o RAID 1 + 0.

Considerar:

Eixos RAID 6, 8 + 2 - 10.

8 blocos de dados consecutivos para gravação - calcule a paridade no cache e grave um bloco em cada disco. 10 gravações por 8, significa uma penalidade de gravação de 1,25. 10 discos de RAID 1 + 0 ainda têm uma penalidade de gravação de 2 (porque você precisa gravar em cada subespelho). Portanto, nesse cenário, você pode realmente fazer o RAID 6 ter um desempenho melhor que o RAID1 + 0. No uso no mundo real, você obtém um pouco mais de um perfil de IO misto.

Portanto, o cache de gravação faz uma enorme diferença no desempenho percebido dos conjuntos RAID - você pode gravar na velocidade da RAM e tem uma penalidade baixa de gravação - melhorando o rendimento sustentado, se o fizer.

Caso contrário, você sofre o desempenho lento do SATA, mas multiplique por 6 e adicione alguma contenção. Seu SATA RAID-6 de 10 vias sem cache de gravação seria um pouco mais rápido que uma única unidade sem RAID ... mas não muito.

Você se arrisca - como observa - a perda de energia significa perda de dados. Você pode atenuar isso realizando ciclos de liberação de cache, backup de bateria do cache ou usando SSD ou outros caches não voláteis.


7

Nenhuma das outras respostas mencionadas atrasou a alocação . Todos os XFS, ext4, BTRFS e ZFS o utilizam. O XFS está usando-o desde antes da ext4, então vou usá-lo como exemplo:

O XFS nem decide onde colocar os dados até a gravação. A alocação atrasada fornece ao alocador muito mais informações para basear suas decisões. Quando um arquivo está sendo gravado pela primeira vez, não há como saber se ele será um arquivo de 4k ou um arquivo de 1G e ainda em crescimento. Se houver 10 G de espaço livre contíguo em algum lugar, colocar o arquivo 4k no início não é bom. Colocar o arquivo grande no início de um grande espaço livre reduz a fragmentação.


4

Todas as outras respostas aqui estão no mínimo corretas para o caso normal, e eu recomendaria a leitura de qualquer uma delas antes da minha, mas você mencionou dd e dd tem um caso de uso típico que pode não envolver cache de gravação. O cache de gravação é implementado principalmente no nível do sistema de arquivos. Os dispositivos brutos normalmente não fazem cache de gravação (vários drivers de dispositivo, como raid ou lvm, são outra bola de cera). Como o dd é frequentemente usado com dispositivos de bloco bruto, ele fornece as opções bs e relacionadas para permitir gravações grandes para melhor desempenho em dispositivos brutos. Isso não é tão útil quando os dois pontos de extremidade são arquivos regulares (embora gravações grandes usem menos chamadas do sistema nesse caso). O outro local comum em que isso é particularmente visível é o pacote mtools, que é uma implementação do sistema de arquivos fatiados do espaço do usuário. o uso de mtools com uma unidade de disquete sempre parece incrivelmente lento, pois as ferramentas são completamente síncronas e as unidades de disquete são incrivelmente lentas. Montar o disquete e usar o sistema de arquivos com gordura do kernel é muito mais responsivo, exceto por umount que é síncrono (e muito importante para que seja assim, para evitar a perda de dados, especialmente para dispositivos removíveis como disquetes). Existem apenas alguns outros programas que eu sei que são usados ​​regularmente com dispositivos brutos, como bancos de dados especialmente configurados (que implementam seu próprio cache de gravação), tar e dispositivos especiais e ferramentas de sistema de arquivos como chdsk, mkfs e mt. Montar o disquete e usar o sistema de arquivos com gordura do kernel é muito mais responsivo, exceto por umount que é síncrono (e muito importante para que seja assim, para evitar a perda de dados, especialmente para dispositivos removíveis como disquetes). Existem apenas alguns outros programas que eu sei que são usados ​​regularmente com dispositivos brutos, como bancos de dados especialmente configurados (que implementam seu próprio cache de gravação), tar e dispositivos especiais e ferramentas de sistema de arquivos como chdsk, mkfs e mt. Montar o disquete e usar o sistema de arquivos com gordura do kernel é muito mais responsivo, exceto por umount que é síncrono (e muito importante para que seja assim, para evitar a perda de dados, especialmente para dispositivos removíveis como disquetes). Existem apenas alguns outros programas que eu sei que são usados ​​regularmente com dispositivos brutos, como bancos de dados especialmente configurados (que implementam seu próprio cache de gravação), tar e dispositivos especiais e ferramentas de sistema de arquivos como chdsk, mkfs e mt.


4
Os dispositivos de bloco Linux leem / gravam o cache da página por padrão. Você precisa usar O_DIRECTse quiser ignorar o cache. dd oflag=direct. IIRC, algumas unidades padronizam o direcionamento de E / S em dispositivos de bloco. (E exigem leitura / escrita de blocos alinhados, que o Linux não porque ele está apenas escrevendo o pagecache de qualquer maneira.)
Peter Cordes

3

A filosofia é insegura por padrão.

Existem duas estratégias razoáveis ​​e óbvias possíveis: liberar gravações no disco imediatamente ou atrasar a gravação. O UNIX escolheu historicamente o último. Portanto, obtenha segurança, você precisa ligar fsyncdepois.

No entanto, você pode especificar a segurança antecipadamente montando um dispositivo com a opção syncou por arquivo, abrindo-os com O_SYNC.

Lembre-se de que o UNIX foi projetado para especialistas em computadores. "Seguro por padrão" não foi considerado. Segurança significa E / S mais lenta, e esses sistemas antigos realmente tinham E / S lenta, tornando o preço alto. Infelizmente, nem o UNIX nem o Linux mudaram para o padrão de segurança, embora essa seja uma alteração sem interrupção.


6
Uma grande maioria dos aplicativos e usuários não precisa nem se importa com a segurança que as gravações síncronas forneceriam. Se houver uma falha ou queda de energia, você corre o risco de perder os últimos 30 segundos de dados. Isso é bom para a maioria das pessoas, a menos que haja uma transação financeira envolvida ou algo semelhante que custe mais de 30 segundos do nosso tempo. A padronização de E / Ss síncronas implicaria em todos os aplicativos que têm como alvo a usabilidade para ter O_NOSYNC definido.
Jlliagre

2

Ele comercializa uma pequena quantidade de confiabilidade para um grande aumento na taxa de transferência.

Suponha, por exemplo, um programa de compactação de vídeo. Com gravação atrasada ("write back"):

  1. gastar 10ms comprimir quadro
  2. emitir quadro de gravação no disco
  3. aguarde 10ms para que o disco reconheça a gravação concluída
  4. GOTO 1

Versus

  1. gastar 10ms comprimir quadro
  2. emitir quadro de gravação no disco (concluído em segundo plano)
  3. GOTO 1

A segunda versão aparece duas vezes mais rápido porque pode usar a CPU e o disco ao mesmo tempo, enquanto a primeira versão está sempre aguardando uma ou outra.

Geralmente, você deseja write-back para operações de streaming e operações de arquivos em massa e write-through para bancos de dados e aplicativos semelhantes a bancos de dados.


1

Em muitos aplicativos, os dispositivos de armazenamento estarão ocupados intermitentemente na leitura de dados. Se um sistema sempre puder adiar gravações até um momento em que o dispositivo de armazenamento não esteja ocupado lendo dados, do ponto de vista de um aplicativo, as gravações levarão tempo zero para serem concluídas. As únicas situações em que as gravações não seriam instantâneas seriam quando:

  1. Os buffers de gravação são preenchidos até o ponto em que nenhuma solicitação de gravação adiada pode ser aceita até que as gravações sejam concluídas.

  2. É necessário desligar ou remover o dispositivo para o qual as gravações estão pendentes.

  3. Um aplicativo solicita especificamente a confirmação de que uma gravação foi realmente concluída.

De fato, é apenas por causa dos requisitos acima que as gravações precisam realmente ocorrer. Por outro lado, geralmente não há razão para não realizar gravações pendentes nos momentos em que um dispositivo estaria ocioso; portanto, muitos sistemas as executam nesse momento.


0

Há também o seguinte:

Escreva "Oi, Joe Moe"
é mais rápido que:
Escreva "Oi",
escreva "Joe"
Escreva "Moe"

E também:

Escreva "Oi, tudo bem?"
é mais rápido que:
Escreva "Oi, e aí?"
Exclua essa
gravação "Olá, tudo bem?"
Exclua essa
gravação "Olá, tudo bem?"

É melhor que as modificações e a agregação ocorram na RAM do que no disco. As gravações em disco em lote liberam os desenvolvedores de aplicativos de tais preocupações.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.