Com que frequência executar scrub em um pool ZFS VPS
O scrub verifica todos os blocos alocados, mas um pool VPS em disco único não pode reparar danos. Veja uma frequência prática e suas limitações.
O que um scrub do ZFS faz de facto
Um scrub do ZFS lê todos os blocos alocados no pool, recalcula o respetivo checksum e compara o resultado com o checksum armazenado no ponteiro de bloco pai. Quando os dois não coincidem, o ZFS repara o bloco usando a redundância disponível no pool. Nenhuma outra operação do ZFS faz este trabalho. As leituras normais verificam apenas os blocos que são efetivamente acedidos. Por isso, um ficheiro que não é aberto há dois anos permanece por verificar até um scrub o ler.
Um scrub não é fsck, a operação de reparação offline de que outros sistemas de ficheiros precisam. Não existe uma fase de reparação estrutural, porque o ZFS nunca deixa o formato em disco num estado inconsistente: cada escrita é feita numa localização nova e o uberblock, o ponteiro raiz do pool, só é atualizado no fim. Um scrub também não lê o dispositivo inteiro. Lê apenas os blocos alocados. Por isso, um pool quase vazio pode ser processado em minutos, enquanto o mesmo pool com 80% de utilização demora muito mais tempo.
O scrub é executado com a prioridade de I/O mais baixa disponível no ZFS. No Linux, zfs_vdev_scrub_max_active tem o valor predefinido 2, pelo que há no máximo duas leituras de scrub em curso por vdev (dispositivo virtual, o grupo de discos que o ZFS trata como uma unidade). zfs_scrub_min_time_ms tem o valor predefinido 750. Este é o tempo mínimo que a thread de sincronização dedica ao trabalho do scrub entre flushes de grupos de transações, os commits periódicos nos quais o ZFS agrupa as escritas. Num sistema inativo, o scrub utiliza todo o disco. Sob carga, cede recursos. Num pool com um ou dois dispositivos, não há para onde ceder esses recursos. Por isso, o agendamento é mais importante neste caso do que num chassis de grandes dimensões com sessenta discos.
Por que fazer scrub em um pool que não consegue se reparar?
Esta é a frase que determina todo o resto num pool pequeno. Sem redundância, um scrub deteta corrupção, mas não consegue corrigi-la. Um único disco virtual numa VPS é um pool sem mirror e sem paridade. O ZFS lê o bloco inválido, falha a verificação da soma de verificação, contabiliza-o na coluna CKSUM, identifica o ficheiro e para aí, porque não existe uma segunda cópia a partir da qual possa reconstruí-lo.
Há duas exceções parciais que vale a pena conhecer. Por predefinição, o ZFS armazena uma cópia adicional dos metadados (redundant_metadata=all), escrita numa região diferente do dispositivo. Assim, um scrub pode reparar uma entrada de diretório ou um ponteiro de bloco danificado mesmo num pool com um único dispositivo. Além disso, um dataset com copies=2 mantém duas cópias dos seus blocos de dados, ao dobro do custo de espaço. Nenhuma das duas opções ajuda se o dispositivo deixar de estar disponível. A documentação da propriedade copies alerta precisamente para isto: não crie um pool striped, defina copies=2 e acredite que tem redundância.
Num pool com um único dispositivo, o scrub oferece-lhe uma coisa: notificação antecipada e precisa. Transforma a corrupção silenciosa num nome de ficheiro em zpool status -v enquanto o seu backup ainda contém uma versão válida desse ficheiro. Isto é um argumento a favor dos backups, não contra os scrubs. Se ainda não distinguiu uma imagem de um ponto no tempo de uma cópia real fora do servidor, comece por por que um snapshot de uma VPS não é um backup, porque o resultado de um scrub só é útil se existir outro local com uma cópia intacta.
Um scrub que não encontra nada também é um resultado. Indica-lhe que os dados que está prestes a utilizar são íntegros. É isso que precisa de saber antes de uma restauração ou migração.
Com que frequência deve executar um scrub num pequeno pool VPS?
Mensalmente é o padrão correto e é o intervalo assumido pelos pacotes. Debian e Ubuntu disponibilizam um cron job que executa o scrub de pools saudáveis no segundo domingo de cada mês. O sistema periodic do FreeBSD usa um limite em dias, e daily_scrub_zfs_default_threshold tem o valor predefinido de 35, que o manual descreve como cinco semanas.
Executar o scrub semanalmente num pequeno pool ocupado normalmente custa mais do que compensa. Com um ou dois dispositivos, o scrub compete pela mesma fila que a aplicação, e não existe um dispositivo livre para absorver essa carga. Num VPS, o limite de I/O é finito. Por isso, as leituras consumidas pelo scrub são leituras que a base de dados não pode utilizar. Em contrapartida, o scrub semanal fornece, no máximo, três semanas de aviso antecipado sobre uma falha que, de qualquer forma, não pode reparar. Essa troca só faz sentido quando o scrub é barato.
Meça o tempo e decida depois. Execute um scrub manualmente e acompanhe quanto tempo demora.
- Execute
sudo zpool scrub tanknuma noite com pouca carga e registe o tempo total a partir dezpool status. - Se terminar claramente em menos de uma hora e o servidor ficar inativo durante a noite, a execução semanal é aceitável.
- Se demorar muitas horas enquanto o pool estiver a servir tráfego, mantenha a frequência mensal e deixe o job fornecido pelo pacote tratar da execução.
- Volte a medir sempre que o pool crescer de forma significativa, porque a duração do scrub acompanha os dados alocados, não a capacidade do disco.
Independentemente da opção escolhida, registe-a junto do restante trabalho recorrente do servidor. O scrub deve constar da mesma lista que as atualizações de pacotes e a rotação de logs: consulte uma lista de verificação mensal para manutenção de servidores Linux.
Iniciar, pausar e parar um scrub
sudo zpool scrub tank
sudo zpool status tankPausar e parar são operações diferentes. Escolher a opção errada pode custar horas de trabalho repetido.
sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank-p pausa o scrub. O estado e o progresso da pausa são sincronizados periodicamente no disco. Por isso, um scrub pausado mantém-se assim depois de uma exportação ou de um reboot: o pool volta a estar disponível com o scrub ainda pausado, à sua espera. Executar zpool scrub novamente retoma o scrub a partir do último checkpoint gravado no disco. -s para o scrub. O próximo scrub iniciado começa do princípio. Use -p quando precisar de libertar o disco durante uma hora. Use -s quando quiser eliminar o scrub.
Há mais dois flags que deve conhecer. -w espera que o scrub termine antes de devolver o controlo. É o comportamento adequado num script, para que o passo seguinte não comece demasiado cedo. -e verifica apenas os ficheiros com erros de dados conhecidos, conforme indicado por zpool status -v. Esta é a forma rápida de confirmar que um ficheiro restaurado a partir de um backup está agora íntegro.
O ZFS executa um scrub ou um resilver — a reconstrução que ocorre depois da substituição de um dispositivo — de cada vez por pool, porque ambas as operações exigem muitos recursos de I/O. Se um dispositivo estiver a fazer resilvering, o scrub espera pela sua vez.
Como interpretar o estado do zpool durante um scrub
Execute sudo zpool status tank e analise os seus próprios valores, em vez de os comparar com os de outra pessoa. Durante um scrub, a linha scan: apresenta o valor já verificado, o valor enviado para leitura, o total, o valor reparado, a percentagem concluída e uma estimativa do tempo restante.
Scanned é a fase de metadados: o ZFS percorre a árvore de blocos e recolhe os endereços que precisa de ler. Issued é a fase de dados: são as leituras efetivamente enviadas para o dispositivo, ordenadas pela posição no disco. O scrub ordenado é o motivo por existirem dois contadores, e issued é o contador que acompanha o progresso real. No início, scanned avança muito mais depressa do que issued, por isso a estimativa de tempo tem pouco significado. Avalie-a depois dos primeiros dez por cento.
Repaired contabiliza os bytes reescritos a partir de uma cópia válida. Num pool sem redundância, este valor mantém-se em zero, independentemente do que o scrub encontrar. Este é o ponto anterior expresso novamente como um valor que pode monitorizar.
Leia depois as colunas de cada dispositivo. READ e WRITE contabilizam os erros de I/O comunicados pelo próprio dispositivo. CKSUM contabiliza os blocos que falharam a verificação de checksum, e CKSUM é a coluna que um scrub serve para preencher. Um valor CKSUM diferente de zero num dispositivo que parece saudável é um erro real: os dados foram lidos, mas foram lidos com conteúdo incorreto.
A última linha apresenta o resultado. errors: No known data errors indica uma execução concluída com sucesso. Qualquer outro resultado significa que deve executar sudo zpool status -v tank, que apresenta a lista completa de erros de dados desde o último scrub concluído, incluindo os nomes dos ficheiros afetados. Restaure esses ficheiros a partir da cópia de segurança, execute sudo zpool clear tank para repor os contadores e execute novamente o scrub. Cada scrub concluído reconstrói essa lista, por isso um nome de ficheiro ausente depois de um scrub completo sem erros desapareceu efetivamente.
Qual trabalho periódico de scrub está configurado no seu servidor?
Não presuma que existe um, nem que existe apenas um. O mecanismo varia conforme a plataforma e o pacote. O formato do pool é idêntico em todo o lado, o que facilita esquecer que as ferramentas usadas com ele não são. A forma como o ZFS é distribuído no FreeBSD em comparação com o Linux é a diferença relevante aqui.
No FreeBSD, o trabalho pertence ao sistema periodic. Defina estas variáveis em /etc/periodic.conf:
daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"daily_scrub_zfs_pools é uma lista de nomes de pools separados por espaços. Se ficar vazia, todos os pools serão submetidos a scrub. daily_scrub_zfs_default_threshold é o número de dias entre scrubs quando não existe um limite específico para o pool. O manual indica 35 como valor predefinido. O trabalho diário é executado todos os dias, mas só inicia um scrub depois de o limite ser atingido.
No Linux, isso depende do pacote ZFS da sua distribuição. Alguns sistemas incluem os dois mecanismos ao mesmo tempo. Existem timers systemd por pool, zfs-scrub-monthly@tank.timer e zfs-scrub-weekly@tank.timer, ativados individualmente para cada pool. Debian e Ubuntu também incluem /etc/cron.d/zfsutils-linux, que executa um script para submeter todos os pools ONLINE a scrub no segundo domingo de cada mês. Verifique o que está configurado antes de adicionar qualquer coisa:
systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrubzpool history é a resposta correta, porque regista os scrubs que o pool realmente iniciou, com as respetivas datas. Dois scrubs por mês significam que os dois mecanismos estão ativos e que um deles deve ser removido. Para ativar um timer:
sudo systemctl enable --now zfs-scrub-monthly@tank.timerO espaço livre é mais importante do que qualquer parâmetro ajustável
A duração de um scrub num pool pequeno depende da quantidade de dados alocados e do grau de dispersão desses dados. Encher o pool piora ambos.
As orientações do OpenZFS recomendam manter mais de 10% de espaço livre no pool. Abaixo desse valor, os metaslabs, que são os blocos usados pelo alocador, começam a ultrapassar um limiar de 4% de espaço livre, e o alocador muda de first-fit para best-fit. O best-fit exige muito mais CPU. A latência de escrita aumenta, a fragmentação agrava-se e o scrub seguinte fica ainda mais lento, porque a mesma quantidade de dados passa a ser lida em blocos mais numerosos e menores.
Por isso, a primeira medida não é alterar um parâmetro. É apagar dados. Num sistema ZFS, os snapshots antigos são normalmente a causa principal, seguidos de imagens e camadas Docker que ninguém eliminou e pacotes do kernel deixados para trás pelas atualizações. Execute zfs list -o space antes de fazer qualquer outra alteração, porque este comando separa o espaço ocupado por snapshots do espaço ocupado por dados ativos.
Depois vêm os parâmetros, de forma resumida. No Linux, pode consultar os valores atuais:
cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_activeO FreeBSD expõe os mesmos parâmetros através de sysctl. Localize os parâmetros no seu sistema com sysctl -a | grep scrub. Aumentá-los faz o scrub terminar mais cedo, mas torna a aplicação mais lenta. Reduzi-los produz o efeito contrário. Num pool com um ou dois dispositivos, nenhuma configuração permite obter ambos os resultados, porque existe apenas uma fila para dividir. Um parâmetro raramente corrige um problema de arquitetura. Se um scrub mensal causar impacto, a conclusão correta é que o pool está demasiado cheio ou que o dispositivo é demasiado lento. Um parâmetro ajustável apenas desloca o problema.
O tempo do scrub é a sua previsão do resilver
Um resilver percorre os mesmos dados que um scrub: lê os blocos alocados, verifica-os e grava os blocos em falta no dispositivo de substituição. Portanto, o tempo que o scrub demora é a previsão mais fiável da duração de uma reconstrução e do período durante o qual o pool funcionará com redundância reduzida.
O ZFS agenda o trabalho de resilver de forma mais agressiva do que o trabalho de scrub, por isso uma reconstrução normalmente termina mais depressa do que um scrub do mesmo pool. Considere o tempo do scrub como um limite superior conservador. Se o scrub demora nove horas, planeie uma janela de reconstrução dessa ordem e tenha em conta que a falha de um segundo dispositivo durante essa janela provoca a perda do pool. Esse é o argumento prático a favor de pares espelhados em vez de um único grupo raidz largo, porque o raidz, o esquema de paridade que o ZFS usa em vez de RAID 5, reconstrói os dados lendo todos os dispositivos sobreviventes.
Num pool com um único dispositivo, não existe resilver. Se o dispositivo falhar, o pool também falha. O seu tempo de recuperação é o tempo de restauro, por isso meça o restauro. Um restauro que nunca executou não é um plano de recuperação.
O que muda quando aluga o disco
Numa VPS, o dispositivo de bloco é virtual. O hypervisor apresenta um volume e, por baixo dele, pode existir armazenamento NVMe local ou um volume de rede replicado com a sua própria paridade. Daqui resultam duas consequências para os scrubs.
Primeiro, a redundância da plataforma é invisível para o ZFS, que não a pode utilizar. Se a plataforma reparar um erro de suporte abaixo da VPS, o ZFS nunca vê o problema. Se a plataforma entregar um bloco incorreto, o ZFS deteta-o, mas não o consegue corrigir, porque a cópia correta está do outro lado desse limite.
Segundo, normalmente não é possível ler os dados SMART (self-monitoring, analysis and reporting technology) do dispositivo subjacente a um disco virtual. Por isso, os avisos antecipados de que depende o monitoramento da integridade do disco numa VPS podem não estar disponíveis. O contador CKSUM dos seus scrubs passa a ser o principal sinal sob o seu controlo.
Se quiser que o ZFS repare os erros, em vez de apenas os reportar, o pool precisa de mais de um dispositivo dentro da mesma instância. Essa é uma decisão de arquitetura, não uma questão de ajuste. Escolher uma VPS de armazenamento em vez de uma VPS comum proporciona a capacidade necessária, mas a existência de dois dispositivos independentes depende do plano. Execute lsblk e confirme antes de criar um mirror sobre aquilo que pode revelar-se como duas partições do mesmo volume. Alugamos servidores Linux e FreeBSD, não um appliance ZFS gerido. Por isso, a programação dos scrubs e os backups ficam a seu cargo. Esta é a contrapartida: controlo total do pool e responsabilidade total pela sua manutenção.
FAQ
Com que frequência devo fazer scrub num pool ZFS numa VPS?
Uma vez por mês é adequado para a maioria dos pools pequenos e corresponde ao comportamento predefinido dos pacotes: uma tarefa cron no segundo domingo no Debian e no Ubuntu, e um limite predefinido de 35 dias no sistema periodic do FreeBSD. Fazer scrub semanalmente só é razoável depois de medir a duração de um scrub e confirmar que termina rapidamente num servidor que, de resto, esteja sem carga. Num pool ocupado com um ou dois dispositivos, o scrub semanal consome I/O real das aplicações todas as semanas e oferece apenas mais algumas semanas de aviso antecipado.
Fazer scrub num pool ZFS com um único disco não tem utilidade?
Não, desde que tenha claro o que essa operação fornece. Sem redundância, o scrub deteta corrupção, mas não a consegue reparar, exceto nos metadados, dos quais o ZFS mantém uma cópia adicional por predefinição. O resultado é uma lista identificada de ficheiros danificados em zpool status -v, com antecedência suficiente para os restaurar enquanto ainda existir uma cópia válida noutro local. A resposta correta consiste em melhorar os backups, porque o scrub indica exatamente que ficheiro deve restaurar.
Posso pausar um scrub ZFS e concluí-lo mais tarde?
Sim. zpool scrub -p tank pausa-o, e o estado de pausa e o progresso são gravados periodicamente no disco, pelo que o scrub permanece pausado durante uma exportação ou um reboot. Execute novamente zpool scrub tank para retomar a partir do último checkpoint. Não use zpool scrub -s tank para este efeito: -s para o scrub, e o próximo começa novamente do início.
Porque é que o meu scrub ZFS é tão lento e como posso acelerá-lo?
A duração do scrub acompanha a quantidade de dados alocados e a fragmentação, não a capacidade do disco. Um pool com mais de 90% de utilização é lento porque os metaslabs com menos de 4% de espaço livre fazem o allocator passar de first-fit para best-fit, e a fragmentação resultante transforma o scrub numa sequência de muitas leituras pequenas. Libertar espaço normalmente ajuda mais do que qualquer parâmetro ajustável. Pode aumentar zfs_scrub_min_time_ms ou zfs_vdev_scrub_max_active para dar ao scrub uma parcela maior da fila, mas num pool com um ou dois dispositivos essa parcela é retirada diretamente às aplicações.