cómo duplicar un grupo zfs completo a otro grupo zfs

15

Tengo un grupo de zfs que contiene varios zvols y conjuntos de datos de los cuales algunos también están anidados. Todos los conjuntos de datos y zvols son capturados periódicamente por zfs-auto-snapshot. Todos los conjuntos de datos y zvols también tienen algunas instantáneas creadas manualmente.

He configurado un grupo remoto en el que, debido a la falta de tiempo, la copia inicial a través de la red local de alta velocidad a través de zfs send -R no se completó (faltan algunos conjuntos de datos, algunos conjuntos de datos tienen instantáneas desactualizadas o faltantes).

Ahora el grupo es físicamente remoto a través de una conexión de baja velocidad y necesito sincronizar periódicamente el grupo remoto con el grupo local, lo que significa que los datos presentes en el grupo local deben copiarse en el grupo remoto, los datos que se han ido del grupo local deben eliminarse del grupo remoto, y los datos presentes en el grupo remoto pero no en el grupo local deben eliminarse del grupo remoto, por datos que significan 'zvols', 'conjuntos de datos' o 'instantáneas'.

Si estuviera haciendo esto entre dos sistemas de archivos regulares usando rsync, sería "-axPHAX --delete" (eso es lo que realmente hago para hacer una copia de seguridad de algunos sistemas).

¿Cómo configuro una tarea de sincronización para que los conjuntos de datos y zvols del grupo remoto (incluidas sus instantáneas) puedan estar sincronizados con los zvols, conjuntos de datos e instantáneas locales?

Me gustaría evitar la transferencia a través de ssh, debido al bajo rendimiento de ssh; Preferiría mbuffer o iscsi en su lugar.

Costin Gușă
fuente
¿Cómo hiciste tu inicial zfs send -R ...? Si canalizó la salida a través de ssh, ¿deshabilitó los caracteres de escape con zfs send -R ... | ssh -e none ...?
Andrew Henle
Además, debe asegurarse de que su conexión lenta tenga suficiente ancho de banda para mantener actualizada la copia remota. Si está recibiendo más cambios en el sistema local de los que puede enviar al sistema remoto, nunca podrá mantener actualizada la copia remota. Tome una secuencia de replicación zfs incremental y guárdela en un archivo. Si el archivo es más grande que la cantidad de datos que puede enviar al sitio remoto en el tiempo transcurrido entre las instantáneas, nunca podrá mantenerse al día. zfs send -R -i pool@snap1 pool@snap2 | gzip --fast > /output/file.gz
Andrew Henle
También podría intentar usar este script para hacerlo automáticamente: github.com/psy0rz/zfs_autobackup/blob/master/README.md
edwin eefting

Respuestas:

11

Descargo de responsabilidad: como nunca he usado zvols, no puedo decir si son diferentes en la replicación que los sistemas de archivos normales o las instantáneas. Supongo que sí, pero no confíe en mi palabra.


Su pregunta es en realidad múltiples preguntas, trato de responderlas por separado:

Cómo replicar / duplicar el grupo completo en una ubicación remota

Debe dividir la tarea en dos partes: primero, la replicación inicial debe completarse, luego es posible la replicación incremental, siempre y cuando no se meta con sus instantáneas de replicación . Para habilitar la replicación incremental, debe conservar las últimas instantáneas de replicación, todo lo anterior puede eliminarse. Si elimina la instantánea anterior, zfs recvse quejará y abortará la replicación. En este caso, debe comenzar de nuevo, así que trate de no hacerlo.

Si solo necesita las opciones correctas, son:

  • zfs send:
    • -R: envía todo lo que se encuentra dentro del grupo o conjunto de datos (replicación recursiva, necesaria todo el tiempo, incluye -p). Además, al recibir, todas las instantáneas de origen eliminadas se eliminan en el destino.
    • -I: incluye todas las instantáneas intermedias entre la última instantánea de replicación y la instantánea de replicación actual (solo se necesita con envíos incrementales)
  • zfs recv:
    • -F: expande el grupo de destino, incluida la eliminación de conjuntos de datos existentes que se eliminan en el origen
    • -d: descarte el nombre del grupo de origen y reemplácelo con el nombre del grupo de destino (el resto de las rutas del sistema de archivos se conservarán y, si es necesario, también se crearán)
    • -u: no monte el sistema de archivos en el destino

