2014年10月30日木曜日

Nginxのレスポンスタイムをパーセンタイル値で計測するMunin plugin

Alberto Permuy Leal

https://github.com/takeshiyako2/munin-nginx_request_time

nginxのレスポンスタイムをパーセンタイル値で計測するMunin pluginです。
id:t-cyrillさんのプラグインがオリジナルです。これをLTSVに対応させました。
90パーセンタイル, 95パーセンタイル値とMAX値をグラフにします。(MAX値は別グラフ)


min 最小値
median 中央値
percentile90 90パーセンタイル
percentile95 95パーセンタイル


パーセンタイルとは?
計測値の分布(ばらつき)を小さい数字から大きい数字に並べ変え、パーセント表示することによって、小さい数字から大きな数字に並べ変えた計測値においてどこに位置するのかを測定する単位。
 例えば、計測値として100個ある場合、5パーセンタイルであれば小さい数字から数えて5番目に位置し、50パーセンタイルであれば小さい数字から数えて50番目に位置し、95パーセンタイルであれば小さい方から数えて95番目に位置する。
 このようにパーセンタイルは全体における自分の位置を測定する単位として用いられ、企業年金においては年金ALMにおいて計算された数値を説明するのに用いられることがある。
パーセンタイル(percentile)|用語集|企業年金連合会
http://www.pfa.or.jp/yogoshu/ha/ha17.html


 Nginxの$request_timeは、nginxがリクエストを受けてからレスポンスをクライアントに返しきるまでの時間なので、変に遅いクライアントが居ないとも限らない・・・。
平均値だと、極端な異常値が少しでもあったばあい、これに引きづられて数字が大きくなったりして、あまり信用できなくなったりします。
測定誤差をできるだけ減らしたいので、平均値ではなくてパーセンタイルを取ろうという考え方です。

以下、セットアップ方法です。


nginxのログフォーマットをLTSVに変更。※ LTSV公式サイトを参考にします。http://ltsv.org/
# emacs /etc/nginx/nginx.conf
---
    log_format  ltsv  "time:$time_local"
                      "\thost:$remote_addr"
                      "\tforwardedfor:$http_x_forwarded_for"
                      "\treq:$request"
                      "\tstatus:$status"
                      "\tsize:$body_bytes_sent"
                      "\treferer:$http_referer"
                      "\tua:$http_user_agent"
                      "\treqtime:$request_time"
                      "\tcache:$upstream_http_x_cache"
                      "\truntime:$upstream_http_x_runtime"
                      "\tvhost:$host";

    access_log  /var/log/nginx/access.log  ltsv; # mainをltsvに変更
---

nginxをリロード。
# /etc/init.d/nginx configtest
# /etc/init.d/nginx reload

nginxのログを読めるようにしておきます。
# chmod 644 /var/log/nginx/access.log

logrotateの設定も変えておきます。
# emacs /etc/logrotate.d/nginx
        create 640 nginx adm
->
        create 644 nginx adm


CPANモジュールをインストール。
# cpanm install Text::LTSV
# cpanm install File::ReadBackwards
# cpanm install Statistics::Lite
# cpanm install Statistics::Descriptive

Muninプラグインを設置
# cd /usr/share/munin/plugins/
# wget --no-check-certificate https://raw.githubusercontent.com/takeshiyako2/munin-nginx_request_time/master/nginx_request_time

Muninプラグインにリンクを貼る
# ln -s /usr/share/munin/plugins/nginx_request_time /etc/munin/plugins/nginx_request_time
# ln -s /usr/share/munin/plugins/nginx_request_time /etc/munin/plugins/nginx_request_time_max

munin-nodeをリスタート。
# service munin-node restart

簡単ですね!


※ 他にも、レスポンスタイムの可視化として有効なのは、例えば、[10ms ~ 50ms], [51ms~ 100ms], [101ms以上]で別々でカウントしたりする方法があります。こちらも実装しておくと安心できるでしょう。


参考)

『性能エンジニアリング入門(2):負荷テストのデータ、読めてますか? (1/2)』
http://www.atmarkit.co.jp/ait/articles/1201/06/news121.html

負荷テストの勘所 その2 | Insight Technology, Inc.
http://www.insight-tec.com/technical-information/%E8%B2%A0%E8%8D%B7%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E5%8B%98%E6%89%80%E3%80%80%E3%81%9D%E3%81%AE%EF%BC%92.html

負荷テストについて基本的なメモ - ablog
http://d.hatena.ne.jp/yohei-a/20090722/1248264521

