2015年2月26日木曜日

MySQL HandlerSocketを監視するNagiosプラグイン

Quinn Dombrowski Sci-fi https://www.flickr.com/photos/quinnanya/7496308140

https://github.com/takeshiyako2/check-mysql-all/blob/master/check_handlersocket
HandlerSocket Plugin for MySQLへの接続を監視するNagiosプラグインです。
HandlerSocketへの読み込みコネクションチェック、書き込みコネクションチェック、検索チェックをサポートしています。

作者は、PerconaのRyan Loweさんです。
Ryan Lowe, Author at MySQL Performance Blog http://www.percona.com/blog/author/ryanalowe/




以下、セットアップ方法です。
環境は、Amazon Linux AMI 2014.09.2 (HVM) - ami-18869819です。

Perlのperl-Net-HandlerSocketモジュールをセットアップ。
# yum -y install cmake libtool libtool-ltdl libtool-ltdl-devel libedit-devel perl perl-devel git gcc-c++ perl-Time-HiRes perl-Test-Simple nagios-plugins-all
# git clone git://github.com/DeNA/HandlerSocket-Plugin-for-MySQL.git
# cd HandlerSocket-Plugin-for-MySQL
# ./autogen.sh
# ./configure --disable-handlersocket-server
# make
# make install
# cd perl-Net-HandlerSocket
# perl Makefile.PL
# make & make test
# make install

check_handlersocketプラグインをダウンロード。
# curl -O  https://raw.githubusercontent.com/garrinmf/check-mysql-all/master/check_handlersocket
$ perl check_handlersocket -h

ヘルプを見ると、タイムアウトは ”デフォルトで10秒” と書いてありますが、これは間違いで0.01秒です。
コードを見ると ualarm($OPTIONS{'timeout'}); となっているので、タイムアウトのオプションには、マイクロ秒を指定してあげます。
つまり、1秒 = 1000000、10秒 = 10000000 です。

以下、プラグインの使い方です。

読み込みコネクションと書き込みコネクションをチェック。
$ perl check_handlersocket -K read_connect -H localhost --timeout=1000000
OK: HandlerSocket is accepting read connections 

$ perl check_handlersocket -K write_connect -H localhost --timeout=1000000
OK: HandlerSocket is accepting write connections 

検索チェック。
テスト用テーブルを作成。
$ mysql -u root
mysql> USE test;
mysql> CREATE TABLE sample (id INT PRIMARY KEY, val INT);
mysql> INSERT INTO sample (id, val) VALUES (10, 100);
mysql> SELECT * FROM sample;

sampleテーブルから id = 10 を検索。
$ perl check_handlersocket -K read_exec -H localhost --database=test --table=sample --index='PRIMARY' --columns=val --index-value=10 --timeout=1000000
OK: Read

あとは、プラグインをNagiosなどに組み込めばOKです。
Enjoy!

2015年2月24日火曜日

Amazon EC2 + EBSにおけるIOバリアの設定によるパフォーマンス差は?

eutrophication&hypoxia Great Barrier Reef, Australia https://www.flickr.com/photos/48722974@N07/5093723696/in/photolist-91shvW-5w9sqC-bUL52L-bARkuF-oZ4DjD-9PqSyd-oDCmjp-dxNCMf-7dRfHA-92ovCb-nhNGq1-9QZNLw-bnWmc9-98cxQE-37z2C2-8L7EAm-cQZbq5-7tFo5g-gqgAZj-6tBwB-9QZPXN-8ek6w6-ehRoem-bARbgp-bAR83k-oDBrdB-p7qfCy-9uh9sc-bARa1x-pNZtk1-fFgqFF-grTuPe-grTfJ3-hMNwxi-oW5FA7-6NwjG9-aMZYRe-oDCnZt-q2EBwq-7tFjm4-bARc6v-grTjbJ-zZvy1-zZvxY-6erQZF-zZsmF-bnWhuh-7tFnyH-gqqXvo-fU8Mbp
Amazon EC2 + EBS を使ったとき、I/Oバリアのオン・オフでパフォーマンスが変わるか測ってみました。
=> 結果、変わらないことがわかりました。
また、CentOSを使ったときは、カーネルのバージョンを最新にすることによってパフォーマンスが改善することがわかりました。