Si prefiere un ejemplo completo, aquí hay un pequeño script:

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

Usa algo más rápido que SSH

Si tiene una conexión suficientemente segura, por ejemplo, un túnel IPSec o OpenVPN y una VLAN separada que solo existe entre el remitente y el receptor, puede cambiar de SSH a alternativas sin cifrar como mbuffer como se describe aquí , o podría usar SSH con cifrado débil / sin cifrado y la compresión deshabilitada, que se detalla aquí . También había un sitio web sobre cómo recompilar SSH para que fuera mucho más rápido, pero desafortunadamente no recuerdo la URL, la editaré más tarde si la encuentro.

Para conjuntos de datos muy grandes y conexiones lentas, también puede ser útil para la primera transmisión a través del disco duro (use un disco encriptado para almacenar zpool y transmitirlo en un paquete sellado a través de mensajería, correo o en persona). Como el método de transmisión no importa para enviar / recibir, puede canalizar todo al disco, exportar el grupo, enviar el disco a su destino, importar el grupo y luego transmitir todos los envíos incrementales a través de SSH.

El problema con las instantáneas desordenadas

Como se indicó anteriormente, si elimina / modifica sus instantáneas de replicación, recibirá el mensaje de error

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

lo que significa que su comando fue incorrecto o que se encuentra en un estado inconsistente donde debe eliminar las instantáneas y comenzar de nuevo.

Esto tiene varias implicaciones negativas:

  1. No puede eliminar una instantánea de replicación hasta que la nueva instantánea de replicación se haya transferido correctamente. Como estas instantáneas de replicación incluyen el estado de todas las demás instantáneas (anteriores), el espacio vacío de los archivos eliminados y las instantáneas solo se reclamarán si finaliza la replicación. Esto puede ocasionar problemas de espacio temporales o permanentes en su grupo que solo puede solucionar reiniciando o finalizando el procedimiento de replicación completo.
  2. Tendrá muchas instantáneas adicionales, lo que ralentiza el comando de lista (excepto en Oracle Solaris 11, donde se solucionó).
  3. Es posible que deba proteger las instantáneas contra la eliminación (accidental), excepto por el script en sí.

Existe una posible solución a esos problemas, pero no lo he intentado yo mismo. Puede usar zfs bookmarkuna nueva función en OpenSolaris / illumos creada específicamente para esta tarea. Esto lo liberaría de la administración de instantáneas. El único inconveniente es que, en la actualidad, solo funciona para conjuntos de datos únicos, no de forma recursiva. Tendría que guardar una lista de todos sus conjuntos de datos antiguos y nuevos y luego recorrerlos, marcarlos, enviarlos y recibirlos, y luego actualizar la lista (o una pequeña base de datos, si lo prefiere).

Si prueba la ruta de marcadores, ¡me interesaría saber cómo funcionó para usted!

usuario121391
fuente
Muchas gracias por esta respuesta detallada. solo estoy enviando ... recibiendo a zpool.
jitter
1
Buen guión. Agregaría -d 1a ambos zfs listcomandos para limitar la profundidad de búsqueda (no es necesario buscar debajo del nombre del grupo). Esto evita largas demoras en los grupos con muchas instantáneas (por ejemplo, mi grupo de "copia de seguridad" tiene 320000 instantáneas y zfs list -r -t snapshot backuptarda 13 minutos en ejecutarse. Solo toma 0.06 segundos con -d 1). El zfs destroycomando en el bucle for necesita la -ropción de eliminar recursivamente todas las instantáneas con el mismo nombre de snap.
cas
5

Personalmente, me haría una lista de zvols, conjuntos de datos, etc. en el servidor remoto que no tienen instantáneas actualizadas, y luego las actualizaría zfs send, incluso si esto lleva mucho tiempo y consume mucho tiempo. de ancho de banda.

