Como posso limitar a largura de banda usada por um processo?

42

Eu tenho um servidor CentOS 5.7 que fará backup de seus arquivos todas as noites. Estou preocupado que os visitantes dos vários sites hospedados pelo servidor tenham um desempenho degradado enquanto o backup está sendo transferido pela rede.

É possível limitar a taxa de transferência máxima permitida de um processo para uma interface de rede? Gostaria de limitar a transferência de arquivos baseada em SSH a apenas metade da minha largura de banda disponível. Isso pode estar no lado do servidor ou cliente; ou seja, ficaria feliz em fazer isso no cliente que inicia a conexão ou no servidor que recebe a conexão.

(Infelizmente, não posso adicionar uma interface para dedicar aos backups. Eu poderia aumentar minha taxa de transferência disponível, mas isso significaria apenas que a transferência de rede seria concluída mais rapidamente, mas ainda assim maximizaria a capacidade total da conexão enquanto o fazia.)


Alguns antecedentes

Talvez alguns antecedentes estejam em ordem. Recuando, tive um problema em não ter espaço local suficiente para criar o próprio backup. Digite SSHFS! O backup é salvo no que é ostensivamente uma unidade local, para que nenhum bit de backup esteja no próprio servidor web.

Por que isso é importante? Porque isso parece invalidar o uso do venerável rsync --bwlimit. rsyncna verdade, não está fazendo a transferência nem pode , porque não posso poupar espaço para salvar o arquivo de backup.

Ouço você perguntar: "Então, espere, por que você precisa criar um arquivo de backup? Por que não apenas rsyncos arquivos e pastas de origem?" Porque uma coisa chata chamada "Plesk" está na mistura! Este é o meu host voltado para o cliente, que usa o Plesk por conveniência. Como tal, uso o Plesk para iniciar os backups porque o Plesk adiciona todo tipo de magia extra ao backup, o que torna muito seguro consumi-lo durante um procedimento de restauração.

rosto triste

Wesley
fonte
1
Veja serverfault.com/questions/52027/…
Jeff Ferland 14/12
1
Outra possibilidade para a minha situação, que aliás não responde exatamente a uma pergunta específica, é usar ionicepara limitar as gravações que um processo pode fazer. Como estou escrevendo em um sistema de arquivos SSHFS, posso reduzir a classe do processo de backup para 3 para que ele ceda completamente a qualquer outro processo que queira gravar. Dessa forma, obtenho o efeito desejado, que nunca degradará a experiência de um visitante do site por causa da largura de banda monótona do backup.
Wesley
Uma pergunta, seu ssh usa compressão? "Compressão sim" para o seu .ssh / config?
Zlatko

Respostas:

25

Você pode usar iptablespara marcar um pacote (--pid-owner ...) e depois usar tcpara modelar o tráfego. Também "--sid-owner" pode ser usado para incluir threads e filhos desse processo.

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

Coincidir --pid-owner
Kernel 2.3, 2.4, 2.5 e 2.6
Exemplo de iptables -A OUTPUT -m owner --pid-owner 78
Explicação Essa correspondência é usada para corresponder aos pacotes com base no ID do processo (PID) responsável por eles. Essa correspondência é um pouco mais difícil de usar, mas um exemplo seria apenas para permitir que o PID 94 envie pacotes da porta HTTP (se o processo HTTP não for encadeado, é claro). Como alternativa, poderíamos escrever um pequeno script que pegue o PID de uma saída ps para um daemon específico e, em seguida, adicione uma regra para ele. Por exemplo, você pode ter uma regra, como mostrado no exemplo Pid-owner.txt

