Edited at

Linuxサーバのパフォーマンス測定スクリプト

More than 3 years have passed since last update.

書けば書くほどニッチな方向に向かってる気がしています。

果たして需要があるのでしょうか?

脱力モードで書きますね( ´ー`)ンフフ

2014-09-03 ジワジワ来てるので結果集計用エクセルを自分で用意してね☆(ゝω・)vキャピってのが心苦しくなって来ました。

Evernote共有で申し訳ないですが一式ファイルへのリンク乗せておきます!

》 監視ロガー20140903.zip https://www.evernote.com/shard/s12/sh/1180dd43-4d5a-4461-938f-45bb405fc715/bb939159f7a2b127


パフォーマンス測定!?

困りました。

そんなんした事無いのです。

色々と調べた結果、自分で書いちゃうのがベストかなと…。

1. 測定用シェルと2. 結果を処理するエクセルの2つを使用します。


AWSのCPU負荷測定について

AWSは 50%us 近辺でCPU負荷MAXなので注意します。

cpu項目に %us と右端に %stとあります。

usとstの合計がcpu負荷合計と見ないと大変な事になります(白目)

stは Steal Time で仮想CPUのawsならではの項目になるのかな?

Steal Time を見落とすと死ぬぜ!死ぬなよ!

追記:検証してるアルパカさんがいた

microインスタンスはlimitかけると大きくパフォーマンスが向上する(※再追記あり) - アルパカDiary

http://d.hatena.ne.jp/toritori0318/20140312/1394634304

Who Stole my CPU? Few Basics on CPU Steal Time | I am OnDemand http://iamondemand.com/blog/who-stole-my-cpu/


参考コンソール1

参考にコンソール貼り付けようと思いましたが、調整済みで Steal Time 出ていません。

なんの参考にもなりません。

ですが、瞬間的ですが CPU 71%出てます。すごいです。

この場合CPUが4発なので load average値が4.0以下になっていれば適正値です。

load averageが4.0を超えると加速度的にやばいことになり Steal Time が増加するんじゃないかな…。

※ 適当なこと言ってたらご指摘頂きたいです

ちなみに m2.2xlarge です。すごく早いです。


top_on_aws

top - 00:43:24 up 64 days, 22:49,  1 user,  load average: 1.63, 1.40, 0.91

Tasks: 88 total, 1 running, 87 sleeping, 0 stopped, 0 zombie
Cpu0 : 2.7%us, 2.7%sy, 0.0%ni, 84.6%id, 10.1%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 71.6%us, 0.7%sy, 0.0%ni, 16.4%id, 11.4%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu2 : 0.0%us, 0.7%sy, 0.0%ni, 98.3%id, 1.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu3 : 22.5%us, 1.3%sy, 0.0%ni, 25.5%id, 50.7%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 35062104k total, 34898468k used, 163636k free, 86940k buffers
Swap: 0k total, 0k used, 0k free, 10977060k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6316 mysql 20 0 24.2g 22g 5092 S 101.4 66.3 8465:20 mysqld
927 root 20 0 0 0 0 S 0.3 0.0 122:18.58 jbd2/xvda1-8
15802 root 20 0 115m 2612 1124 S 0.3 0.0 54:52.77 bash
1 root 20 0 19360 672 364 S 0.0 0.0 0:04.07 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:11.83 ksoftirqd/0
4 root 20 0 0 0 0 S 0.0 0.0 1:36.49 kworker/0:0
5 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/u:0



参考コンソール2

load averageの話が出てきたので負荷が高い場合のコンソールも持ってきました。

mysqlを同時に6スレッド?だったけな?なので待ちが発生しLAも高くなっています。

Qiitaへ投稿したスレッドコントロール シェルスクリプトで同時Job数の調整をしています。

※わりと適当なこと言っているので、ちゃんと調べてください

このサーバも m2.2xlarge です(複数サーバ使ってます)


ShellScript - シェルスクリプトでコマンド多重コントロール - Qiita http://qiita.com/TanukiTam/items/b64e0669e479c26d4790



top_on_aws

top - 00:50:22 up 78 days, 17:10,  1 user,  load average: 3.12, 1.81, 1.25

Tasks: 142 total, 1 running, 140 sleeping, 0 stopped, 1 zombie
Cpu0 : 26.1%us, 11.7%sy, 0.0%ni, 19.1%id, 43.1%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 22.7%us, 6.0%sy, 0.0%ni, 29.3%id, 41.7%wa, 0.0%hi, 0.0%si, 0.3%st
Cpu2 : 42.8%us, 19.7%sy, 0.0%ni, 19.1%id, 18.4%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu3 : 26.0%us, 10.1%sy, 0.0%ni, 2.7%id, 60.8%wa, 0.0%hi, 0.0%si, 0.3%st
Mem: 35062104k total, 34849072k used, 213032k free, 77040k buffers
Swap: 0k total, 0k used, 0k free, 10919984k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
730 mysql 20 0 23.8g 22g 5680 S 140.0 66.2 5935:28 mysqld
15130 hogehoge 20 0 103m 5312 1812 S 4.0 0.0 0:00.14 mysql
15178 hogehoge 20 0 102m 4456 1812 S 3.7 0.0 0:00.11 mysql
15226 hogehoge 20 0 102m 4508 1812 S 1.7 0.0 0:00.05 mysql
225 root 20 0 0 0 0 S 0.7 0.0 142:39.83 kswapd0
14415 hogehoge 20 0 11580 1644 1192 S 0.7 0.0 0:00.22 sh
929 root 20 0 0 0 0 S 0.3 0.0 81:55.33 jbd2/xvda1-8
5758 root 20 0 108m 2604 1108 S 0.3 0.0 196:41.45 bash
1 root 20 0 19360 1200 892 S 0.0 0.0 0:11.26 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:28.84 ksoftirqd/0
4 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0



測定用シェルスクリプト

時間単位にプロセス状況を引っこ抜いてログ出力します。

読みにくいのは後でエクセル整形するので問題ないです。

メモリやネットワークを使わなくても取得しておくと安心です。

使っているデータ

* /proc/stat

* /proc/meminfo

* /proc/net/dev - eth0

※ 形式が違っていたら自分で直して使って下さい


proc_total.sh

#!/bin/bash

#
# パフォーマンステストのために書き起こし
#
# System 状況を sleep x 毎に整形しログ出力する
# 別の excel に貼り付けて計算後に状況を確認する
#
# /proc/stat CPU使用率
# /proc/meminfo メモリ使用状況
# /proc/net/dev eth0トラフィック状況
#
LANG=C
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:
export LANG PATH
umask 022

HEADER='"date","time"'
# /proc/stat
HEADER=${HEADER}',"hostname","cpu","user","nice","system","idel","iowait","irq","softirq","steal","guest"'
# /proc/meminfo
HEADER=${HEADER}',|,"MemTotal","MemFree","Buffers","Cached","SwapCached","Active","Inactive","Active(anon)","Inactive(anon)","Active(file)","Inactive(file)","Unevictable","Mlocked","SwapTotal","SwapFree","Dirty","Writeback","AnonPages","Mapped","Shmem","Slab","SReclaimable","SUnreclaim","KernelStack","PageTables","NFS_Unstable","Bounce","WritebackTmp","CommitLimit","Committed_AS","VmallocTotal","VmallocUsed","VmallocChunk","AnonHugePages","HugePages_Total","HugePages_Free","HugePages_Rsvd","HugePages_Surp","Hugepagesize","DirectMap4k","DirectMap2M"'
# /proc/net/dev - eth0
HEADER=${HEADER}',|,"face","bytes","packets","errs","drop","fifo","frame","compressed","multicast","|bytes","packets","errs","drop","fifo","colls","carrier","compressed"'

echo $HEADER
while [ true ]
do
CPU=(`head -1 /proc/stat`)
CPUS="${CPU[0]},${CPU[1]},${CPU[2]},${CPU[3]},${CPU[4]},${CPU[5]},${CPU[6]},${CPU[7]},${CPU[8]},${CPU[9]}"
MEM=`awk '{ printf ",%d",$2 }' /proc/meminfo`
TFC=(`cat /proc/net/dev | grep eth0`)
TFCS="${TFC[0]},${TFC[1]},${TFC[2]},${TFC[3]},${TFC[4]},${TFC[5]},${TFC[6]},${TFC[7]},${TFC[8]},${TFC[9]},${TFC[10]},${TFC[11]},${TFC[12]},${TFC[13]},${TFC[14]},${TFC[15]},${TFC[16]}"
echo `date '+%Y/%m/%d,%H:%M:%S.%N'`","`hostname`",${CPUS},|${MEM},|,${TFCS}"
sleep 5s
#sleep 1m
done



出力テキスト結果加工エクセル

削除したつもりですが固有名称的ヤバいものがあれば教えて下さい。

あれ?エクセル貼れない?

自分で頑張って作ってください(うひ)


[Invalid file type: application/zip]()

Evernote共有で申し訳ないですが一式ファイルへのリンク乗せておきます!

》 監視ロガー20140903.zip https://www.evernote.com/shard/s12/sh/1180dd43-4d5a-4461-938f-45bb405fc715/bb939159f7a2b127

proc_totalログ解析.xlsx

proc_totalログ解析_サンプル.xlsx を参考にして下さい。


  • [貼り付け]シートにテキスト内容を貼り付け

  • [結果]シートで前後差分の計算結果が表示される

  • [結果]シートの必要な部分をコピー

  • 例:[250]シートのペースト開始位置を右クリックし値貼り付け

  • 後は適当に色つけたりチェックしたり

[説明]シートにちょっと説明


参考にいただいたソースと出典

その頃の明確な記憶が無いのでソースメモに残っている限りとなります。

ありがとうございました。

オレオレって人はご連絡下さい。


cpu_check.sh


cpu_check.sh

#!/bin/bash

CPU1=(`head -1 /proc/stat`)

while [ true ]
do
sleep 1
CPU2=(${CPU1[@]})
CPU1=(`head -1 /proc/stat`)

total=`expr ${CPU1[1]} - ${CPU2[1]} + ${CPU1[2]} - ${CPU2[2]} + ${CPU1[3]} - ${CPU2[3]} + ${CPU1[4]} - ${CPU2[4]}`

user=`echo "scale=2; (${CPU1[1]} - ${CPU2[1]}) * 100 / $total" | bc;`
nice=`echo "scale=2; (${CPU1[2]} - ${CPU2[2]}) * 100 / $total" | bc;`
sys=`echo "scale=2; (${CPU1[3]} - ${CPU2[3]}) * 100 / $total" | bc;`
idle=`echo "scale=2; (${CPU1[4]} - ${CPU2[4]}) * 100 / $total" | bc;`

printf "`date '+%Y/%m/%d d %H:%M:%S.%N'` `hostname` %3.2f %3.2f %3.2f %3.2f \n" $user $nice $sys $idle
done

# LinuxでCPU使用率を取得する。 - redtower's memo http://redtower.plala.jp/2010/06/06/linux-cpu.html
# ユーザモード(user)、低優先度のユーザモード(nice)、システムモード(sytem)、タスク待ち(idle)
# 1行目にCPUの状態を表す数値が格納されている。それ以外は「man proc」で確認すること。
#
# システムが起動してから現在までに消費した時間が記録されている
# cpu 21435 120 78001 50180652 13622 1 1321 69374 0
# | | | | | | | | |
# | | | | | | | | *- 9:guest がある。これは、 Linux カーネルの制御下のゲストオペレーティングシステムの仮想 CPU の実行に消費された時間である。
# | | | | | | | |
# | | | | | | | *- 8:steal (盗まれた時間; stolen time) が存在する。これは、仮想化環境での動作時に他のオペレーティングシステムにより消費された時間である。
# | | | | | | |
# | | | | | | *- 7:softirq (ソフト割り込みの処理を行った時間; 2.6.0-test4 以降)
# | | | | | |
# | | | | | *- 6:irq (割り込み処理を行った時間; 2.6.0-test4 以降)
# | | | | |
# | | | | *- 5:iowait (I/O の完了を待っていた時間; 2.5.41 以降)
# | | | |
# | | | *- 4:タスク待ち(idle)
# | | |
# | | *- 3:システムモード(sytem)
# | |
# | *- 2:低優先度のユーザモード(nice)
# |
# *- 1:ユーザモード(user)



memory_size.sh

Apacheチューニングのためのメモリ使用量計算 - ひとりごと

http://d.hatena.ne.jp/youhey/20110115/1295060276


memory_size.sh

#!/bin/sh

GREP="/bin/grep"
AWK="/bin/awk"
PRINTF="/usr/bin/printf"

if [ $# -lt 1 ]; then
echo "usage: ${0} [pid ...]" 1>&2
exit 100
fi

$PRINTF "PID\tRSS\t(peak)\tVM\t(peak)\n"

for p in $@
do
status="/proc/${p}/status"
if [ -f $status ]; then
rsssize=`$GREP '^VmRSS:' $status | $AWK '{print $2}'`
rsspeak=`$GREP '^VmHWM:' $status | $AWK '{print $2}'`
vmsize=`$GREP '^VmSize:' $status | $AWK '{print $2}'`
vmpeak=`$GREP '^VmPeak:' $status | $AWK '{print $2}'`
$PRINTF \
"%d\t%d\t(%d)\t%d\t(%d)\n" \
$p \
$rsssize \
$rsspeak \
$vmsize \
$vmpeak
fi
done

# [root@ham1 apache]# ./memory_size.sh `pgrep httpd`
# PID RSS (peak) VM (peak)
# 11562 9788 (9812) 260064 (260088)
# 12816 9784 (9808) 260064 (260088)
# 12817 9820 (9844) 260064 (260088)
# 13591 9788 (9812) 260064 (260088)
# 13841 9784 (9808) 260064 (260088)
# 13958 9888 (9912) 260064 (260088)
# 14032 9832 (9856) 260064 (260088)
# 15380 9788 (9812) 260064 (260088)
# 15679 9788 (9812) 260064 (260088)
# 31681 11356 (11356) 256564 (256616)
# [root@ham1 apache]#

# PID
# RSS VmRSS topでのRES(Resident)、実際に使用している物理メモリ領域のサイズ。
# 上結果では大体 9MB 使用している
# (peak) VmHWM mm->hiwater_rss か mm->rss のどちらかで高い値を示した物
# mm->hiwater_rss このプロセスがある時点で使っていたページフレームの最大数
# mm->rss プロセスに割り当てられているページフレームの数
# ページフレームのサイズは固定なので、ページフレーム数 → バイト数に変換するとメモリサイズになります。
# VM VmSize topでのVIRT(Virtual)、仮想メモリ領域のサイズ
# (peak) VmPeak このプロセスがある時点で使っていた最大仮想メモリサイズ

# Apacheチューニングのためのメモリ使用量計算 - ひとりごと
# http://d.hatena.ne.jp/youhey/20110115/1295060276
#
# for p in `pgrep httpd`; do grep "^VmHWM:" /proc/$p/status |awk '{print $2}'; done
#
# $ ./memory_size.sh `pgrep httpd`
# $ sudo ./shared_memory_size.pl `pgrep httpd`
#
# 実メモリ上ページサイズ
# 平均26.77MB
# 最大31.38MB
# 最小20.9MB
#
# 実メモリ上ページサイズ(ピーク)
# 平均31.34MB
# 最大32.91MB
# 最小30.21MB
#
# 共有率
# 平均32%
# 最大41%
# 最小27%

# 計算結果から、Apacheプロセスのメモリ使用量を32MBと想定、平均して32%程度のメモリを共
# 有するものとして、Apacheプロセスが消費するメモリの予想は平均21.76MB程度か。
#
# Webサーバには4GBを搭載しているので、OSが512MB程度占有するものとして、
# 「(4GB - 512MB)/ 21.76MB」でApacheに割り当てられそうなプロセス数は164と算出できる。
#
# 余裕をもたせるとして、100〜150程度の設定が妥当そうか。



none_shared_memory_fetcher.pl

Apacheとかforkしたプロセスのメモリチューニングに関するメモとスクリプト | hirobanex.net

http://hirobanex.net/article/2013/10/1381407737


none_shared_memory_fetcher.pl

#!/usr/bin/perl

use strict;
use warnings;

@ARGV or die "usage: %0 [pid ...]";

printf "PID\tRSS\tSHARED\tNONE_SHARED\n";

for my $pid (@ARGV) {
open my $fh, "< /proc/$pid/smaps" or (warn $! and next);
my @rows = <$fh>;
my $rss = mem_size_fetcher('Rss',@rows) or next;
my $shared = mem_size_fetcher('Shared_Clean',@rows) + mem_size_fetcher('Shared_Dirty',@rows);

printf
"%d\t%d\t%d (%d%%)\t%d\n",
$pid,
$rss,
$shared,
int(($shared / $rss) * 100),
($rss - $shared),
}

sub mem_size_fetcher {
my ($target,@rows) = @_;

my $mem_size = 0;

for my $row (@rows) {
my ($mem) = $row =~ /^$target:\s*(\d+)/i;
$mem_size +=($mem||0);
}

return $mem_size;
}

# Apacheとかforkしたプロセスのメモリチューニングに関するメモとスクリプト | hirobanex.net
# http://hirobanex.net/article/2013/10/1381407737
#
# 使い方は、naoyaさんのと同じで、
#
# sudo perl none_shared_memory_fetcher.pl `pgrep apache2` | head
#
# ってたたけば、
# PID RSS SHARED NONE_SHARED
# 31021 6600 5572 (84%) 1028
# 31024 5064 4868 (96%) 196
# 31025 5068 4868 (96%) 200
# 31026 5040 4840 (96%) 200
# 31027 5684 5172 (90%) 512
# 31028 5088 4892 (96%) 196
# 31029 5032 4840 (96%) 192
# 31030 5040 4844 (96%) 196
# 31031 5044 4840 (95%) 204
#
#
# って感じに出力される。NONE_SHAREDのkb数が子プロセス単独のメモリ使用量なので、ばらつ
# きがあるものこれだと、だいたい大目に見て、250くらいで、×プロセス数がApacheに使うメ
# モリってことになるみたい。
#
# なお、リクエストの度にメモリリークとかいろいろで子プロセスは太る傾向にあるから、ある
# 程度リクエスト流して、MaxRequestsPerChildの上限近いプロセスで計算する必要があるみた
# い。
#
# DSASチームのとてもありがたい下の方にMySQLのInnoDB周りのメモリ設定用ツールがあるんだ
# けど、ホントはこんな感じのがあるといいけど、いまどきApacheだけに限定するのもキモいの
# でそういうのはやめた。

# やってみた
# vi none_shared_memory_fetcher.pl
#
# chmod +x none_shared_memory_fetcher.pl
# ./none_shared_memory_fetcher.pl `pgrep httpd` | head
# [root@ham1 apache]# ./none_shared_memory_fetcher.pl `pgrep httpd` | head
# PID RSS SHARED NONE_SHARED
# 11562 9796 8204 (83%) 1592
# 12816 9908 8292 (83%) 1616
# 12817 9916 8296 (83%) 1620
# 13591 9796 8188 (83%) 1608
# 13841 9816 8204 (83%) 1612
# 13958 9820 8212 (83%) 1608
# 14032 9808 8224 (83%) 1584
# 15380 9880 8260 (83%) 1620
# 15679 9880 8276 (83%) 1604
# [root@ham1 apache]#
# [root@ham1 apache]# ./memory_size.sh `pgrep httpd`
# PID RSS (peak) VM (peak)
# 11562 9788 (9812) 260064 (260088)
# 12816 9784 (9808) 260064 (260088)
# 12817 9820 (9844) 260064 (260088)
# 13591 9788 (9812) 260064 (260088)
# 13841 9784 (9808) 260064 (260088)
# 13958 9888 (9912) 260064 (260088)
# 14032 9832 (9856) 260064 (260088)
# 15380 9788 (9812) 260064 (260088)
# 15679 9788 (9812) 260064 (260088)
# 31681 11356 (11356) 256564 (256616)
# [root@ham1 apache]# for p in `pgrep httpd`; do grep "^VmHWM:" /proc/$p/status |awk '{print $2}'; done

# これを最大のデータを渡した時の状況を見てテストするといける



proc_meminfo.sh


proc_meminfo.sh

#!/bin/sh

zbxHOSTNAME="$1"
zbxSERVER="$2"

TEMPFILE="/tmp/zbxTMP$$"

cat /proc/meminfo |while read LINE
do ARTICLE=`echo $LINE |cut -d":" -f1 | tr "()" "_"`
ITEMNUM=`echo $LINE|cut -d":" -f2|sed -e "s/ kB/ * 1024/" |bc`
echo `date '+%Y/%m/%d %H:%M:%S.%N'` `hostname` "$ARTICLE $ITEMNUM"
# done >$TEMPFILE
done

LANG=C;
(
awk '
BEGIN
{ printf "\"DATE\",\"TIME\""}
{printf ",\"%s(%s)\"",$1,$3}
END
{printf "\n"}'
/proc/meminfo > meminfo.csv
); while true;
do ( awk 'BEGIN{ printf strftime("%Y/%m/%d, %H:%M:%S") } {printf ",%d",$2} END{printf "\n"}' /proc/meminfo >> meminfo.csv );sleep 1; done



proc_stat.sh


proc_stat.sh

#!/bin/bash

while [ true ]
do
sleep 1
echo `date '+%Y/%m/%d %H:%M:%S.%N'` `hostname` `head -1 /proc/stat`
done