以下、スループットを測ったときのメモです。

インスタンスとスペック
CentOS 6 (x86_64) - with Updates HVM
Instance type: c4.2xlarge
Disc: 300GB Provisioned IOPS (SSD) 1000 IOPS

EC2のCentOS6 HVMでresize2fs "Nothing to do!"と言われたとき
http://takeshiyako.blogspot.jp/2014/12/ec2centos6-hvmresize2fs-nothing-to-do.html
こちら方法で、あらかじめ、ディスクスペースを増やしておきます。

yum updateもしておきます。
# yum -y update
# reboot

現在のマウントの状況を確認。
# grep barrier /proc/mounts
/dev/xvda1 / ext4 rw,relatime,barrier=1,data=ordered 0 0

fstabファイルを編集。barrier=0を付与します。
# emacs /etc/fstab

UUID=xxxxxxxxxxxxxxxxx /                       ext4    defaults        1 1
->
UUID=xxxxxxxxxxxxxxxxx /                       ext4    defaults,barrier=0        1 1

サーバをリブート
# reboot

マウントの状況を確認。barrier=0が付与されていることを確認。
# grep barrier /proc/mounts
/dev/xvda1 / ext4 rw,relatime,barrier=0,data=ordered 0 0

dbenchを使ってベンチマークをします。5回づつ施行します。
# yum --enablerepo=epel -y install dbench
# dbench 5 -D . > ./dbench.log

I/Oバリアあり
Throughput 198.832 MB/sec  5 clients  5 procs  max_latency=291.996 ms
Throughput 198.525 MB/sec  5 clients  5 procs  max_latency=231.604 ms
Throughput 197.24 MB/sec  5 clients  5 procs  max_latency=529.609 ms
Throughput 198.003 MB/sec  5 clients  5 procs  max_latency=537.408 ms
Throughput 193.24 MB/sec  5 clients  5 procs  max_latency=500.507 ms

I/Oバリア無し 
Throughput 195.168 MB/sec  5 clients  5 procs  max_latency=336.223 ms
Throughput 196.525 MB/sec  5 clients  5 procs  max_latency=341.762 ms
Throughput 196.241 MB/sec  5 clients  5 procs  max_latency=664.540 ms
Throughput 197.79 MB/sec  5 clients  5 procs  max_latency=814.218 ms
Throughput 195.378 MB/sec  5 clients  5 procs  max_latency=441.299 ms
I/Oバリアあり・なしで差がないことがわかります。

気になったので、カーネルによって差が出るか、測ってみました。
カーネル 2.6.32-431.29.2.el6.x86_64
Throughput 58.7519 MB/sec  5 clients  5 procs  max_latency=204.272 ms
Throughput 60.9603 MB/sec  5 clients  5 procs  max_latency=197.062 ms
Throughput 58.7519 MB/sec  5 clients  5 procs  max_latency=204.272 ms
Throughput 63.2337 MB/sec  5 clients  5 procs  max_latency=658.214 ms
Throughput 61.4362 MB/sec  5 clients  5 procs  max_latency=984.695 ms

yum -y updateでカーネルを最新にしました。
カーネル 2.6.32-504.8.1.el6.x86_64
Throughput 195.168 MB/sec  5 clients  5 procs  max_latency=336.223 ms
Throughput 196.525 MB/sec  5 clients  5 procs  max_latency=341.762 ms
Throughput 196.241 MB/sec  5 clients  5 procs  max_latency=664.540 ms
Throughput 197.79 MB/sec  5 clients  5 procs  max_latency=814.218 ms
Throughput 195.378 MB/sec  5 clients  5 procs  max_latency=441.299 ms
パフォーマンスが改善していることがわかります。

Amazon Linux AMI 2014.09.2 (HVM) - ami-18869819 では、もっとパフォーマンスが良かったです。
Throughput 330.06 MB/sec  5 clients  5 procs  max_latency=557.884 ms
Throughput 331.476 MB/sec  5 clients  5 procs  max_latency=326.321 ms
Throughput 329.715 MB/sec  5 clients  5 procs  max_latency=614.967 ms
Throughput 333.588 MB/sec  5 clients  5 procs  max_latency=302.362 ms
Throughput 332.771 MB/sec  5 clients  5 procs  max_latency=418.299 ms