Mircea Vutcovici
fonte
Eu acho que isso está relacionado à minha solução para a melhor maneira de fazer isso. --pid-owner na verdade não seleciona com base no processo, mas no proprietário do processo. Eu precisaria criar um usuário especial para iniciar o processo e, em seguida, filtrar com base nesse proprietário, para ter certeza de que estou modelando o tráfego apenas a partir desse processo específico e não, por exemplo, vários daemons que poderiam ter sido iniciados a partir de um usuário genérico.
23412 Wesley
@ Wesley Não é isso que a página de manual diz: " --pid-owner processidCorresponde se o pacote foi criado por um processo com o ID de processo fornecido ". Você pode usar o seguinte
comando
Essa resposta seria muito melhor se incluísse um exemplo de como usar o iptables e o tc para esse fim. O iptables -A OUTPUT -m owner --pid-owner 78exemplo dado não parece completo (como apenas corresponde aos pacotes, não diz como "marcá-los") e tcnão é explicado.
Ajedi32
Para marcar um pacote, você precisa adicionar algo como -j MARK --set-mark 1. Para mais detalhes veja: wiki.archlinux.org/index.php/...
Mircea Vutcovici
40

Uma opção que eu acabei de descobrir é usar o trickle .

trickle é um shaper de largura de banda leve e portátil para usuários. Pode ser executado no modo colaborativo (junto com o truque) ou no modo autônomo.

trickle funciona tirando proveito do pré-carregamento do carregador unix. Essencialmente, ele fornece ao aplicativo uma nova versão da funcionalidade necessária para enviar e receber dados por soquetes. Em seguida, limita o tráfego com base no atraso no envio e recebimento de dados por um soquete. trickle é executado inteiramente no espaço do usuário e não requer privilégios de root.

Wesley
fonte
1
Foi esse que resolveu meu problema. Eu estava tendo um problema com o daemon do bitcoin sugando aleatoriamente toda a minha largura de banda quando um cliente decidiu que eu era a pessoa de quem ele deveria baixar o blockchain inteiro.
omniforme
O tricklelink que você forneceu leva a um 404.
Geremia 27/11
Corrigi o link quebrado (substituindo-o por um link da Wayback Machine).
G-Man diz 'Reinstate Monica'
3
Trickle parece estar no github agora: github.com/mariusae/trickle
Cheetah
ousudo apt-get install trickle
ggll 6/01/17
22

Se você pode gravar em um canal (ou stdout), pode instalar o pvcomando (visualizador de canal). Foi originalmente escrito para exibir o progresso dos dados transferidos através de um pipe.

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
fonte
Esta é realmente a resposta que acho que vou usar! No entanto, não é exatamente uma resposta para a pergunta específica que fiz originalmente. Infelizmente, a questão meio que se transformou, mas ainda estava focada em limitar a velocidade da rede de um processo. No entanto, você pode contribuir para esta nova pergunta que fiz: unix.stackexchange.com/q/34174/4232
Wesley
Obrigado! Eu estava fazendo uma coisa semelhante e acabei fazendo ssh my-remote-server bash -c "'find / -xdev|cpio -o|gzip -c1'"|pv --rate-limit 1M > my-remote-root.cpio.gz.
Clacke
1
Poderia também combiná-lo com o ionice, mas não era permitido nesse servidor em 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

Eu uso o rsync com a opção --bwlimit = KBPS pelo mesmo motivo.

Nossa Ethernet de 1 Gbit é facilmente capaz de inundar nosso antigo RAID SCSI320 DAS e, essencialmente, o DOS é algumas de nossas caixas de produção mais antigas que dependem dele para suas lojas NFS.

Magalhães
fonte
4

Como você está transferindo os dados? (rsync sobre ssh? scp? sftp? outra coisa?)

O rsync permitirá que você limite a largura de banda (consulte a opção --bwlimit = KBPS). rsync -e ssh --bwlimit ..

Como alternativa, você pode configurar um qdisc ou equivalente para limitar a taxa de fantasia, mas suspeito que, no seu caso, isso seria um exagero grave. A documentação sobre isso está disponível no HOWTO Linux Advanced Routing and Traffic Control

Devdas
fonte