2012年7月アーカイブ

知っている人多いと思うけど、よく使うイディオム

$ .. | sort | uniq -c | sort -nr

「sort | uniq -c」で重複行をカウントでき、さらに「sort -n」で行を数字と見なしてソートすることで重複行のカウントで並べなおすことができます

例えば、Webサーバのaccess_logからよくアクセスしてくるIPアドレスを集計してランキングを表示するには以下のよう書けます

$ tail -10000 access_log |cut -f 1 -d ' ' | sort |uniq -c|sort -nr|head -10
209 207.46.204.192
203 59.106.108.114
202 66.249.69.108
171 199.59.149.168
137 78.46.45.35
129 66.249.69.65
120 66.249.69.135
117 66.249.69.131
116 66.249.69.122
116 66.249.69.121

さくっとできて便利ですね。

ちなみに、「66.249」から始まるIPアドレスはgooglebotさんです。覚えておきましょう

PCIeに接続するタイプのSSD、Intel SSD 910 800GBを借りる事ができたのでベンチマーク結果置いておきますね

サーバは Intel Xeon L5630 を2つ積んで、HTが有効なので16コアに見えます。ベンチマークは namikawa氏の「噂の高速SSDを積んだAmazon EC2インスタンスのI/Oベンチマークをとってみた」とほぼ同じ条件で取ってみました。

OSは CentOS 6.3 です。

Intel SSD 910 800GBは200GBのデバイスが4つに見えます。dmesgで以下のように表示されています。

scsi 1:0:0:0: Direct-Access     INTEL(R)  SSD 910 200GB   a40D PQ: 0 ANSI: 6
scsi 1:0:0:0: SSP: handle(0x0009), sas_addr(0x5000cca013005bbd), phy(0), device_name(0x5000cca013005bbf)
scsi 1:0:0:0: SSP: enclosure_logical_id(0x5001517bb289a8b0), slot(0)
scsi 1:0:0:0: qdepth(254), tagged(1), simple(1), ordered(0), scsi_level(7), cmd_que(1)
scsi 1:0:1:0: Direct-Access     INTEL(R)  SSD 910 200GB   a40D PQ: 0 ANSI: 6
scsi 1:0:1:0: SSP: handle(0x000a), sas_addr(0x5000cca013005bb9), phy(7), device_name(0x5000cca013005bbb)
scsi 1:0:1:0: SSP: enclosure_logical_id(0x5001517bb289a8b0), slot(7)
scsi 1:0:1:0: qdepth(254), tagged(1), simple(1), ordered(0), scsi_level(7), cmd_que(1)
scsi 1:0:2:0: Direct-Access     INTEL(R)  SSD 910 200GB   a40D PQ: 0 ANSI: 6
scsi 1:0:2:0: SSP: handle(0x000b), sas_addr(0x5000cca013005bb1), phy(3), device_name(0x5000cca013005bb3)
scsi 1:0:2:0: SSP: enclosure_logical_id(0x5001517bb289a8b0), slot(3)
scsi 1:0:2:0: qdepth(254), tagged(1), simple(1), ordered(0), scsi_level(7), cmd_que(1)
scsi 1:0:3:0: Direct-Access     INTEL(R)  SSD 910 200GB   a40D PQ: 0 ANSI: 6
scsi 1:0:3:0: SSP: handle(0x000c), sas_addr(0x5000cca013005bb6), phy(5), device_name(0x5000cca013005bb7)
scsi 1:0:3:0: SSP: enclosure_logical_id(0x5001517bb289a8b0), slot(5)
scsi 1:0:3:0: qdepth(254), tagged(1), simple(1), ordered(0), scsi_level(7), cmd_que(1)

ベンチマーク準備

まずfioとxfsのユーティリティを導入します

$ wget http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS/fio-2.0.7-1.el5.rf.x86_64.rpm
$ sudo rpm -Uvh fio-2.0.7-1.el5.rf.x86_64.rpm
$ sudo yum install -y xfsprogs

4つのデバイスをRAID0にして、xfsでフォーマットします

$ mdadm --create --verbose --assume-clean /dev/md0 --chunk=256 --level=0 --raid-devices=4 /dev/sdb /dev/sdc /dev/sdd /dev/sde
$ mkfs.xfs -f -b size=4096 -i size=512 -l size=64m /dev/md0
$ mount -t xfs -o noatime,logbufs=8 /dev/md0 /data

ベンチマークはnamikawa氏と同じように以下のコマンドを順に実行しました

$ fio -filename=/data/test2g -direct=1 -rw=read -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1
$ fio -filename=/data/test2g -direct=1 -rw=write -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1
$ fio -filename=/data/test2g -direct=1 -rw=randread -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1
$ fio -filename=/data/test2g -direct=1 -rw=randwrite -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1
$ fio -filename=/data/test2g -direct=1 -rw=read -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1
$ fio -filename=/data/test2g -direct=1 -rw=write -bs=32m -size=2G -numjobs=16 -runtime=10 -group_reporting -name=file1

結果

計測した結果が以下です

Benchmark Type Bandwidth IOPS
4k, sequential read 639.4MB/s 159846
4k, sequential write 119.7MB/s 29915
4k, randam read 664.5MB/s 166134
4k, randam write 112.7MB/s 28181
32m, sequential read 1285.7MB/s 40
32m, sequential write 1464.3MB/s 45


ReadのIOPSが15万越え、帯域幅は1GB/sを大きく超えます。
この結果と今の価格をどのように考えるかちょっと悩みどころですね

とあるサーバでロードアベレージが上がったときに何が起きているか知りたくなったので書いてみました。他に似たツールがあれば教えて欲しいです

インストール

インストールはcpanmを使います

$ cpanm App::LoadWatcher

cpanmが入っていないなら

$ curl -L http://cpanmin.us/ | perl - App::LoadWatcher

とすると楽です

使い方

ロードアベレージが「0.6」以上のときにuptimeを表示するには

$ load_watcher -l 0.6  -- uptime

こんな感じです。ハイフン2つ書いたあとにコマンドを書きます

オプションは

-load -l     = load average    ロードアベレージの閾値
-interval -i = interval second ロードアベレージを確認する間隔(秒)
-continue -c                   デフォルトではコマンド実行後に終了するが、終了させずに繰り返し動作させる

となります

今回、負荷の上がったときのMySQLの通信を見たかったので

$ sudo load_watcher -l 1 -- 'tcpdump -s 65535 -x -nn -q -tttt -i any -c 100000 port 3306 > /tmp/mysql.tcp'

こんな感じで実行しました。



ちなみに最初はこんなシェルを書いて実行してた。

while :
do
  LOAD=$(cat /proc/loadavg |awk '{print $1*100}')
  if [ $LOAD -gt 80 ]; then
      tcpdump -s 65535 -x ...
      exit
  fi
  sleep 5
done

シェル力が低くてすみません