New Relic ハンズオン・ワークショップ in Tokyoに行ってきた
行ってきてみました。
new relic使っているものの、transactionからどの処理が遅いか的な使い方しかしてなかったので。
スピーカーはNew Relic の Joe LoCascio さん。前編英語かと思いきやしっかり通訳の方がいらっしゃって一安心。
アジェンダ
ざっくりメモ
new relicの大枠の機能
-
- サーバー側のプロファイリング
BROWSER
- フロントエンド側のプロファイリング
SYNTHETICS
- サーバーの死活監視。ブラウザテスト的なこともできるらしい
MOBILE
- ネイティブアプリのプロファイリング
SERVERS
- サーバーのリソース監視
PLUGIN
INSIGHTS
- new relicで収集したデータをSQL的な感じ抽出してデータ分析できる
apdex
レスポンスタイムからユーザ満足度を図った数値
基準レスポンスタイムを設定し、そこから割合判定
apdex計算式
apdex = (satisfied + (tolerating / 2)) / total requests
satisfied -> 満足。レスポンスタイムが基準値以下
tolerating -> まあまあ。基準値の4倍以下
flustrated -> 不満足。基準値の4倍以上
key transaction
特定のtransactionをkey transactionに設定することでより詳細な情報を取得できるようになる
x-ray sessionで関数レベルで分析できる
error analytics
- クラスごと、トランザクションごとグルーピングできる
- error traceもできる
- newrelicのモジュールを追加すれば、newrelic専用エラー出力もできる
newrelicのAPIでデプロイメントマーカーを設定できる。
- リリース前後での変化を可視化
custom dashboard
- 監視したい情報を自分用にピックアップできる
using alerts
アラートポリシー設定可能
アラート条件、通知チャンネル柔軟に設定可能
所感
やろうと思えばもろもろ監視系すべてイケるっぽい
- でもすでにmuninとかもあったり、他の監視ツールとの住み分けなり統合なり考えないといけなそう
色々できそうだけどnewrelicのオーバーヘッドはないのだろうか・・・
過去にnew relicからマスターDBへ定期的にデータ取得してたりとかあった
野良のプラグインとか要調査が必要そう
どうやらもろもろphp対応は後回しの模様・・・
- 最近風当たりの強さを感じる
頂いたnew relic Tシャツが意外とアグレッシブ
でした!
crontabのエラー、(CRON) bad minuteはただの改行の場合でも出る
タイトルでもうほぼ終了なのですが、 crontabを更新した後に、cronのエラーログ/var/log/cronを確認すると下記のエラー
Feb 23 13:29:01 localhost crond[4436]: (xxxxxx) RELOAD (/var/spool/cron/xxxxxx) Feb 23 13:29:01 localhost crond[4436]: (CRON) bad minute (/var/spool/cron/xxxxxx) Feb 23 13:29:01 localhost crond[4436]: (CRON) bad minute (/var/spool/cron/xxxxxx)
書式間違っちゃったかなと思い、確認するも明らかに正しいはず・・・ 試しに全てコメントアウトしても上記のエラーが出る始末
よくよく見るとエラーの数と改行の数が一緒 crontabを改行なしにしてみると、エラーは出なくなりました
もうちょっとそれっぽいエラーにして欲しかった感。。。
golangでcrontabからドキュメントを作成するコマンドラインツール crondocを作った
javadoc,phpdoc的にcrontabからドキュメントを生成するツール
crondocをgolangでつくってみました
きっかけ
いくつかのサーバーの設定、ミドルウェア変更することになり、
影響範囲を確認していたのですが、サーバーごとにcronの運用が統一されていなかったのでcronまわり影響範囲を確認するのに時間がかかってしまいました
そこでcronの運用フローを統一する過程でcronの簡単なドキュメントを作成したくなりました
その際、javadoc,phpdocのcron版みたいのがないか探してみたのですが、ないようなのでせっかくなので自作してみました
crondocの機能
ざっくり下記のような機能で作ってみました
- 標準入力、ファイル指定でcrontabからドキュメントを出力
- 改行までをひとグループとしてドキュメント出力
- ドキュメントを出力はmarkdowm形式
- @authorなどのタグ付ができる
出力例
現状下記のようなcrontabの場合はこんな感じです
- crontab
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # @title monday.sh # @author hoge # @param env[dev|stg|prod] # start every monday 0 10 * * 1 sh /home/hoge/happy_monday.sh prod
↓↓↓
使い方
ソースはこちら
github.com
バイナリを落としてきて、下記のようにすればドキュメントが出力されるはずです
$ crodoc /etc/crontab $ crontab -l | crodoc -s
続 サービス稼働中に不要なDBのテーブルを安全に削除する方法
前回の続編です。
前回まで
前回はdropするテーブルのデータファイルにハードリンクを貼ることでdrop時にファイル削除されることを回避することができました。
しかしioniceで優先度を下げても、巨大なテーブルのデータファイルなどを削除する際はCPU使用率など見る限り負荷がかかっていました。 ioniceは緩やかに削除というより実行の順番の優先度を下げるという挙動のようです。
なので、次に負荷をかけずに巨大なファイルを削除するということで下記を参考にさせてもらいました。 www.nari64.com
truncateコマンドで徐々にファイルサイズを削り、小さくした後に削除するというやり方です。
安全にテーブルdropする手順
まとめて下記のような流れで処理しました
- 削除前に念のため、dump取る
mysqldump DB_NAME hoge_table > dump_hoge_table.sql
- 対象テーブルのデータファイルにハードリンクを貼る
ln /usr/local/mysql/data/DB_NAME/hoge_table.ibd /root/hoge_table.ibd ln /usr/local/mysql/data/DB_NAME/hoge_table.frm /root/hoge_table.frm
- drop tableを実行
mysql DB_NAME -e "DROP TABLE hoge_table"
- ハードリンクを貼ったファイルをtruncateコマンドで徐々にサイズを削った後に、rmを実行
//ファイルサイズ取得 $file_size = 0; $cmd = "du -m {$file_path} | awk '{print $1}'"; exec($cmd, $output, $ret); if($ret == 0) $file_size = $output[0]; //truncateで徐々に切り詰める if($file_size){ $i = 1; while ($i <= $file_size) { $tmp_size = $file_size - $i; $cmd = "truncate -s {$tmp_size}M {$file_path}"; exec($cmd, $output, $ret); //0.1sec sleep usleep(100000); $i++; } //ファイル削除 $cmd = "rm {$file_path}"; $res = exec($cmd, $output, $ret);
的な感じで、稼働中の本番DBで百数テーブル、260GB程度削除しましたが、負荷なく実行できました。 そこそこ時間はかかりますが、、、truncateの部分はもっと攻めて良さそうですがそれはまた次の機会に・・・
これでどんどん不要なテーブル消せますね!
感謝致します。
サービス稼働中に不要なDBのテーブルを安全に削除する方法
担当サービスのDBサーバーのディスク容量の空きが少なくなり、不要なテーブルを削除することになりました。
対象のテーブルのデータ量が多く、平常時でもそこそこ負荷のあるサーバーなのですが、
テーブル削除だけのためにメンテナンスをするのもアレなので、
深夜帯にしれっとdropしたい気持ちを抑えつつ、負荷のかからないdrop tableの手順を試してみました。
サービス稼働中にテーブルdropする時の問題点
metadata lock
drop対象のテーブルに書き込みやトランザクションが貼ってあるとmeta data lockがかかってしまいます
今回は参照等がないテーブルなので、問題なし
巨大なファイルを削除するとI/O待ちが発生する
巨大なテーブルのデータファイルを削除すると他のプロセスがI/O待ちになる可能性があります
安全にテーブルdropする方法やってみた
完全にこちらを参考をさせて頂きました。
dropする前にデータファイルにハードリンクを貼り、
drop時はファイル削除を行わず、後に優先度を下げて実ファイルを削除するという流れです。
さっそく本番でもやってみました。
# データファイルにハードリンクを張る ln /usr/local/mysql/data/hoge_db/bk_hoge_tbl.ibd /home/hoge/bk_hoge_tbl.ibd time mysql -e "DROP TABLE bk_hoge_tbl" real 0m0.047s user 0m0.002s sys 0m0.002s time ionice -c 3 rm -f /home/hoge/bk_hoge_tbl.ibd real 0m14.505s user 0m0.001s sys 0m0.065s
確かに意図通り、dropはデータ量に限らず一瞬で終わり、
データ削除はデータ量によって実行時間に違いがありました。
が、、、drop中は問題ありませんでしたが、データ削除中に若干レスポンスの悪化が見られました。
巨大なファイルを低負荷で削除する方法
結局、巨大なファイルを削除する時のI/O待ちが問題なら
drop前にパーティション切ってデータ細切れにするのはどうかな?でもめんどいなーって思っていたら下記の記事を見つけました。
巨大なファイルを削除する方法
このケースが一番悩まされました。しかし、最近 truncate コマンド使えばいいのでは〜ということに気がつきました。
truncate コマンドを用いて少しずつファイルサイズを減らす
sleep をはさむ
徐々にファイルサイズを小さくして、削除すればI/O負荷軽減できそうです。
次回はこちらの手順で削除してみようかと思います♪
感謝致します。
mysql explain で出てくるSelect tables optimized awayって何ですか?
日次で開発環境で実行されたクエリにEXPLAINをかけて、危なそうなクエリを通知するようにしています。 そこでこんなんが出てきました
mysql> EXPLAIN PARTITIONS SELECT MAX(`hoge_col`) AS total_count FROM `hoge_table`;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
index貼られてないー><
↓
index貼る
↓
mysql> EXPLAIN PARTITIONS SELECT MAX(`hoge_col`) AS total_count FROM `hoge_table`;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+------------------------------+
変わらず・・・
そこでよくよく確認すると、hoge_colはprimary_keyになっていました。
で、今度は「Select tables optimized away」はなんだと。
ドキュメントを確認すると、
MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.8.2 EXPLAIN 出力フォーマット
Select tables optimized away
クエリーにはすべてインデックスを使用して解決された集約関数 (MIN()、MAX())、または COUNT(*) のみが含まれていますが、GROUP BY 句は含まれていませんでした。オプティマイザは 1 行のみを返すべきであると判断しました。
オプティマイザが良きにはからってくれた結果だそうです。 内部的にはインデックスを使っているようなので、負荷等は問題なさそうです。ほぼ最速の模様。
感謝致します。
1分でできる!mysqlslapでDBのかんたん性能調査、ベンチマーク
業務中にそこそこ大きなスキーマ変更をすることになり、実際パフォーマンスに変化があるかベンチマークを取る必要が出てきました。
jmeterとかでごりょごりょとかしないとなのかーとか思ったのですが、 今回はスキーマ変更のみなので、単純にDBのみの測定でよいので、なんかいいツールはないかと探したところ、
mysqlslapなるものがあるようなので試してみました
MySQL :: MySQL 5.7 Reference Manual :: 4.5.7 mysqlslap — Load Emulation Client
MySQLクライアント負荷エミュレーション mysqlslap を使う - Qiita
mysqlslapはMySQLサーバのクライアント負荷をエミュレートし、各ステージのタイミングを報告する診断プログラムです。サーバにたいして複数のクライアントがアクセスしているかのように作動します。mysqlslapはMySQL 5.1.4.から提供されています。
さっそく試してみーる
使い方
mysqlがインストールされていれば標準でmysqlslapもインストールされているはずなので、すぐ使えます
基本的には、測定する際特定のスキーマを作って、テキトーなクエリを実行してベンチマークを取る感じのようですが、 今回は実際の本番相当のデータ量のテーブルを用意し、それに対して測定を行いました。
#測定するSQL SELECT * FROM TMP_TABLE WHERE hoge = 'hoge'
/usr/local/mysql/bin/mysqlslap\ --no-defaults\ --user=USER\ --password=PASS\ --host=localhost\ --port=3306\ --engine=innodb\ --concurrency=500\ --iterations=30\ --create-schema=TMP_DB\ --query="SELECT * FROM TMP_TABLE WHERE hoge = 'hoge'" Benchmark Running for engine innodb Average number of seconds to run all queries: 0.755 seconds Minimum number of seconds to run all queries: 0.702 seconds Maximum number of seconds to run all queries: 0.795 seconds Number of clients running queries: 500 Average number of queries per client: 1
的な感じでベンチマーク取れます! 500回SELECTするのを30回行い、それらの最大最小平均が取れます
オプション
オプション | 内容 |
---|---|
no-defaults | 設定ファイルに書かれたデフォルトをスキップ |
user | 接続ユーザ |
password | パスワード |
host | mysqlのhost |
port | mysqlのpoot |
engine | 対象ストレージエンジン |
concurrency | シミュレートする実行の数 |
iterations | 実行するテストの回数 |
create-schema | テストを実行するスキーマ |
query | 実行するクエリ(ファイル指定も可能) |
今回は作成済みのDB、テーブルに対して実行したのですが、 他にもテキトーなクエリを自動生成して、ベンチマークを取ることもできるようです。 というかそのほうが本来の使い方っぽいですね。。。
設定ファイルいじって性能確認する的な。
ともあれとってもお手軽!
ベンチマークというと手間かかるなーと思いがちですが、 これなら、実装後にさくっと確認できていい感じです!
もっと早く知りたかった・・・!
感謝致します。