第17回 Webアプリケーションのパフォーマンス改善(1):Perl Hackers Hub|gihyo.jp … 技術評論社
http://gihyo.jp/dev/serial/01/perl-hackers-hub/001701

突然のTwitter砲にもなんとか耐えたさくらVPSに感謝する - As a Futurist...
http://blog.riywo.com/2011/02/07/162154


2014年10月28日火曜日

MySQLスレーブの整合性を保つための3つの設定

David Guthrie

MySQLのスレーブサーバが落ちて、立ち上げた時にマスターとの整合性を心配したくないのであれば以下の設定を入れると良いそうです。

MySQL設定ファイルに追記
# emacs /etc/my.cnf

[mysql]
binlog_checksum            = CRC32
relay_log_info_repository  = TABLE
relay_log_recovery         = ON

MySQLをリスタート
# service mysqld restart


各設定に意味については、下記サイトが参考になります。

binlog_checksum            = CRC32
”バイナリログが破損した場合に破損を検出し易くするために、バイナリログにチェックサムを追加”
http://thinkit.co.jp/story/2014/01/23/4717/page/0/1

relay_log_info_repository  = TABLE
relay_log_recovery         = ON
"MySQL 5.6でスレーブをクラッシュセーフにするには"
http://yakst.com/ja/posts/57


結果、スレーブサーバは以下の様な設定になりました。
※ HandlerSocket の設定込みです。


2014年10月23日木曜日

AWSガチャは下手なチューニングよりも効果が出る?

foxfoto_archives

Amazon EC2は立ち上げるインスタンスによって微妙なパフォーマンス差が出ると言われていて、複数回、インスタンスを立ち上げたり、捨てたりして、良いインスタンスを得ることを”Amazon EC2インスタンスガチャと”呼ばれています。
そのパフォーマンス差は、どれくらいなのか?気になったので測ってみました。

検証環境はこんな感じです。
AMI ID: CentOS 7 x86_64 (2014_09_29) EBS HVM-b7ee8a69-ee97-4a49-9e68-afaee216db2e-ami-d2a117ba.2 (ami-89634988)
Instance Type: c3.xlarge

1)Magnetic(standard)
2)Magnetic(standard) + EBS-Optimized
3)General Purpose (SSD) + EBS-Optimized
4)Provisioned IOPS (IOPS 1000) + EBS-Optimized

上記のディスクを接続した各10インスタンスづつ立てて、ベンチマークします。

fioでベンチマーク

まず。fioでIOPSを調べます。

fioをインストール。
# yum -y install epel-release.noarch
# yum -y install fio
fioをランダムリード・モードで実行。
# fio -rw=randread -bs=4k -size=1G -numjobs=32 -runtime=60 -direct=1 -invalidate=1 -ioengine=libaio -iodepth=32 -iodepth_batch=32 -group_reporting -name=randread


インスタンスによって差異が出てきました。

dbenchでベンチマーク

違うベンチマークツールでスループットを調べてみます。
ベンチマークには、dbench(https://dbench.samba.org/)を使います。

dbenchをインストール。
# yum -y install dbench
dbenchを実行。
# dbench 5 -D . > dbench.log



かなりの差が出てしましいました。

まとめ

インスタンスによっては、ディスク性能でけっこうな差がでてしまいました。

Magnetic(standard)はAWSガチャによってかなりの性能差が出ます。EBS-Optimizedをつけても変わりません。

一見、General Purpose (SSD)が良い結果を出しているように見えますが、バーストしている状態だと思われます。数十回ベンチマークをかけたら仕様どおりガクンと性能が落ちました。
(最も低い結果で iops=305, Throughput 75.5844 MB/sec, max_latency=7719.676 ms ほど)
長時間連続して負荷がかかる環境には使わないほうがよいでしょう。
逆に、バッチ処理などの用途では威力を発揮しそうです。
General Purpose (SSD)のバーストについては、こちらの記事が参考になります。
『Amazon EBSのGeneral Purpose(SSD)のバーストルールを理解する | Developers.IO』
http://dev.classmethod.jp/cloud/study-ebs-ssd-burst-rule/

 Provisioned IOPSはまあまあ安定しています。

ちなみにUnixBenchも試してみましたが、これは主にCPUへのベンチマークツールなので、差は殆どありませんでした。
MySQLのマスターサーバなどでディスク性能が要求される用途では、Provisioned IOPSを選ぶと安心できるでしょう。

※ 2014/10/24 General Purpose (SSD) + EBS-Optimized と Provisioned IOPS (IOPS 1000) + EBS-Optimized のベンチマークを追記。