Amazon Linux AMI と CentOS それぞれのカーネルを比較したグラフです。



まとめ。

ディスクアクセスの多いアプリケーションは、Amazon Linux AMI で EBS プロビジョンド IOPS(SSD)を選択するのが良い。
これは、おそらく、ほかのOSと比べてAWS環境に最適化が施されているためである、と予想。(SR-IOVの設定の違いかな?と考えましたが未検証です。詳しい方がいらっしゃったら教えていただけると有難いです。)
あえて、CentOSを使うならば、そのままではかなりスループットが悪い。カーネルのバージョンアップによって改善されるが Amazon Linux AMI のスループットの60%ほどにとどまる。
ほかのOSでも検証してみたいです。

2015年2月19日木曜日

MuninのMySQLプラグインで"Unknown section: INDIVIDUAL BUFFER POOL INFO"エラーが出たときの対処法


https://github.com/munin-monitoring/munin/blob/devel/plugins/node.d/mysql_.in

最新のMySQL5.6で、MuninのMySQLプラグインでを利用しようとすると下記のようなエラーが出ます。
# cd /etc/munin/plugins
# munin-run mysql_innodb_rows
Unknown section: INDIVIDUAL BUFFER POOL INFO at /etc/munin/plugins/mysql_innodb_rows line 1098.

原因は、プラグインが INDIVIDUAL BUFFER POOL INFOの情報を解析せず、エラー処理がうまくいっていないためです。
これを解決するために、該当の情報をスキップするようにPerlのコードを編集します。
具体的には以下のようになります。

%section_mapハッシュの最後に、'INDIVIDUAL BUFFER POOL INFO' => \&skip, を追記します。
# emacs /usr/share/munin/plugins/mysql_
修正前。
    my %section_map = (
~~~~
        'BACKGROUND THREAD'        => \&skip,
    );
修正後。
    my %section_map = (
~~~~
        'BACKGROUND THREAD'        => \&skip,
        'INDIVIDUAL BUFFER POOL INFO'   => \&skip, 
    );

動作チェック。
# munin-run mysql_innodb_rows
Innodb_rows_deleted.value 215
Innodb_rows_inserted.value 13082874
Innodb_rows_read.value 14092838
Innodb_rows_updated.value 14092617

エラーを吐かずに動作するようになりました。

2015年2月17日火曜日

Amazon EC2 CentOS 6 (x86_64) - with Updates HVM のディスク容量を増やす

https://www.flickr.com/photos/thebluekids/6094359814

Amazon EC2でAMI: CentOS 6 (x86_64) - with Updates HVM を利用したときは、最初に設定したストレージ容量が起動時に反映されず、しかもresize2fsができずディスクの容量を増やすことができません。

# resize2fs /dev/xvda1
resize2fs 1.41.12 (17-May-2010)
The filesystem is already 2096896 blocks long.  Nothing to do!

resize2fsができず、”Nothing to do!”となります。
EC2でディスクの容量を拡張したいときなど、パーティションをリサイズしたいことがあると思います。

cloud-initを利用してディスクの容量を拡張する方法(EC2のCentOS6 HVMでresize2fs "Nothing to do!"と言われたとき)もありますが、ここでは、fdiskを利用して新しくディスクの容量を割り当てていきます。

以下、コマンドとともに <<コメント>> として説明を入れています。
#  df -h  <<7.9GBのディスクを確認。>>
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.9G  797M  6.7G  11% /
tmpfs           3.6G     0  3.6G   0% /dev/shm

# fdisk -l <<ディスクとパーティーションを確認。ディスクは322.1 GBだけど、パーティーションが7.9GB(8387584ブロック)のみ。>>

Disk /dev/xvda: 322.1 GB, 322122547200 bytes
255 heads, 63 sectors/track, 39162 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00098461

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *           1        1045     8387584   83  Linux

# fdisk /dev/xvda <<fdiskコマンドをスタート。/dev/xvdaを指定。>>

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c') and change display units to
         sectors (command 'u').

