¿Cómo puedo limitar el ancho de banda utilizado por un proceso?

42

Tengo un servidor CentOS 5.7 que realizará copias de seguridad de sus archivos todas las noches. Me preocupa que los visitantes de los distintos sitios que aloja el servidor experimentarán un rendimiento degradado mientras la copia de seguridad se transfiere a través de la red.

¿Es posible limitar el rendimiento máximo permitido de un proceso a una interfaz de red? Me gustaría limitar la transferencia de archivos basada en SSH a solo la mitad de mi ancho de banda disponible. Esto podría estar en el lado del servidor o del cliente; es decir, me complacería hacerlo en el cliente que inicia la conexión o en el servidor que recibe la conexión.

(Desafortunadamente, no puedo agregar una interfaz para dedicarla a las copias de seguridad. Podría aumentar mi rendimiento disponible, pero eso solo significaría que la transferencia de red se completaría más rápido, pero aún así maximizaría la capacidad total de la conexión al hacerlo).


Algunos antecedentes

Tal vez algunos antecedentes están en orden. Al retroceder, tuve un problema al no tener suficiente espacio local para crear la copia de seguridad. Ingrese SSHFS! La copia de seguridad se guarda en lo que aparentemente es una unidad local para que nunca haya bits de copia de seguridad en el servidor web.

¿Por qué es eso importante? Porque eso parecería invalidar el uso de lo venerable rsync --bwlimit. rsyncen realidad no está haciendo la transferencia ni puede hacerlo porque ni siquiera puedo ahorrar espacio para guardar el archivo de copia de seguridad.

Puedo escucharle preguntar: "Espera, ¿por qué necesita hacer un archivo de respaldo? ¿Por qué no solo rsynclos archivos y carpetas de origen?" ¡Porque una cosa molesta llamada "Plesk" está en la mezcla! Este es mi proveedor de alojamiento web orientado al cliente que utiliza Plesk por conveniencia. Como tal, utilizo Plesk para iniciar las copias de seguridad porque Plesk agrega todo tipo de magia adicional a la copia de seguridad que hace que su consumo durante un procedimiento de restauración sea muy seguro.

cara triste

Wesley
fuente
1
Otra posibilidad para mi situación, que por cierto no responde exactamente la pregunta específica, es usar ionicepara estrangular las escrituras que puede hacer un proceso. Como estoy escribiendo en un sistema de archivos SSHFS, puedo reducir la clase del proceso de copia de seguridad a 3 para que dé paso a cualquier otro proceso que quiera escribir. De esa forma obtengo el efecto que quiero, que es nunca degradar la experiencia de un visitante del sitio debido al ancho de banda de acaparamiento de respaldo.
Wesley
Una pregunta, ¿tu ssh usa compresión? "Compresión sí" a su .ssh / config?
Zlatko

Respuestas:

25

Puede usar iptablespara marcar un paquete (--pid-owner ...), luego usar tcpara dar forma al tráfico. También se puede usar "--sid-owner" para incluir hilos y elementos secundarios de ese proceso.

http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#OWNERMATCH

Coincidencia --pid-owner
Kernel 2.3, 2.4, 2.5 y 2.6
Ejemplo de iptables -A OUTPUT -m propietario --pid-owner 78
Explicación Esta coincidencia se utiliza para unir paquetes basados ​​en el ID de proceso (PID) que fue responsable de ellos. Esta coincidencia es un poco más difícil de usar, pero un ejemplo sería solo permitir que el PID 94 envíe paquetes desde el puerto HTTP (si el proceso HTTP no está enhebrado, por supuesto). Alternativamente, podríamos escribir un pequeño script que tome el PID de una salida ps para un demonio específico y luego agregue una regla para ello. Por ejemplo, podría tener una regla como se muestra en el ejemplo Pid-owner.txt

