sincronizando arquivos grandes FreeBSD

6

Estou com dificuldade em entender isso.

Minha configuração de teste tem um script de shell chamando continuamente 'ls -la' em um arquivo 1G e imprimindo o tempo desde a última vez que ele foi executado. Eu então executo um programa para modificar partes do arquivo e sincronizá-lo com o disco.

Não importa se eu chamo o fsync, ou o sistema faz uma sincronização, ou mesmo se eu uso o pwrite para escrever as partes diferentes (ainda testando esse bit), quando a sincronização acontece o 'ls -la' irá congelar durante todo o tempo da sincronização - entre 7-40 segundos (dependendo da dispersão das modificações).

Se eu usar o msync para sincronizar partes de uma vez, ou tentar fsync com mais frequência enquanto escrevo, a duração será muito maior (talvez 10x o tempo, mas ainda mais dependendo da frequência com que o faço). A msync acima apenas grava em 16KB / Transaction, mesmo que as páginas sejam sequenciais.

Eu li em algum lugar que o OpenBSD implementou 'gravações parciais de arquivos' ou algo assim. Eu não consigo lembrar agora.

Existe alguma maneira que eu possa fazer algo similar com a eficiência do fsync sem que os arquivos sejam bloqueados o tempo todo?

Na verdade, o problema 'A' (para o qual eu acho que 'B' é a solução) é simplesmente trabalhar com arquivos grandes e 'incentivá-los' a serem gravados em disco para que a memória possa ser liberada rapidamente se precisa ser. Simplesmente omitir NO_SYNC não é bom, pois as mudanças ocorrerão quase ao mesmo tempo, causando esta situação. Nenhuma das outras opções de tratamento parece ajudar também. Ou seja, se eu não sincronizar, as páginas parecem ficar em volta até que eu fique sem memória, onde de repente elas começarão a trocar (embora apenas 16KB / Transaction e um MB / s muito baixo).

Como você trabalha com arquivos grandes no FreeBSD?

SOLUÇÃO:

Descobri que, ajustando meus fragmentos do msync e usando o MS_ASYNC em vez do MS_SYNC na chamada do msync, posso obter o desempenho que quero, enquanto ainda permitindo que outros processos abram e mmap / leiam o arquivo.

    
por Haru 16.10.2012 / 02:48

3 respostas

1

O freeBSD usará memória livre para armazenar em cache a E / S do disco, assim como outros UNIXes. Em um sistema com muita memória livre e poucos usuários, arquivos realmente grandes podem ser completamente estacionados na memória. De modo que parece que mais memória é usada.

close() ( fclose() ) e fsync ( fflush() ) são as únicas chamadas de sistema que forçam o sistema operacional para gravar o cache. Isto é verdade apenas se nenhum outro processo tiver o arquivo aberto. O FreeBSD não possui fdatasync , que apenas grava dados em cache, mas não metadados no disco físico.

Do BSD 4.4 em Você pode rastrear paginação e cache de arquivos com mincore() syscall.

Então, você precisa fflush após cada poucas gravações.

Jogue com parms de cache de disco:

http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/configtuning-disk.html
    
por 16.10.2012 / 03:02
1

Você está resolvendo o problema (monitorando o estado do arquivo) completamente errado. Em vez de verificar periodicamente o estado do arquivo (e executar problemas de simultaneidade de E / S de vez em quando), seu programa deve simplesmente solicitar que o kernel seja notificado quando um determinado arquivo (ou coleção de arquivos) for alterado.

Mecanismos para fazer isso existem em todos os Unixes modernos, mas, infelizmente, eles não são os mesmos ...

Na família BSD de Unixes, isso é feito com kqueue / kevent . No Linux há inotify. No Solaris há poll e / dev / poll.

Existem bibliotecas de plataforma cruzada, que ocultam os detalhes da implementação do SO e fornecem API portável. Se você precisa de portabilidade, procure o File Alterations Monitor ou seu subconjunto mais moderno chamado gamin (portado em / usr / ports / devel / gamin). Se a sua aplicação é apenas para o BSD (Free), você pode usar o kqueue / kevent diretamente.

    
por 19.10.2012 / 18:09
0

link

Explica seu problema claramente. A sincronização libera buffers sujos (cache atualizado) para o disco periodicamente. Esses flushes "periódicos" são o que você quer evitar. Veja o que o sysctl pode fazer pelo seu problema.

    
por 17.10.2012 / 04:48

Tags