A maior parte da maneira sem efeitos colaterais de arquivar um arquivo grande enquanto ele está sendo modificado

1

Estou cuidando de um aplicativo que gera uma grande quantidade de dados em um arquivo de log (cerca de 5G por dia) em um servidor Red Hat. Esse processo é executado durante 24 horas durante a semana, portanto, não há nenhum ponto no dia em que o arquivo não está sendo modificado, embora as informações adicionadas durante a meia-noite não sejam particularmente importantes, por isso é OK se perdermos digamos alguns segundos de dados durante esse período.

Para criar arquivos "seguros" do arquivo de log diariamente, criei um script que faz o seguinte em algum momento no início da manhã:

  • faz uma cópia do arquivo para uma pasta local
  • truncar o arquivo "ativo"
  • tar + compacta a cópia
  • mova o tar.gz da cópia para o nosso espaço de arquivo

Aqui está o script em si, caso haja problemas evidentes:

DF=$(date +"%Y%m%d_%H%M%S")
TARGET="fixdata-logs-$DF"
cp -r ./fixdata/logs $TARGET

#Truncate the original log file
find ./fixdata/logs -name '*.log' -exec sh -c 'cat /dev/null >| {}' \;

#Zip the log files
tar -zcvf $TARGET.tar.gz $TARGET

#Delete the labelled copy
rm -rf $TARGET

#Archive files older tha 3 days
find . -type f -mtime +3 -name \*.gz -exec mv {} $ARCHIVE_DIR \;

(Eu entendo que alguns dados podem ser perdidos, mas esse script é executado em um momento em que alguns segundos de perda de dados não são importantes.)

O problema é que, durante esse período, o aplicativo frequentemente relata erros relacionados aos recursos do sistema. Por exemplo, o monitor de pulsação de sua fila geralmente falha ao produzir pulsações regulares. É claro que esse processo de copiar > tar.gz- > está causando um impacto suficiente no IO do servidor que afeta o comportamento do aplicativo.

Como posso reduzir o impacto desse script? O tempo para terminar não é importante - se uma solução demorar mais, mas não causar erros de aplicação, então é preferível que algo seja rápido. Existem outras abordagens que devo considerar?

Para completar, eu considerei o seguinte, mas tenho dúvidas:

  • Ignore a parte de cópia e o tar diretamente: Mas estou preocupado que o tar tenha problemas se o arquivo estiver sendo modificado enquanto estiver ocupado.
  • Copie primeiro para a pasta de arquivos e, em seguida, tar - talvez, se a compactação for feita em um disco diferente, o impacto de IO seja menor? Estou preocupado que o espaço de arquivo que usamos não seja adequado para operações de disco de entrada / saída como a compactação, pois não acho que seja um disco de acesso aleatório tradicional. Eu também não tenho certeza se uma cópia para um disco físico diferente não vai piorar as coisas, como eu teria pensado que o sistema operacional tem alguma maneira inteligente de fazer uma cópia local sem ler fisicamente todos os bytes do arquivo. Infelizmente minhas habilidades * nix não estão ajudando aqui.
  • Aguarde até o final de semana: infelizmente, o espaço em disco no servidor não é suficiente para conter os dados de uma semana antes de arquivá-los. É claro que posso pedir para aumentá-lo, mas primeiro quero ver se existem soluções mais sensatas.
por notdazedbutconfused 08.09.2015 / 09:42

2 respostas

1

Você pode fazer isso com significativamente redução da carga de E / S, não fazendo a cópia + truncamento. Em vez disso, renomeie o arquivo e, se o processo contiver o descritor de arquivo de log aberto, faça o que for necessário para fazer com que ele recicle seus descritores de log (normalmente, enviar um HUP é a maneira canônica de fazer isso). Se o programa ainda não tiver esse recurso, faça um patch dele.

Ao fazer isso, você não terá a sobrecarga de E / S de uma cópia na mesma mídia (que é uma leitura + gravação simultâneas) e, em seguida, o truncamento (que pode ou não ser uma carga significativa, dependendo seu sistema de arquivos), e então a leitura para tar / compress e a carga de escrita para fazer o arquivo.

Depois de renomear os arquivos de log, você pode tar / compress / whatever em seu tempo livre. Para reduzir ainda mais a carga de E / S, considere fazer o lado de gravação do tar / compress diretamente no armazenamento de arquivamento - embora seu armazenamento em arquivamento possa não ser um dispositivo típico de acesso aleatório, ele ainda precisará de um fluxo direto de dados que estão sendo compactados em tempo real (até mesmo o S3 pode fazer isso, com a ferramenta CLI certa).

A outra coisa a considerar, ortogonal ao acima, é usar ionice . Ao executar um programa como ionice -c 3 <command> , você descarta a prioridade de E / S do processo para "somente ocioso" - ou seja, se houver alguma coisa mais no sistema que deseja executar / O seu programa será colidido. Essa é uma boa idéia, mas pode ser ignorada se você tiver um sistema de E / S pesado (seu programa pode levar aaaaages para ser concluído, pois raramente recebe tempo de E / S) . Nos casos em que você já está fazendo uma quantidade excessiva de E / S desnecessária, tornar a prioridade "somente ociosa" tornará o problema muito pior.

Também suspeito strongmente que o agendamento apenas ocioso não faça o que ele diz na lata; Vi pequenas lentidões no desempenho em outros processos ("melhor esforço" programado) quando programas "somente ociosos" estão em execução, em comparação a quando o processo "somente ocioso" não está em execução. Eu suspeito que isso acontece porque quando um programa pede E / S enquanto o processo "somente ocioso" está no meio de uma operação de E / S, há um atraso até que a E / S seja feita antes do "melhor esforço" A operação de E / S do processo pode ser iniciada. Ou seja, ainda é muito melhor do que se o processo "apenas ocioso" estivesse sendo executado com prioridade "melhor esforço", mas não é a correção maravilhosa - tudo o que pode parecer à primeira vista.

    
por 08.09.2015 / 11:11
-1

Dê uma olhada no utilitário linux logrotate que está disponível em rhel, ele tem compressão, copytruncate e várias outras opções e também lida com arquivos de log que estão em uso pelos aplicativos como você tem. Você também pode tentar usar um disco ssd e copiar os dados para o que deve ser o mais rápido e, embora ele ainda use cpu, o io para um disco lento seria eliminado, desde que você não usasse o usb.

    
por 08.09.2015 / 11:00