[Linux]trickleを使ってプログラムごとにアドホックに帯域制御する

ネットワークの帯域制御は用途や手段に応じて様々な手段が存在する

今回は、Linux 環境下で trickle を使ってプログラム単位でアドホックに帯域制御する方法をメモ。

trickle とは

  • ユーザースペースで動作するトラフィックシェイパー
  • ダイナミックローダーのプリローダー(LD_PRELOAD)を利用して socket の送受信に割り込んでトラフィックを制御
  • プログラム単位で制御

trickle をインストール

RedHat Installation

epel レポジトリからインストールする

# yum info trickle
...
Installed Packages
Name        : trickle
Arch        : x86_64
Version     : 1.07
Release     : 19.el6
Size        : 89 k
Repo        : installed
From repo   : epel
Summary     : Portable lightweight userspace bandwidth shaper
URL         : http://monkey.org/~marius/pages/?page=trickle
License     : BSD with advertising
Description : trickle is a portable lightweight userspace bandwidth shaper.
            : It can run in collaborative mode or in stand alone mode.
            :
            : trickle works by taking advantage of the unix loader preloading.
            : Essentially it provides, to the application,
            : a new version of the functionality that is required
            : to send and receive data through sockets.
            : It then limits traffic based on delaying the sending
            : and receiving of data over a socket.
            : trickle runs entirely in userspace and does not require root privileges.
# yum install trickle --enablerepo=epel

Ubuntu Installation

何も考えずに apt-get でインストールできる

# apt-get install trickle

trickle を使う

  • standalone mode(単一プログラムでの制御)
  • collaborative mode(複数プログラム合算での制御)

の2モードがある。

standalone mode

プログラムごとにトラフィックを制御する
trickle が一番得意とすると思われる用途

実行例

$ trickle -s -d {DOWNLOAD_LIMIT(KB/s)} command
$ trickle -s -u {UPLOAD_LIMIT(KB/s)} command
$ trickle -s -u {UPLOAD_LIMIT(KB/s)} -d {DOWNLOAD_LIMIT(KB/s)} command

要は、コマンドの先頭に trickle {制御条件} を追加するだけと非常にお手軽。

-s は standalone mode を指定するオプション。

wget で実際の動きを確認してみる。(wget自体にも帯域を制御するオプションは存在するが、今回は使わない)

なにも制御しなかった時

$ wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso
--2015-05-13 12:09:32--  http://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso
Resolving stable.release.core-os.net... 64.233.187.128
Connecting to stable.release.core-os.net|64.233.187.128|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 169869312 (162M) [application/x-iso9660-image]
Saving to: `coreos_production_iso_image.iso'
22% [=======>                               ] 38,317,350   719K/s  eta 1m 50s

ダウンロード速度は 719K/s となっている

下りを 100KB/s に制限した時

$ trickle -s -d 100 wget http://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso
--2015-05-13 12:11:12--  http://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso
Resolving stable.release.core-os.net... 64.233.187.128
Connecting to stable.release.core-os.net|64.233.187.128|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 169869312 (162M) [application/x-iso9660-image]
Saving to: `coreos_production_iso_image.iso.1'

 0% [                                       ] 1,196,032   99.3K/s  eta 27m 15s ^C

ダウンロード速度は 99.3K/s  に絞られている。
期待通り。

collaborative mode

次に collaborative mode の動作を確認

trickled デーモンを起動し、以降、非スタンドアローンモードで trickle コマンドを実行すると、デーモン起動時に指定した条件を満たしつつ各プログラムが帯域制御される。

デーモンの起動

$ trickled -d {DOWNLOAD_LIMIT(KB/s)}
$ trickled -u {UPLOAD_LIMIT(KB/s)}
$ trickled -u {UPLOAD_LIMIT(KB/s)} -d {DOWNLOAD_LIMIT(KB/s)}
$ trickled -d 10

trickle はスタンドアローン-sオプションを外して起動すれば OK

$ trickle curl -o a http://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso

大きなファイルをダウンロード、細かいインタラクティブなやりとりが何度も発生、な
どプログラムによって traffic shape のかけ方を変えたい時がある。

次の様な設定ファイルを用意し、trickled 起動時に $ trickled -c /path/to/trickled.conf -u 10 -d 10 というように -c オプ ションで指定する。

[ssh]
Priority = 1
Time-Smoothing = 0.1
Length-Smoothing = 2
[wget]
Priority = 8
Time-Smoothing = 5
Length-Smoothing = 20
  • priority が低いプログラムほど優先される。
  • Time-Smoothing は traffic shape する塊を時間(秒)で指定。
  • Length-Smoothing は traffic shape する塊を転送量(KB)で指定。

備考

“trickle: Could not reach trickled, working independently: No such file or directory” エラー

trickled デーモンが起動していない状態で -s オプションなしに trickle を起動すると、上記警告メッセージが表示され、スタンドアローンモードで起動する。

明示的に trickle オプションを指定すれば、このメッセージは表示されなくなる。

LD_PRELOAD をちら見

trickle-overload.c がプリロードされる関数群のコア。
trickle_ld_reload

“Trickle: A Userland Bandwidth Shaper for Unix-like Systems” (USENIX 2005) の Figure 1 から。

trickle を起動し、環境変数 LD_PRELOAD が利用されていることを確認。

# strings /proc/1491/environ
...
_=/usr/bin/trickle
TRICKLE_DOWNLOAD_LIMIT=10
TRICKLE_UPLOAD_LIMIT=10
TRICKLE_VERBOSE=0
TRICKLE_WINDOW_SIZE=200
TRICKLE_ARGV=wget
TRICKLE_SOCKNAME=
TRICKLE_TSMOOTH=3.0
TRICKLE_LSMOOTH=20
LD_PRELOAD=/usr/lib64/trickle/trickle-overload.so <- HERE

PID を指定して、ライブラリの一覧を列挙

# lsof -p 1491 | awk '{print $9}' | grep '\.so'
/lib64/libnss_dns-2.12.so
/lib64/libnss_files-2.12.so
/lib64/libselinux.so.1
/lib64/libresolv-2.12.so
/lib64/libkeyutils.so.1.3
/lib64/libkrb5support.so.0.1
/lib64/libpthread-2.12.so
/lib64/libz.so.1.2.3
/lib64/libk5crypto.so.3.1
/lib64/libcom_err.so.2.1
/lib64/libkrb5.so.3.3
/lib64/libgssapi_krb5.so.2.2
/lib64/libnsl-2.12.so
/lib64/libc-2.12.so
/lib64/librt-2.12.so
/lib64/libdl-2.12.so
/usr/lib64/libcrypto.so.1.0.1e
/usr/lib64/libssl.so.1.0.1e
/usr/lib64/trickle/trickle-overload.so <- HERE
/lib64/ld-2.12.so

References

man

  • TRICKLE(1) : trickle – a lightweight userspace bandwidth shaper
  • TRICKLED(8) : trickled – userspace bandwidth manager daemon
  • TRICKLED.CONF(5) : trickled.conf – format of the configuration file used by trickled(8).
Advertisements
Tagged with: , ,
Posted in linux

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
%d bloggers like this: