タグ・アーカイブ: bash

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

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をかける場合には、バイト数による影響も考えなければなりません。

履歴書書いたりするときに「あれー、2000年って平成何年だっけ?」とか、100年前って和暦で言うところの何年なんだ?と「ふ」とした疑問がわいたりすることがあるでしょう。

そんなあなたに、wareki.shを作りました。

※ ブログに書いたときにダブルクォートなどがサニタイズされてしまったので、再度UPしました。


#!/bin/sh

LANG=ja_JP.utf8
case $1 in
[0-9]*) date +%Ec --date=$1'years ago' | cut -b 1-22
| sed -e "s/年[0-1][0-9]月[0-3][0-9]日/年/g;s/$/t西暦$(LANG=C date +%Y --date=$1'years ago')年/g"
| sed s/年 [1-3]/年't'/g ;;
[[:alpha:]]) echo "USAGE $0 1";;
esac

最初に端末を日本語UTF-8環境にしていますが、EUC-JPな環境の人は、ここを書き換えてください。また、和暦の右側に西暦を表示することで、和暦と西暦の対応が見やすくなっています。

使い方はいたって簡単、wareki.shのあとに、引数として正の整数を与えてやってください。今年の値を出す場合は、0を与えます。たとえば・・・

$ wareki.sh 10
平成10年        西暦1998年
$ wareki.sh 100
明治41年        西暦1908年

とまあ、こんなあんばいです。なお、CentOS4.xでは和暦は明治35年以降が表示されます。今年から100年前までの一覧表を出すには

$ for i in `echo {0..100}`; do ~/bin/wareki.sh $i; done

これでOKです。
ね、簡単でしょ?