Mircea Vutcovici
fuente
Creo que esto se relaciona con mi solución para la mejor manera de hacerlo. --pid-owner en realidad no selecciona según el proceso, sino el propietario del proceso. Tendría que crear un usuario especial para iniciar el proceso y luego filtrar en función de ese propietario solo para estar seguro de que estoy formando el tráfico solo de ese proceso específico y no, por ejemplo, múltiples demonios que podrían haberse lanzado desde Un usuario genérico.
Wesley
@Wesley Eso no es lo que dice la página de manual: " --pid-owner processidCoincide si el paquete fue creado por un proceso con el ID de proceso dado ". linux.die.net/man/8/iptables
Ajedi32
Esta respuesta sería mucho mejor si incluyera un ejemplo de cómo usar iptables y tc para este propósito. El iptables -A OUTPUT -m owner --pid-owner 78ejemplo dado no parece estar completo (ya que solo coincide con los paquetes, no dice cómo "marcarlos") y tcno se explica en absoluto.
Ajedi32
Para marcar un paquete necesita agregar algo como -j MARK --set-mark 1. Para más detalles ver: wiki.archlinux.org/index.php/…
Mircea Vutcovici
40

Una opción que acabo de descubrir es usar goteo .

goteo es un modelador de ancho de banda de espacio de usuario ligero y portátil. Puede ejecutarse en modo colaborativo (junto con goteo) o en modo independiente.

El goteo funciona aprovechando la precarga del cargador Unix. Básicamente, proporciona a la aplicación una nueva versión de la funcionalidad que se requiere para enviar y recibir datos a través de sockets. Luego limita el tráfico en función de retrasar el envío y la recepción de datos a través de un socket. El goteo se ejecuta completamente en el espacio de usuario y no requiere privilegios de root.

Wesley
fuente
1
Este es el que resolvió mi problema. Estaba teniendo un problema con el demonio bitcoin chupando al azar todo mi ancho de banda cuando un cliente decidió que yo era la persona de la que deberían descargar toda la cadena de bloques.
Omnifarioso
El trickleenlace que le dio conduce a un 404.
Geremia
Arreglé el enlace roto (reemplazándolo con un enlace de Wayback Machine).
G-Man dice 'Restablece a Monica' el
3
Trickle parece estar en github ahora: github.com/mariusae/trickle
Cheetah
osudo apt-get install trickle
ggll
22

Si puede escribir en una tubería (o stdout), puede instalar el pvcomando (visor de tuberías). Originalmente se escribió para mostrar el progreso de los datos transferidos a través de una tubería.

tar cvf - /files/to/backup | pv -L 512k > /your/file/on/sshfs

   -L RATE, --rate-limit RATE
          Limit the transfer to a maximum of RATE  bytes  per  second.   A
          suffix of "k", "m", "g", or "t" can be added to denote kilobytes
          (*1024), megabytes, and so on.
hhaamu
fuente
¡Esta es realmente la respuesta que creo que usaré! Sin embargo, no es exactamente una respuesta a la pregunta específica que hice originalmente. Por desgracia, la pregunta se transformó, pero todavía se centró en limitar la velocidad de la red de un proceso. Sin embargo, puede contribuir a esta nueva pregunta que hice: unix.stackexchange.com/q/34174/4232
Wesley
¡Gracias! Estaba haciendo algo similar y terminé haciéndolo ssh my-remote-server bash -c "'find / -xdev|cpio -o|gzip -c1'"|pv --rate-limit 1M > my-remote-root.cpio.gz.
clacke
1
Podría haberlo combinado también con ionice, pero no estaba permitido en ese servidor en particular. ssh my-remote-server ionice -c3 bash -c "'find / -xdev|cpio -o|gzip -c1'"|pv --rate-limit 1M > my-remote-root.cpio.gz
clacke
6

Yo uso rsync con la opción --bwlimit = KBPS por la misma razón.

Nuestra ethernet de 1 Gbit es capaz de inundar fácilmente nuestro antiguo SCSI320 DAS RAID, y esencialmente DOS es algunas de nuestras cajas de producción más antiguas que dependen de él para sus tiendas NFS.

Magallanes
fuente
4

¿Cómo transfieres los datos? (rsync sobre ssh? scp? sftp? algo más?)

rsync le permitirá limitar el ancho de banda (vea la opción --bwlimit = KBPS). rsync -e ssh --bwlimit ..

Alternativamente, puede configurar un qdisc o equivalente para limitar la velocidad de fantasía, pero sospecho que en su caso esto sería una exageración severa. La documentación sobre esto está disponible en el COMO de Linux Advanced Routing and Traffic Control

Devdas
fuente