Cada cuánto ejecutar un scrub de ZFS en un VPS
Un scrub verifica cada bloque asignado, pero en un pool ZFS de un solo dispositivo detecta daños que no puede reparar. Consulta la frecuencia recomendada.
Qué hace realmente un scrub de ZFS
Un scrub de ZFS lee cada bloque asignado del pool, vuelve a calcular su suma de comprobación y compara el resultado con la suma de comprobación almacenada en el puntero de bloque padre. Si no coinciden, ZFS repara el bloque usando la redundancia disponible en el pool. Ninguna otra operación de ZFS realiza esta tarea. Las lecturas normales sólo verifican los bloques que se leen, por lo que un archivo que no se ha abierto en dos años permanece sin verificar hasta que un scrub lo lee.
Un scrub no es fsck, la pasada de reparación sin conexión que necesitan otros sistemas de archivos. No existe una fase de reparación estructural porque ZFS nunca deja el formato en disco en un estado dañado: cada escritura se realiza en una ubicación nueva y el uberblock, el puntero raíz del pool, se actualiza en último lugar. Un scrub tampoco lee todo el dispositivo. Sólo lee los bloques asignados. Por eso, un pool casi vacío completa el scrub en minutos, mientras que el mismo pool al 80% de ocupación tarda mucho más.
El scrub se ejecuta con la prioridad de E/S más baja disponible en ZFS. En Linux, zfs_vdev_scrub_max_active tiene el valor predeterminado 2, por lo que puede haber como máximo dos lecturas de scrub en curso por vdev (dispositivo virtual, el grupo de discos que ZFS trata como una sola unidad). zfs_scrub_min_time_ms tiene el valor predeterminado 750, el tiempo mínimo que el subproceso de sincronización dedica al trabajo del scrub entre las descargas de grupos de transacciones, las confirmaciones periódicas en las que ZFS agrupa las escrituras. En una máquina inactiva, el scrub utiliza todo el disco. Durante la carga de trabajo, cede recursos. En un pool con uno o dos dispositivos no hay otro lugar al que cederlos, por lo que la programación es más importante en este caso que en un chasis grande con sesenta unidades.
¿Por qué ejecutar un scrub en un pool que no puede repararse?
Esta es la frase que determina todo lo demás en un pool pequeño. Sin redundancia, un scrub detecta la corrupción, pero no puede corregirla. Un solo disco virtual en un VPS es un pool sin mirror ni paridad. ZFS lee el bloque defectuoso, no supera la suma de comprobación, lo cuenta en la columna CKSUM, identifica el archivo y se detiene, porque no hay una segunda copia desde la que reconstruirlo.
Conviene conocer dos excepciones parciales. De forma predeterminada, ZFS almacena una copia adicional de los metadatos (redundant_metadata=all) en otra región del dispositivo, por lo que un scrub puede reparar una entrada de directorio o un puntero de bloque dañados incluso en un pool de un solo dispositivo. Además, un dataset con copies=2 conserva dos copias de sus bloques de datos, con el doble de consumo de espacio. Ninguna de estas opciones permite recuperarse si el dispositivo deja de estar disponible. La documentación de la propiedad copies advierte exactamente de esto: no cree un pool striped, establezca copies=2 y piense que tiene redundancia.
Por tanto, en un pool de un solo dispositivo, el scrub proporciona una cosa: una notificación temprana y precisa. Convierte la corrupción silenciosa en un nombre de archivo en zpool status -v mientras la copia de seguridad todavía conserva una versión correcta de ese archivo. Esto es un argumento a favor de las copias de seguridad, no un argumento contra los scrub. Si todavía no tiene clara la diferencia entre una imagen de un punto en el tiempo y una copia real fuera del servidor, empiece por por qué una snapshot de un VPS no es una copia de seguridad, porque el resultado de un scrub sólo es útil si existe otra copia intacta.
Un scrub que no encuentra nada también es un resultado. Le indica que los datos en los que está a punto de confiar están intactos, que es lo que necesita saber antes de una restauración o una migración.
¿Con qué frecuencia debe ejecutar scrub en un grupo pequeño de VPS?
La opción predeterminada adecuada es una vez al mes, que es lo que ya suponen los paquetes. Debian y Ubuntu incluyen un trabajo de cron que ejecuta scrub en los grupos en buen estado el segundo domingo de cada mes. El sistema periodic de FreeBSD utiliza un umbral en días, y daily_scrub_zfs_default_threshold tiene el valor predeterminado 35, que el manual describe como cinco semanas.
Ejecutar scrub semanalmente en un grupo pequeño con mucha actividad suele costar más de lo que aporta. Con uno o dos dispositivos, scrub compite por la misma cola que la aplicación y no hay ningún dispositivo adicional que absorba esa carga. En un VPS, la cuota de E/S es limitada, por lo que las lecturas que consume scrub son lecturas que la base de datos no puede realizar. Frente a ese coste, ejecutar scrub semanalmente sólo proporciona como máximo tres semanas de aviso adicional sobre un fallo que, de todos modos, no puede reparar. Esta relación sólo compensa cuando scrub es barato.
Mida la duración y decida después. Ejecute scrub una vez manualmente y observe cuánto tarda.
- Ejecute
sudo zpool scrub tankuna tarde con poca actividad y registre el tiempo total desdezpool status. - Si termina bastante antes de una hora y el servidor está inactivo durante la noche, ejecutarlo semanalmente es asumible.
- Si tarda muchas horas mientras el grupo está atendiendo tráfico, mantenga la frecuencia mensual y deje que el trabajo incluido en el paquete lo gestione.
- Vuelva a medirlo cada vez que el grupo crezca de forma apreciable, porque la duración de scrub depende de los datos asignados, no de la capacidad del disco.
Sea cual sea la opción elegida, anótela junto con las demás tareas recurrentes del servidor. scrub debe figurar en la misma lista que las actualizaciones de paquetes y la rotación de registros: consulte una lista de comprobación mensual para el mantenimiento de servidores Linux.
Iniciar, pausar y detener un scrub
sudo zpool scrub tank
sudo zpool status tankPausar y detener son operaciones distintas. Elegir la opción incorrecta puede hacerle perder horas de trabajo repetido.
sudo zpool scrub -p tank
sudo zpool scrub tank
sudo zpool scrub -s tank-p pausa el scrub. El estado y el progreso de la pausa se sincronizan periódicamente con el disco. Por eso, un scrub pausado sobrevive a una exportación o a un reinicio: el pool vuelve a estar disponible con el scrub todavía pausado y espera a que usted lo reanude. Ejecutar zpool scrub de nuevo reanuda el proceso desde el último punto de control escrito en el disco. -s detiene el scrub. El siguiente scrub que inicie comenzará desde el principio. Use -p cuando necesite recuperar el disco durante una hora. Use -s cuando quiera eliminar el scrub.
Conviene conocer otras dos opciones. -w espera a que termine el scrub antes de devolver el control. Esto es lo que necesita en un script para que el paso siguiente no se inicie antes de tiempo. -e ejecuta el scrub sólo sobre los archivos con errores de datos conocidos, según informa zpool status -v. Es la forma rápida de confirmar que un archivo restaurado desde una copia de seguridad está ahora limpio.
ZFS ejecuta un scrub o un resilver, la reconstrucción que se realiza después de sustituir un dispositivo, cada vez en un pool, porque ambas operaciones requieren mucha E/S. Si un dispositivo está en proceso de resilver, el scrub espera su turno.
Cómo leer el estado de zpool mientras se ejecuta un scrub
Ejecute sudo zpool status tank y lea sus propios valores en lugar de compararlos con los de otra persona. Durante un scrub, la línea scan: muestra el valor escaneado, el valor emitido, el total, el valor reparado, el porcentaje completado y una estimación del tiempo restante.
Scanned es la fase de metadatos: ZFS recorre el árbol de bloques y recopila las direcciones que necesita leer. Issued es la fase de datos: las lecturas que se envían realmente al dispositivo, ordenadas según el orden del disco. El scrub ordenado es la razón por la que existen dos contadores, e issued es el que indica el progreso real. Al principio, scanned avanza mucho más que issued y la estimación de tiempo apenas resulta útil. Evalúela después de alcanzar el primer diez por ciento.
Repaired cuenta los bytes reescritos a partir de una copia correcta. En un pool sin redundancia, este valor permanece en cero independientemente de lo que encuentre el scrub. Es el punto anterior expresado como un número que puede supervisar.
A continuación, lea las columnas de cada dispositivo. READ y WRITE cuentan los errores de E/S notificados por el propio dispositivo. CKSUM cuenta los bloques que no superaron la verificación de checksum, y CKSUM es la columna que el scrub debe completar. Un valor CKSUM distinto de cero en un dispositivo que parece estar sano es real: los datos regresaron, pero lo hicieron incorrectamente.
La última línea contiene el resultado. errors: No known data errors indica que la comprobación se superó. Cualquier otro resultado significa que debe ejecutar sudo zpool status -v tank, que muestra la lista completa de errores de datos desde el último scrub completo, incluidos los nombres de los archivos afectados. Restaure esos archivos desde una copia de seguridad, ejecute sudo zpool clear tank para restablecer los contadores y vuelva a ejecutar el scrub. Cada scrub completo reconstruye esa lista, por lo que un nombre de archivo ausente después de un scrub completo sin errores ha desaparecido realmente.
¿Qué trabajo periódico de scrub está configurado en el servidor?
No dé por hecho que existe uno ni que sólo existe uno. El mecanismo cambia según la plataforma y el paquete. El formato del pool es idéntico en todas partes. Esto facilita olvidar que las herramientas que lo gestionan no lo son. La diferencia entre la forma en que ZFS se distribuye en FreeBSD y en Linux es lo importante aquí.
En FreeBSD, el trabajo pertenece al sistema periodic. Configure estos valores en /etc/periodic.conf:
daily_scrub_zfs_enable="YES"
daily_scrub_zfs_pools="tank"
daily_scrub_zfs_default_threshold="35"daily_scrub_zfs_pools es una lista de nombres de pools separados por espacios. Si se deja vacía, se ejecuta el scrub en todos los pools. daily_scrub_zfs_default_threshold indica el número de días entre scrubs cuando no se establece un umbral específico para el pool. El manual indica 35 como valor predeterminado. El trabajo diario se ejecuta todos los días, pero sólo inicia un scrub cuando se supera el umbral.
En Linux, depende del paquete de ZFS de la distribución. Algunos sistemas incluyen ambos mecanismos a la vez. Hay temporizadores systemd por pool, zfs-scrub-monthly@tank.timer y zfs-scrub-weekly@tank.timer, que se habilitan para cada pool individualmente. Debian y Ubuntu también incluyen /etc/cron.d/zfsutils-linux, que ejecuta un script para hacer scrub en todos los pools ONLINE el segundo domingo de cada mes. Compruebe qué tiene antes de añadir nada:
systemctl list-timers 'zfs-*'
ls /etc/cron.d/ | grep -i zfs
sudo zpool history tank | grep scrubzpool history es la respuesta fiable, porque registra los scrubs que el pool inició realmente, junto con sus fechas. Dos scrubs al mes significan que ambos mecanismos están activos y que debería deshabilitar uno de ellos. Para habilitar un temporizador:
sudo systemctl enable --now zfs-scrub-monthly@tank.timerEl espacio libre importa más que cualquier parámetro ajustable
La duración de un scrub en un pool pequeño depende de la cantidad de datos asignados y de su dispersión. Llenar el pool empeora ambos factores.
La recomendación de OpenZFS es mantener más del 10% de espacio libre en el pool. Por debajo de ese valor, los metaslabs, que son los bloques en los que trabaja el asignador, empiezan a cruzar un umbral del 4% de espacio libre y el asignador cambia de first-fit a best-fit. best-fit consume mucha más CPU. Aumenta la latencia de escritura, aparece fragmentación y el siguiente scrub tarda todavía más, porque la misma cantidad de datos llega como un número mayor de lecturas más pequeñas.
Por tanto, la primera medida no es ajustar un parámetro. Es eliminar elementos. En un sistema ZFS, la causa habitual son las instantáneas antiguas, seguidas de imágenes y capas de Docker que nadie ha depurado y paquetes del kernel que quedaron tras las actualizaciones. Ejecute zfs list -o space antes de hacer cualquier otra cosa, porque separa el espacio ocupado por las instantáneas del espacio ocupado por los datos activos.
Después vienen los parámetros, brevemente. En Linux puede consultar los valores actuales:
cat /sys/module/zfs/parameters/zfs_scrub_min_time_ms
cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_activeFreeBSD expone los mismos parámetros mediante sysctl, así que puede localizar los suyos con sysctl -a | grep scrub. Aumentarlos hace que el scrub termine antes y ralentiza las aplicaciones. Reducirlos produce el efecto contrario. En un pool con uno o dos dispositivos, ningún ajuste proporciona ambas cosas, porque sólo hay una cola que repartir. Un parámetro rara vez corrige un problema de diseño. Si un scrub mensual afecta al rendimiento, la lectura correcta es que el pool está demasiado lleno o que el dispositivo es demasiado lento; un parámetro ajustable sólo desplaza el problema.
El tiempo del scrub sirve como previsión del resilver
Un resilver recorre los datos igual que un scrub: lee los bloques asignados, los verifica y escribe los que faltan en el dispositivo de reemplazo. Por tanto, el tiempo que tarda el scrub es la previsión más fiable de cuánto tardará una reconstrucción y de cuánto tiempo funcionará el pool con redundancia reducida.
ZFS programa el trabajo de resilver de forma más agresiva que el trabajo de scrub, por lo que una reconstrucción suele terminar antes que un scrub del mismo pool. Considere el tiempo del scrub como un límite superior conservador. Si el scrub tarda nueve horas, planifique una ventana de reconstrucción de una duración similar y tenga en cuenta que el fallo de un segundo dispositivo dentro de esa ventana provoca la pérdida del pool. Este es el argumento práctico a favor de pares en espejo en lugar de un solo grupo raidz ancho, ya que raidz, la distribución de paridad que ZFS usa en lugar de RAID 5, se reconstruye leyendo todos los dispositivos que siguen funcionando.
En un pool de un solo dispositivo no hay resilver. Si falla el dispositivo, también falla el pool. El tiempo de recuperación es el tiempo necesario para restaurarlo, así que debe medir la restauración. Una restauración que nunca se ha ejecutado no es un plan de recuperación.
Qué cambia cuando alquila el disco
En un VPS, el dispositivo de bloques es virtual. El hipervisor presenta un volumen y, por debajo, puede haber almacenamiento local NVMe o un volumen de red replicado con su propia paridad. Esto tiene dos consecuencias para las operaciones de scrub.
En primer lugar, la redundancia de la plataforma es invisible para ZFS y ZFS no puede utilizarla. Si la plataforma repara un error de medio por debajo de su instancia, ZFS nunca ve el problema. Si la plataforma entrega un bloque incorrecto, ZFS lo detecta, pero no puede corregirlo porque la copia correcta está al otro lado de ese límite.
En segundo lugar, normalmente no puede leer los datos SMART (tecnología de supervisión, análisis y generación de informes) del dispositivo que está debajo de un disco virtual. Por tanto, es posible que las alertas tempranas de las que depende la supervisión del estado del disco en un VPS no estén disponibles. El contador CKSUM de las operaciones de scrub pasa a ser la principal señal que puede controlar.
Si quiere que ZFS repare los errores en lugar de limitarse a informarlos, el pool necesita más de un dispositivo dentro de la misma instancia. Esto es una decisión del plan, no un ajuste de configuración. Elegir un VPS de almacenamiento en lugar de un VPS normal le proporciona la capacidad, pero que también incluya dos dispositivos independientes depende del plan. Ejecute lsblk y confírmelo antes de crear un mirror sobre lo que podrían ser dos particiones del mismo volumen. Alquilamos servidores Linux y FreeBSD, no un dispositivo ZFS administrado, por lo que el calendario de scrub y las copias de seguridad dependen de usted. Ese es el intercambio: control total del pool y responsabilidad total de su mantenimiento.
FAQ
¿Con qué frecuencia debo hacer scrub en un pool ZFS de una VPS?
Una vez al mes es adecuado para la mayoría de los pools pequeños y coincide con la configuración de los paquetes: un trabajo de cron el segundo domingo en Debian y Ubuntu, y un umbral predeterminado de 35 días en el sistema periodic de FreeBSD. Hacerlo semanalmente sólo es razonable después de medir la duración de un scrub y comprobar que termina rápido en un equipo que, por lo demás, está inactivo. En un pool ocupado con uno o dos dispositivos, hacer scrub cada semana consume E/S real de las aplicaciones y sólo ofrece unas pocas semanas de anticipación adicional.
¿Es inútil hacer scrub en un pool ZFS de un solo disco?
No, siempre que tenga claro qué proporciona. Sin redundancia, un scrub detecta la corrupción pero no puede repararla, salvo en los metadatos, de los que ZFS conserva una copia adicional de forma predeterminada. Lo que obtiene es una lista identificada de archivos dañados en zpool status -v, con tiempo suficiente para restaurarlos mientras todavía exista una copia correcta en otro lugar. La respuesta adecuada es mejorar las copias de seguridad, porque el scrub indica exactamente qué archivo debe restaurar.
¿Puedo pausar un scrub de ZFS y terminarlo más tarde?
Sí. zpool scrub -p tank lo pausa, y el estado de pausa y el progreso se escriben periódicamente en el disco, por lo que el scrub permanece pausado después de una exportación o un reinicio. Ejecute zpool scrub tank de nuevo para reanudarlo desde el último punto de control. No use zpool scrub -s tank para esto: -s detiene el scrub y el siguiente vuelve a comenzar desde el principio.
¿Por qué mi scrub de ZFS es tan lento y cómo puedo acelerarlo?
La duración del scrub depende de los datos asignados y de la fragmentación, no de la capacidad del disco. Un pool con más del 90% de ocupación es lento porque los metaslabs con menos del 4% de espacio libre hacen que el asignador pase de first-fit a best-fit, y la fragmentación resultante convierte el scrub en muchas lecturas pequeñas. Liberar espacio suele ayudar más que cualquier parámetro ajustable. Puede aumentar zfs_scrub_min_time_ms o zfs_vdev_scrub_max_active para dar al scrub una mayor parte de la cola, pero en un pool con uno o dos dispositivos esa parte se resta directamente a la aplicación.