bash: 2008年7月アーカイブ

※ 2008/07/19 追記
PHPでもっと凄いスクリプト書いてる人発見 (*゚Д゚) ムホムホ

暇つぶしの勢いで作った。後悔はしていない。どれもアホっぽいとか言うの禁止な。

#!/bin/bash
# 3のつく数字と3の倍数でアホになるスクリプト


# 40まで数える
for i in `echo {1..40}`
do
# 数えた数字が3のつく数かどうかをgrepに引っ掛けて判定する
if [ `echo $i | grep 3` ];
    then
        # アホになる
        echo \(っ。ω゚\)っ<$i
        sleep 1
    else
    # 数えた数字を3で割って余りが出ないか、grepに引っ掛けて判定する
    if [ `echo "scale=1; $i/3" | bc | grep \.0` ];
    # 余りが発生しない(3の倍数だ)とアホになる
    then
        echo \(っ。ω゚\)っ<$i
        sleep 1
    # 3のつく数や3の倍数じゃない数は、普通にカウントする
    else
        echo \(っ´∀`\)っ<$i
        sleep 1
    fi
fi
done


おーもろー!
計算とか見積ってほど大げさじゃあないのですが・・・。

nullpopopoを動かしているサーバでは、ローカルのコンテンツをバックアップ領域にrsyncしていますが、ファイルの数が多くなるほどメモリを消費するのが悩みの種なのです。幸い"out of memory"でrsyncが中断したり他のプロセスを巻き添えにして落っこちたりしないのですが、ここによると

> 大雑把に言うと、rsync はファイルリストにあるファイル毎に約100バイトを消費します。
> これは rsync がそれぞれのファイルについての重要部分の詳細を全て持っている、内部リスト
> 構造を構築するからです。それが絶えず横断するため、rsync はメモリーに構造を維持することが
> 必要になります。

とのこと。そこで、ファイル数に100バイトを掛け算して、rsync実行時にどれだけメモリを食うのかを調べてみました。

まずはドキュメントルートでファイル数を数えます。

$ sudo find * | wc -l
24720

現在、24720個のファイル、ディレクトリが存在しています。それでは単純に100を掛けてみましょう。exprコマンドで掛け算を行うときは、「*」の前に「\」でエスケープしてやる必要があります。また、数字と加減乗除記号との間はスペースをあけましょう。

$ expr `sudo find * | wc -l` \* 100
2472000

1回のrsync実行で、2472000バイトのメモリを消費します。バイト単位じゃ見にくいので、キロバイト(KB)単位で表示する場合、上記の値を1024で割ってやります。

$ expr `sudo find * | wc -l` \* 100 / 1024
2414

2414キロバイト(KB)のメモリを消費するぞと言っています。次に、キロバイト(KB)をメガバイト(MB)に換算・・・つまり、もっかい1024で割ってあげることにします。

$ expr `sudo find * | wc -l` \* 100 / 1024 / 1024
2

もしくは

$ expr `sudo find * | wc -l` \* 100 / `expr 1024 \* 1024`
2

でも値を求めることができます。

はい、2メガバイト(MB)メモリを食うぞと言っています。

これでファイルのバックアップにかかるメモリの量を見積もることができますね。それでは次に、rsyncを実行してどれだけ時間がかかるかを計測します。各コマンドを実行する前に「time」コマンドを付け加えてやります。実例は以下の通りです。

まず、定期rsyncを行うスクリプトを以下のように作りました。

# cat local_sync
=================================== ここから ===================================
#!/bin/sh
# バックアップ先(バックアップサーバが取りに来るディレクトリ)
ARCDIR=/home/backup/arc
# バックアップ元のディレクトリ
TARGDIR=/var/www/vhosts

# バックアップ先ディレクトリがなければ作成する
if [ -d $ARCDIR ];
  then
    :
  else
    mkdir $ARCDIR
fi

# バックアップ元のディレクトリ(バーチャルホスト)ごとにバックアップを行う
for TARG in `ls $TARGDIR`
do
rsync -auzv --delete $TARGDIR/$TARG $ARCDIR
done
=================================== ここまで ===================================

そして、時間計測を行いながら上記スクリプトを実行します。

# time ./local_sync > /dev/null

real    0m1.498s
user    0m0.294s
sys     0m0.949s

今回は、ファイルの追加削除が少なかったのか、それほど時間がかかりませんでした。1秒ちょっとしかかかっていません。なお、上記スクリプトの出力結果を/dev/nullに捨てないと、

sent 5381 bytes  received 20 bytes  10802.00 bytes/sec
total size is 278360  speedup is 51.54
building file list ... done

みたいな出力が出てきます。

もしrsyncの実行時間を計測する必要があったら、同程度なスペックのマシンを用意して、適当なディレクトリでtouchコマンドを使ってファイルを大量に作ってやり、さらに適当なディレクトリへrsyncをかけてやり(勿論timeコマンドつきで)、時間計測をしてやればよいでしょう。必ずしも同じファイルを用意する必要はありません。rsyncはファイルのバイト数ではなくファイルの数に影響されますので。勿論、ネットワーク越しにrsyncをかける場合には、バイト数による影響も考えなければなりません。

カスタム検索

カレンダー



このアーカイブについて

このページには、2008年7月以降に書かれたブログ記事のうちbashカテゴリに属しているものが含まれています。

前のアーカイブはbash: 2008年6月です。

次のアーカイブはbash: 2008年8月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.01