Command (m for help): u <<セクターディスプレイを選択。>>
Changing display/entry units to sectors

Command (m for help): p <<パーティーションを表示。最初のセクター(Start)を確認。この例では、2048>>

Disk /dev/xvda: 322.1 GB, 322122547200 bytes
255 heads, 63 sectors/track, 39162 cylinders, total 629145600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c9349

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1   *        2048    16777215     8387584   83  Linux

Command (m for help): d  <<パーティーションを削除。>>
Selected partition 1

Command (m for help): n  <<新しいパーティーションを作成。>>
Command action
   e   extended
   p   primary partition (1-4)
p  <<プライマリを選択。>>
Partition number (1-4): 1  <<最初のパーティーションを選択。>>
First sector (63-629145599, default 63): 2048 <<最初のセクターを入力。この例では、2048>>
Last sector, +sectors or +size{K,M,G} (2048-629145599, default 629145599): <<ディスクの残り部分を指定。エンターを押してデフォルトを選択。>>
Using default value 629145599

Command (m for help): p  <<パーティーションを表示。最初のセクター(Start)と最後のセクター(End)に間違いがないか確認。>>

Disk /dev/xvda: 322.1 GB, 322122547200 bytes
255 heads, 63 sectors/track, 39162 cylinders, total 629145600 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000c9349

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1            2048   629145599   314571776   83  Linux

Command (m for help): a <<パーティションをブート可能にします。>>
Partition number (1-4): 1  <<最初のパーティーションを選択。>>

Command (m for help): w  <<パーティション情報を書き込み、fdiskセッションを終了します。>>
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

# reboot <<サーバをリブート。>>

# resize2fs /dev/xvda1 <<利用可能なディスクの容量を増やす。>>
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/xvda1 is mounted on /; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 19
Performing an on-line resize of /dev/xvda1 to 78642944 (4k) blocks.
The filesystem on /dev/xvda1 is now 78642944 blocks long.

# df -hT <<ディスクの容量が増えていることを確認。>>
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/xvda1     ext4   296G  810M  280G   1% /
tmpfs          tmpfs  3.6G     0  3.6G   0% /dev/shm

うまくディスク容量が増加できたでしょうか?


参考)AWS Developer Forums: R3.8XLARGE centos/RHEL - resize2fs not working on root drive
https://forums.aws.amazon.com/thread.jspa?messageID=539484

2015年2月16日月曜日

MySQLのInnoDB Row Operationsを監視するNagiosプラグイン

photophilde

https://github.com/takeshiyako2/nagios-check_mysql_innodb_row_operations

MySQLのInnoDB Row Operationsを監視するNagiosプラグインを書きました。
SHOW /*!50000 ENGINE*/ INNODB STATUSの結果を保存しておき、差分を経過時間で除算してRow Operations/secを算出します。
この数値にしきい値をもうけてアラートをすることができます。


以下、設定方法です。
あらかじめ、Rubyを用意しておいてください。

プラグインをgit cloneして、mysql2ライブラリをインストール。
$ git clone git@github.com:takeshiyako2/nagios-check_mysql_innodb_row_operations.git
$ cd nagios-check_mysql_innodb_row_operations
$ bundle

スクリプトの動作チェック。
-o オプションを付けることによって、InnoDB Row Operationsの inserts, updates, deletes, reads からチェックしたい項目選びます。 デフォルトは、reads です。
$ ruby check_mysql_innodb_row_operations.rb -H localhost -u username -p xxxx -o reads -w 100000 -c 200000
OK - Current Status is saved. values:{:inserts=>"10000000", :updates=>"10000000", :deletes=>"10000000", :reads=>"10000000", :unixtime=>1424072459}

$ ruby check_mysql_innodb_row_operations.rb -H localhost -u username -p xxxx -o reads -w 100000 -c 200000
OK - reads 12345 Operations per second|OPS=12345

テンポラリファイルを削除しておく。
$ rm /tmp/check_mysql_innodb_row_operations*
あとは、Nagios/Nrpeに上記のような設定を仕込んでおけばOKです。 Enjoy!

2015年2月13日金曜日