Entonces podría continuar usando a zfs sendpartir de ese momento y no tener que reinventar la rueda escribiendo mi propio código de sincronización. rsynces bueno para sistemas de archivos más antiguos, pero zfs sendes mucho mejor para zfs: sabe exactamente qué bloques han cambiado en la instantánea y solo los envía , mientras que rsync tiene que comparar archivos individuales y / o marcas de tiempo entre servidores locales y remotos. Lo mismo se aplica a los btrfs sendgrupos btrfs.

Si solo tiene una pequeña cantidad de instantáneas que deben actualizarse, esto podría hacerse manualmente. De lo contrario, para hacerlo automáticamente, necesita una lista de las últimas instantáneas locales frente a las instantáneas remotas, y un script para comparar versiones y luego zfs sendinstantáneas locales que no están actualizadas en el servidor rmeote.

Eso será suficiente si solo le importa la última instantánea para cada conjunto de datos. Si te interesan todas las instantáneas anteriores, obviamente tu script también tendrá que manejarlas ... y eso se vuelve MUCHO más complicado. En algunos casos, es posible que tenga que revertir en el servidor remoto para que pueda volver a enviar las instantáneas intermedias / faltantes.

Si desea una conexión segura al servidor remoto, realmente tiene pocas opciones más que usar ssh, o tal vez configurar un túnel con openvpno algo y usar netcat.

cas
fuente
¿Qué hay de usar Zrep? bolthole.com/solaris/zrep
xdg
No sé, nunca lo usé. parece que sería una buena respuesta, aunque si alguien investigara y probara un poco y lo escribiera (eso es una pista).
cas
Lo probé en Ubuntu (ZFS en Linux) y no funcionaba en conjuntos de datos más profundos (tank / something / someother). Estaba usando este puerto para shell - link . La bandera recursiva export ZREP_R=-Rno funcionaba en absoluto. :(
Xdg
1

Eche un vistazo a 'zrepl', en FreeBSD, que podría hacer que su vida y la de cualquier persona sea mucho más fácil. Fue presentado hace unos días durante BSDCan2018 en Ottawa. Parece prometedor y puede ser una solución a sus problemas.

fd0
fuente
La pregunta en la pregunta es: "¿Cómo configuro una tarea de sincronización para que los conjuntos de datos y zvols del grupo remoto (incluidas sus instantáneas) puedan estar sincronizados con zvols, conjuntos de datos e instantáneas locales?"
Jeff Schaller
0

zrep es una buena solución todo en uno, Y tiene documentación + ganchos sobre cómo obtener transferencias más rápidas que solo transferencias SSH simples

https://github.com/bolthole/zrep

también es multiplataforma: compatible con linux, freebsd y solaris / illumos

Philip Brown
fuente
1
La pregunta en la pregunta es: "¿Cómo configuro una tarea de sincronización para que los conjuntos de datos y zvols del grupo remoto (incluidas sus instantáneas) puedan estar sincronizados con zvols, conjuntos de datos e instantáneas locales?"
Jeff Schaller
Jeff, ¿estás sugiriendo que la mejor "respuesta" sería cortar y pegar bits de la documentación de zrep, en lugar de solo dar una referencia a zrep?
Philip Brown
1
No sé cuál sería la mejor respuesta, pero un enlace al software no es una solución. Ya se ha mencionado, de hecho. La pregunta es: "¿Cómo configuro una tarea de sincronización para que los zvols y conjuntos de datos del grupo remoto (incluidas sus instantáneas) puedan estar sincronizados con zvols, conjuntos de datos e instantáneas locales?"
Jeff Schaller
Sí, esa es la pregunta. Sin embargo, para realizar la tarea BIEN, se requiere mucho más que una pequeña reseña en una página web aquí. Es por eso que zrep es un shellscript de 2000 líneas. Incluso si uno eliminara todas las partes que el problema original nunca necesitó, todavía se necesitarían un par de cientos de líneas de script para hacerlo BIEN.
Philip Brown