Si Apache está escribiendo un archivo de algún tipo en un lugar y no ha terminado de escribirlo y luego lo rsync
inicia, rsync
copiará lo que esté allí.
Es decir, si Apache está lidiando con un archivo de 5 MB, solo se escriben 2 MB y se rsync
activa, se copiará el archivo parcial de 2 MB. Por lo tanto, parece que el archivo está "dañado" en el servidor de destino.
Dependiendo del tamaño de los archivos que esté utilizando, puede usar la --inplace
opción rsync
para hacer lo siguiente:
Esta opción cambia la forma en que rsync transfiere un archivo cuando los datos del archivo deben actualizarse: en lugar del método predeterminado de crear una nueva copia del archivo y colocarlo en su lugar cuando está completo, rsync escribe los datos actualizados directamente en el destino archivo.
El beneficio de esto es que si un archivo de 5 MB solo tiene 2 MB copiados en la primera ejecución, la siguiente ejecución tomará 2 MB y continuará copiando el archivo hasta que los 5 MB completos estén en su lugar.
Lo negativo es que podría crear una situación en la que alguien está accediendo al servidor web mientras se copia un archivo y luego vería un archivo parcial. En mi opinión, rsync
funciona mejor en su comportamiento predeterminado de almacenar en caché un archivo "invisible" y luego moverlo a su lugar de inmediato. Pero --inplace
es bueno para escenarios en los que los archivos grandes y las restricciones de ancho de banda pueden interponerse en el camino de que un archivo grande se copie fácilmente desde el principio.
Dicho esto, declara esto; El énfasis es mío:
Cada cinco minutos tiene cron ejecutar rsync ...
Entonces, ¿supongo que tienes algún script bash para administrar este trabajo cron? Bueno, la cosa es rsync
lo suficientemente inteligente como para copiar solo los archivos que necesitan ser copiados. Y si tiene un script que se ejecuta cada 5 minutos, parece que está tratando de evitar rsync
pisar el uno al otro si va más rápido. Es decir, si lo ejecuta cada minuto, existe el riesgo de que uno o más de los rsync
procesos aún se estén ejecutando debido al tamaño del archivo o la velocidad de la red y el siguiente proceso simplemente competirá con él; Una condición de carrera.
Una forma de evitar esto es envolver todo el rsync
comando en un script bash que verifique si hay un bloqueo de archivo; a continuación se muestra un marco de secuencia de comandos bash repetitivo que uso para casos como este.
Tenga en cuenta que algunas personas recomendarán usar, flock
pero como flock
no está instalado en algunos sistemas que uso, y salto mucho entre Ubuntu (que lo tiene) y Mac OS X (que no), utilizo este marco simple sin ningún problema real:
LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'
if mkdir ${LOCK_DIR} 2>/dev/null; then
# If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
echo $$ > ${PID_FILE}
echo "Hello world!"
rm -rf ${LOCK_DIR}
exit
else
if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
# Confirm that the process file exists & a process
# with that PID is truly running.
echo "Running [PID "$(cat ${PID_FILE})"]" >&2
exit
else
# If the process is not running, yet there is a PID file--like in the case
# of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
rm -rf ${LOCK_DIR}
exit
fi
fi
La idea es ese núcleo general, donde yo tengo, echo "Hello world!"
donde está el corazón de su guión. El resto es básicamente un mecanismo / lógica de bloqueo basado en mkdir
. Una buena explicación del concepto está en esta respuesta :
mkdir crea un directorio si aún no existe, y si lo hace, establece un código de salida. Más importante aún, hace todo esto en una sola acción atómica que lo hace perfecto para este escenario.
Entonces, en el caso de su rsync
proceso, recomendaría usar este script simplemente cambiando el echo
comando a su rsync
comando. Además, cambie LOCK_NAME
a algo así RSYNC_PROCESS
y entonces estará listo para comenzar.
Ahora, rsync
envuelto en este script, puede configurar el trabajo cron para que se ejecute cada minuto sin riesgo de una condición de carrera en la que dos o más rsync
procesos luchan por hacer lo mismo. Esto le permitirá aumentar la velocidad o las rsync
actualizaciones, lo que no eliminará el problema de la transferencia parcial de archivos, pero ayudará a acelerar el proceso general para que el archivo completo se pueda copiar correctamente en algún momento.
lsyncd
. Le permite tener "carpetas activas" que realmente prestan atención a la actividad en ellas y luego actuar sobre esos archivos cuando se realizan cambios. Usorsync
mucho como se describe en mi respuesta, pero lo usolsyncd
para casos que requieren una forma de acción no cron / más inmediata.Sí, y el archivo podría estar dañado si rsync está leyendo el archivo al mismo tiempo que se está escribiendo el archivo.
Puedes probar esto: /unix//a/2558
También puedes escribirlo con lsof:
Un código de salida de 0 significa que el archivo está en uso, y el código de salida de 1 significa que no hay actividad en ese archivo.
fuente