MySQLのQPSを監視するNagiosプラグイン

http://www.flickr.com/photos/khouri/8586944387/in/photostream/

https://github.com/takeshiyako2/nagios-check_mysql_qps

MySQLのQPSを監視するNagiosプラグインを書きました。
SHOW STATUS LIKE "Queries"の結果を保存しておき、差分を経過時間で除算してQPSを算出します。
QPSにしきい値をもうけてアラートをすることができます。



以下、設定方法です。
あらかじめ、Rubyを用意しておいてください。

プラグインをgit cloneして、mysql2ライブラリをインストール。
$ git clone git@github.com:takeshiyako2/nagios-check_mysql_qps.git
$ cd nagios-check_mysql_qps
$ bundle

スクリプトの動作チェック。
$ ruby check_mysql_qps.rb -H localhost -u username -p xxxx -w 500 -c 900
OK - Current Status is saved. queries:10000, unixtime:1423816070

$ ruby check_mysql_qps.rb -H localhost -u username -p xxxx -w 500 -c 900
OK - 123 Queries per second|QPS=123

テンポラリファイルを削除しておく。
$ rm /tmp/check_mysql_qps.dat

あとは、Nagios/Nrpeに上記のような設定を仕込んでおけばOKです。
Enjoy!

2015年2月2日月曜日

NginxのQPSを監視するNagiosプラグイン

https://www.flickr.com/photos/r405/13540449253/

https://github.com/regilero/check_nginx_status

Nginxのアクティブコネクション/秒・リクエスト/秒・コネクション/秒を監視するNagiosプラグインです。(※ QPS = リクエスト/秒としています)
これらにしきい値をもうけてアラートをすることができます。
例えば、Nginxが100 リクエスト/秒を超えたらアラートメールを飛ばすなどです。
Webサービスを公開する前には負荷テストをして限界値を測ると思いますが、その限界値に達しないように、あらかじめ、しきい値をもうけて監視しておくと安心できます。


以下、設定方法です。

Nginxの設定ファイルのserverディレクティブに location /nginx_status を追記。
参考)HttpStubStatusModule - Nginx Community
http://wiki.nginx.org/HttpStubStatusModule
server {
    ~~~~~~~~~~~~
    ~~~~~~~~~~~~

    # status
    location /nginx_status {
      stub_status on;
      access_log  off;
      allow       127.0.0.1;
      deny        all;
    }
}

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

PerlモジュールのLWP::UserAgentをインストール。
# yum -y install perl-libwww-perl

check_nginx_status.plプラグインをNagiosのプラグインディレクトリに設置。
# curl https://raw.githubusercontent.com/regilero/check_nginx_status/master/check_nginx_status.pl -O /usr/lib64/nagios/plugins/check_nginx_status.pl

check_nginx_status.plの動作チェック。
# perl /usr/lib64/nagios/plugins/check_nginx_status.pl -H 127.0.0.1 -t 1 -w 1000,100,200 -c 2000,200,300
NGINX OK -  0.048 sec. response time, Active: 38 (Writing: 2 Reading: 0 Waiting: 36) ReqPerSec: 27.770 ConnPerSec: 1.008 ReqPerConn: 37.364|Writing=2;;;; Reading=0;;;; Waiting=36;;;; Active=38;;;; ReqPerSec=27.770492;;;; ConnPerSec=1.008197;;;; ReqPerConn=37.364247;;;;

オプションの意味は?
-H 127.0.0.1 ホスト名を指定
-t 1 秒単位のタイムアウト値しきい値を設定
-w 10000,100,200 アクティブコネクション1000、リクエスト/秒100、コネクション/秒200 これらのしきい値を超えたらWARNING
-c 20000,200,300 アクティブコネクション2000、リクエスト/秒200、コネクション/秒300 これらのしきい値を超えたらCRITICAL

動作チェックで作成されたテンポラリファイルを削除しておく。
# rm /tmp/127.0.0.1_check_nginx_status*

その他の細かい設定については、ヘルプを確認してください。
# perl /usr/lib64/nagios/plugins/check_nginx_status.pl -h

あとは、Nagios/Nrpeに上記のような設定を組み込んでおけばOKです。
Enjoy!