前天一个研发的兄弟问我,实现完成了ClickHouse数据备份的功能,然后把数据上传到HDFS之类的文件系统中,但是提交给测试,发现程序把网卡带宽跑满了,就向我咨询在Linux下是否有可以限制某个命令操作的带宽速率的,然后就推荐了trickle
这个命令给研发同学,这里我也推荐给大家。
毕竟站在巨人的肩膀上更轻松,如果只是针对固定的单一文件读取,还可以利用编程语言实现控制读取速率,如果只是利用单纯封装好了的工具做多文件的备份传输,还是要花点功夫和需要深度的编程功夫的,所以还是Linux世界好,都有前人贡献的开源工具。
认识Trickle
在类Unix系统下没有像Windows使用360那样去限制某个软件的速度,所以Trickle就诞生了。
Trickle是类Unix系统的用户级带宽控制工具, 比如用来限制如Firefox、 FTP 、 SSH以及其他使用网络带宽的程序的带宽;通过Trickle可以设置某个软件的网速,但是前提是通过Trickle命令连带启动这个软件才可以,不能中途去设置。
Trickle是如何工作的
Trickle通过控制socket数据读写量来控制和限制应用的上传/下载速度。它使用另一个版本的BSD套接字API,但区别就是trickle还管理socket调用。
但是要注意的是trickle使用动态链接和加载,所以它只对于使用glibc库
的程序有用。由于trickle可以设置数据在socket上的传输延迟,所以它可以用来限制一个应用的网络带宽。
Trickle通过在程序运行时,预先加载一个速率限制 socket 库 的方法,trickle 命令允许你改变任意一个特定程序的流量。trickle 命令有一个很好的特性是它仅在用户空间中运行,这意味着,你不必需要 root 权限就可以限制一个程序的带宽使用。要能使用 trickle 程序控制程序的带宽,这个程序就必须使用非静态链接库的套接字接口。当你想对一个不具有内置带宽控制功能的程序进行速率限制时,trickle 就派上用场了。
Trickle不能做什么
Trickle不能用于限制使用UDP协议的应用的带宽,它只可用于TCP协议的连接,但是你要知道它也并不是对所有的TCP连接有效。如果你仔细看了Trickle是如果工作的
,你可以猜到原因是什么,所以你还得记住trickle只对使用Glibc库应用有效。
还要说明一下, trickle无法工作在使用静态链接的可执行程序上。
确定Trickle是否可运行在某个特定应用上, 案例如下:
$ ldd /usr/bin/wget |grep --col libc.so
libc.so.6 => /lib64/libc.so.6 (0x00007f461cf5f000)
ldd工具可以帮我们找出某个特定的程序是否使用了libc.so库, 如果程序使用了这个库,就可以使用trickle来限制它的网络带宽使用。ldd命令用于打印每个程序需要的共享库, 如果你是一个好奇宝宝,那么你可以使用man命令来找出关于ldd工具的更多信息,做编译安装程序和可移植的时候ldd命令很管用。
安装和使用Trickle
在 Ubuntu、Debian 及其衍生发行版中安装 trickle:
$ sudo apt-get -y install trickle
在 Fdora 或 CentOS/RHEL (带有 EPEL 软件仓库):
$ sudo yum -y install trickle
源码编译安装:
$ wget https://codeload.github.com/mariusae/trickle/zip/master
$ mv master trickle-master.zip
$ unzip trickle-master.zip
$ yum -y install autoconf automake libtool libevent-devel
$ autoreconf -if
$ ./configure
$ make
$ make install
Trickle Github地址: https://github.com/mariusae/trickle
Trickle基本使用方法,仅需简单地把 trickle 命令(及速率参数)放在你想运行的命令之前即可。
$ trickle -d <download-rate> -u <upload-rate> <command>
这就可以将的下载和上传速率限定为特定值(单位 KBytes/s)。
不使用的情况下:
[root@hctech ~]# wget http://10.0.1.25/iso/centos/CentOS-7.7-x86_64-Minimal-1908.iso
--2020-07-01 02:00:03-- http://10.0.1.25/iso/centos/CentOS-7.7-x86_64-Minimal-1908.iso
Connecting to 10.0.1.25:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 987758592 (942M) [application/octet-stream]
Saving to: ‘CentOS-7.7-x86_64-Minimal-1908.iso’
36% [=================================> ] 364,000,528 108MB/s eta 6s ^C
使用情况下:
[root@hctech ~]# trickle -d 1000 wget http://10.0.1.25/iso/centos/CentOS-7.7-x86_64-Minimal-1908.iso
trickle: Could not reach trickled, working independently: No such file or directory
--2020-07-01 02:05:31-- http://10.0.1.25/iso/centos/CentOS-7.7-x86_64-Minimal-1908.iso
正在连接 10.0.1.25:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:987758592 (942M) [application/octet-stream]
正在保存至: “CentOS-7.7-x86_64-Minimal-1908.iso”
3% [==> ] 37,461,428 981KB/s 剩余 15m 46s^C
如果利用ssh的命令,比如rsync或scp,提示如下情况:
Read from socket failed: Resource temporarily unavailable" on ssh connection
这种情况下加-s
参数即可,例如:
trickle -s -u 1000 rsync -avP -e'ssh -p22' ./xxx.iso root@10.0.1.25:/data/iso/
最后, trickle 也可以以守护进程模式运行,在该模式下,它将会限制所有通过 trickle 启动且正在运行的程序的总带宽之和。启动 trickle 使其作为一个守护进程(例如, trickled):
trickled -s -u 1000 rsync -avP -e'ssh -p22' ./xxx.iso root@10.0.1.25:/data/iso/
但是要配置配置文件/etc/trickled.conf
,实例如下:
# trickled configuration file example
# uncomment p to use it
[ssh]
Priority = 1
Time-Smoothing = 0.1
Length-Smoothing = 2
具体可以自行研究一下,我这里没有这种需求,但是想声明一下一旦 trickled
守护进程在后台运行,你便可以通过 trickle 命令来启动其他程序。假如你通过 trickle 启动一个程序,那么这个程序的最大下载速率将是 1000 KB/s
, 假如你再通过 trickle 启动了另一个程序,则每个程序的(下载)速率极限将会被限制为 500 KB/s, 这里没有具体实践,我说的都是错的。
加钱白嫖再介绍一下wondershaper
另一种控制你的带宽资源的方式是在每一个接口上限制带宽。这在你与其他人分享你的网络连接的上行带宽时尤为实用。同其他一样,Linux 有一个工具来为你做这件事。wondershaper就是干这个的。
wondershaper
实际上是一个 shell 脚本,它使用 tc 来定义流量调整命令,使用 QoS 来处理特定的网络接口。外发流量通过放在不同优先级的队列中,达到限制传出流量速率的目的;而传入流量通过丢包的方式来达到速率限制的目的。
TC案例:
# 限制eth0网卡的带宽为50kbit:
$ /sbin/tc qdisc add dev eth0 root tbf rate 50kbit latency 50ms burst 1000
事实上,wondershaper
的既定目标不仅仅是对一个接口增加其带宽上限;当批量下载或上传正在进行时,wondershaper还试图去保持互动性会话如 SSH 的低延迟。同样的,它还会控制批量上传(例如, Dropbox 的同步)不会使得下载“窒息”,反之亦然。
在 Ubuntu Debian 及其衍生发行版中安装 wondershaper:
$ sudo apt-get install wondershaper
在 Fdora 或 CentOS/RHEL (带有 EPEL 软件仓库) 中安装 wondershaper:
$ sudo yum install wondershaper
wondershaper 的基本使用如下:
$ sudo wondershaper <interface> <download-rate> <upload-rate>
将 eth0 的最大下载/上传带宽分别设定为 1000Kbit/s 和 500Kbit/s:
$ sudo wondershaper eth0 1000 500
你也可以通过运行下面的命令将速率限制进行消除:
$ sudo wondershaper clear eth0
假如你对 wondershaper
的运行原理感兴趣Linux Geek Man,你可以阅读其脚本源文件(/sbin/wondershaper)。
当然iptables --limit
和 ethtool
也可以达到限制网卡带宽的效果,可以自行实践,感兴趣的话。
最后
这两工具的使用都很简单,都为用户提供了一个快速且容易的方式来调整或限制流量。对于那些想更多地了解如何在 Linux 中进行速率控制的读者,可以阅读:https://www.lartc.org/lartc.html。