気が付いたらmysqlサーバがswapしてた
昨日の夜にmuninをフラフラーっと見てたんです。とあるDBサーバで今度作業するっていういので今の状況を確認しておこうと見たら・・・・
2GBもswapしてるじゃないですか!
アタヽ(д`ヽ彡ノ´д)ノフタ
うーん、swap I/Oの頻度はそこまで多くないから死にはしないけど原因見つけて対処しないとなっと。
前に読んだhttp://d.hatena.ne.jp/fat47/20121121/1353495937:【メモ】MySQLでのswap発生とNUMAアーキテクチャを思い出しました。
「お、確かにR410でCPU2個詰めるからもしかしたら・・・」
と思ったので搭載CPUの数を調べようと/proc/cpuinfoを見たら
1個しか搭載してませんでした・・・
# cat /proc/cpuinfo | grep physical | grep id
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
physical id : 1
8coreだったのはHTしてるっぽいですね・・・構築は他の人がやったので細かいところは知らなかったのでちょうどいい機会。
innodb_buffer_poolの設定が間違ってるのかと思いましたが、実メモリ32GBに対して24GB割り当ててたので間違ってはないようだ。他のmy.cnfの設定とか見ても特別変なところはない。
結論 vm.swappinessの設定がデフォルトでした。
kernel 2.6から追加されたkernelパラメータらしいのですが、swap領域の扱いを制御するパラメータとのこと。
このパラメータの値が小さければ小さいほどswapしにくいと。
mysqlでは0にするのを推奨しているようです。まぁmysqlもメモリに乗り切らなかったら(古いキャッシュ)結局Diskにアクセスしに行くんだからswapしようが、普通にDiskIOが発生しようが変わらないんじゃないかと。
でも既にswapしてるしってことで対応手順を
kernel パラメータのvm.swappinessを設定
vm.swappinessはsysctl.confに記述してやらないと再起動したら設定が消えちゃうのでこいつを使ってやる。
# vim /etc/sysctl.confvm.swappiness = 0 #この1行を追記
保存したら
# sysctl -p
で/etc/sysctl.confの設定を反映。サーバの再起動とか何もいらないです。sysctl -w hogehoge = xxxとかでもできた気がするけど、今回は記憶にある方法でこれを採用。まぁあとは、記述した設定がそのまま反映されるので再起動時と全く同じになるというメリットもあります。
上記コマンドでも反映されたパラメータが出力されるのですが、一応確認で
# sysctl -a | grep swappiness
vm.swappiness = 0
これで設定が反映されていることが確認できました。
が!
swapしてることには変わらないのでそれの対応。swapしたデータをメモリに戻してやる。
swapしたデータをメモリに戻す
# cat /proc/swaps
でどのデバイスをswapに割り当ててるか確認する。
今回は/dev/sda2だったので対象はこいつ
# swappoff /dev/sda2
こいつを実行してやればswapにあるデータがメモリに戻ります。メモリに乗らなければ破棄されるらしい。
戻すというかswap領域をなくしてるだけなのですが。
基本メモリは消えても困らないデータを乗せるところなので破棄されてもデータロスは起きないはず。
別のターミナルでtopコマンドとか実行しながら進捗を確認するといいと思います。
swap領域はないならないで困るので戻してやります。
# swapon -a
freeなりなんなりコマンドを実行してswap領域が戻ってることを確認したらめでたしめでたしです。
muninで確認してもswap領域が空いたことを確認できました。
これでもswapするようならmysqlの設定を1から見直す必要があります。
ちなみにこの作業を全てやるのに40分ほどかかりました。mysqlが稼働してて更新が走ってる状態なので完全に止まってる状態ならもう少し早く終るかもです。
こんな設定は1台見つけるとゴキブリの様にうじゃうじゃと他のサーバでも同じ設定になっているのが見つかるので洗い出す仕事が増えました・・・
既に10台以上確認している・・・
まだswapしてなきゃいいけど、swapしてるとやっかい・・・
自作の起動スクリプトをchkconfigに追加する方法
自作の起動スクリプトを書く時に2行加えるだけ
オープンソースだと起動スクリプトがなかったりするので自作したりしますよね?シェルで普通に起動スクリプトを書いてもchkconfigには登録できないと聞いてちょっと調べてやってみました。今回はvarnishの起動スクリプトをchkconfigに登録するために設定してみました。下記の#!/bin/bashを除く2行を追記するだけ
#!/bin/bash
# chkconfig: 2345 75 25
# description: Varnish start/stop Script
何をしているか?
# chkconfig: 2345 75 25
これはchkconfig varnish on
を実行した時にonになるランレベルを2,3,4,5と指定しています。
起動は75番で停止は25番を利用します。
この番号は$ ls /etc/rc.d/rc3.d/
K01smartd K10saslauthd K16abrt-oops K50netconsole K74haldaemon K75quota_nld K85messagebus K88auditd K92ip6tables K99cpuspeed K99rngd S09network-inject S12nslcd S13irqbalance S25cloud-init S30nscd S55sshd S58ntpd S80postfix S85httpd S90munin-node S99local
K05atd K16abrt-ccpp K16abrtd K74acpid K75netfs K85mdmonitor K87restorecond K89rdisc K92iptables K99lvm2-monitor S01sysstat S10network S12rsyslog S20kdump S26udev-post S50snmpd S57ntpdate S64mysql S84tomcat S90crond S99cloud-init-user-scripts
こうゆう番号のことです。なのでかぶらないように適当な数字を振るといいと思います。
EMOBILE(LTE)を購入したのでWiMAXと比較してみた。
EMOBILEの購入きっかけ
正直WiMAXでも十分外で使えるんですが、プチプチ切れたり、急激な速度低下によるストレスが溜まってしょうがないのでEMOBILEを購入してみました。私はプライペートではMac Book Airを使っているのでネットにつながっているかをターミナルでずっと自鯖にpingを打って確認しています。
- プチプチ切れる
というのはpingでRequest timeout for icmp_seqが頻繁に発生するのです。この状態ではネットに繋がっておらず、ヘタすれば再接続することもなくPCからWi-Fiを切って再接続する必要がありました。
- 急激な速度低下
だいたいpingのtimeが100msくらいなのですが、急に数千ms〜数万msとおかしな値になり実際に通常のwebページを表示するのも困難に・・・
- 地下でもないカフェで全く電波が入らないことも・・・
回線速度比較
Mac Book Airから比較
Mac Book AirからはUSENのスピードテストを利用しました
平均するとWiMAXは3Mbps、EMOBILEは6Mbpsと倍くらい違いました。LTEの方が理論値上ベストエフォートが大きいので速くないと困るわけなのですが、ここまで違うとなるとちょっとWiMAXは使いづらくなりますね。ただでさえ安定しないのでWiMAXは極力使いたくない感じです。これからの使い道はEMOBILEの電池が切れた時にWiMAXを利用するというくらいでしょうか?あとはPCはEMOBILE、mobile系はWiMAXと使い分けるのでもいいですが。
※今回は試行回数が少ないので絶対とは言えない数値ですが、私が計測した場所ではこのような違いが出ました。WiMAXの端末自体1年半前のものなので端末の劣化という可能性もありますし、電波状況や他のWi-Fi端末からの干渉によって数値は全然異なってくるので鵜呑みにしないようお願いします。測定場所は吉祥寺の某2Fです。
パナソニック モバイルバッテリー 5,400mAh 無接点充電(Qi)対応 USBモバイル電源 ブラック QE-PL201-K
- 出版社/メーカー: パナソニック
- 発売日: 2011/06/24
- メディア: エレクトロニクス
- 購入: 15人 クリック: 432回
- この商品を含むブログ (27件) を見る
チューニンガソン #4に参加してきました
ゼロスタートさんの公式のブログの方でまとめられてましたので追記 【2012年7月4日】
【レポート】いろいろチューニングしてパフォーマンスを競うバトルイベント!「Tuningathon」第4弾! #tuningathon
チューニンガソンとは
http://www.zusaar.com/event/312053
アプリ以外のインフラ部分だけをチューニングしまくってとにかく速くするというバトルです。
前回参加した時のエントリーはTuningathon 2!に出てきましたです。この時はMediaWikiでいかに速くレスポンスを返すかという回だったのですが、nginxのプロキシの設定を間違え測定不可という結果に終わってしまいました(´・ω・`)・・・
今回はRuby on RailsのRefineryというOSSのCMSが対象でした。
- RoR refineryのコメントPOST/GET回数
- 10並列で一定秒数間測定
- 秒間平均POST/GET回数がスコア
- エラー返却は単純に除外
- POSTはGETの10倍のスコア
- POST後のGETによる反映チェック
- 反映チェックの成功率の二乗をスコアに乗算
がバトル条件でした。
サーバは
であり、スペック的には少々厳しい感じです。
チューニング開始
まず最初に行ったのはtmuxをyumでインストールして、自鯖からconfファイルを持ってきてペイン分割してとtmuxがないとダメな子なので最初にやりました。使い方は前のエントリーから
とりあえず、やることに困ったのでtmux入れてconfを自鯖からコピーした #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
メインウィンドウを3ペインで分割し、1つをtop -d 1を実行し、1つをperf topでベンチマークを実行した時に何が起こるかを確認しました。LL言語はさすがというか、とにかく重いんです。第2回の時もPHPが重すぎて・・・
今回はRoRと全くの未経験ゾーンだったのでとにかくベンチマークを実行・眺めるをやってました。
実は最初の時はベンチマークがうまく走らず、エラー箇所をベンチマークスクリプトの中身から確認したらtry〜catch部分でExceptionが発生していました。おかしいな、おかしいなと半ば諦めも若干入りつつ一旦Google先生にRoR関連のチューニングを調べていました。
何もしていないのにベンチマークを走らせると例外処理をキャッチして計測できない(´・ω・`)・・・これは何が悪いんだ? #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
実はrailsの実行をrootで実行しなきゃいけないのに一般ユーザで実行していて問題になっていたようですw
ベンチマークできたw Score: 2.781 何もしてなければこんなもんか #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
これに気づいたのが13:30頃。まだScoreは2.7くらいのデフォルト状態。いろいろ試してみるも対して変わらない時にTLに
#tuningathon ktkr! Score: 538.924 (get=533.415, comment=5.509(6), check=1.000)
— ばば としあきさん (@netmarkjp) 7月 1, 2012
とか流れてきて、@netmarkjpが強すぎて泣きたくなりましたwトップが1100???((((;゚Д゚)))) #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
更に15時頃1100という謎な値を叩きだす@netmarkjpさん。自分はこの時3とかをさまよってました
16時手前にRubyのEnterprise Editionのインストールが終了して、PATHの設定を書き換えて計測したら5を超えました。
でも@netmarkjpの200分の1というもう絶望的な値でした。この時にはもう20を超えるような人も出始めていました。
Score: 5.156 全然上がらない(´・ω・`)・・・ #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
16:30にPassengerのインストールが終わりapacheのデフォルトポートを3000に、DocumentRootをrailsに当てるという無理やりな構成にして10手前まできました。
Score: 9.087 うーん上がったけど全然だな(´・ω・`)・・・ #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
Passengerの設定をいろいろ変更してみて再度ベンチマークを何度か走らせた時に自己最高の16が出て喜びました。
Score: 16.002 まで来た #tuningathon
— ヌキっぽいなにかさん (@editnuki) 7月 1, 2012
間に公式の測定が走っており、そのタイミングでtop10が10超えくらいだったのでもしかしたらと思ったのですが、この時には結構時間も立っていたのでもうみんな20くらいなのかな〜っと諦めモードも若干入りつつ。Passengerの設定を何度も変えてベンチマークを走らせるということをしていました。多分最後1時間くらいほとんどPassengerいじってましたね。
最後30分くらいになってmysqlのinnodb関連をチューニングかけるかと思いつき、自鯖の設定を丸々コピーして貼っつけましたwww時間がなかったのでコピペで何か変わればいいかな〜くらいにしか思ってませんでしたが、何も変わらず。
自分が一番の失敗だったのはapacheの再起動をした時にScoreが一回急激に下るという現象が何かを本当の意味で理解していなかったことだと思います。単純に何度か行うとキャッシュが聞いてScoreが上がるんです。なので今回トップ2の2組はvarnishでひたすらキャッシュするというので1000を超えるScoreを出していたようです。
自分は気づかずずっとRubyだけ触ってました。CPUバウンドするRubyをどうにかして軽くしたいとしか思ってなかった時点で上位は厳しかったようです。
結果発表
9位 editnuki さん! #tuningathon
— りこさん (@RicoImazu) 7月 1, 2012
なぜか9位に入賞してしまいました(^^)
呼ばれた時にびっくりし過ぎて、前でしゃべってもテンパってて何を喋ったかも覚えてませんwすいませんでしたw
#tuningathon editnukiさん 17.14 nginxとpassengerかな?InnoDB buffer_poolなどを調整した。
— 新党matsuuさん (@matsuu) 7月 1, 2012
nginxは使用せず、apacheを利用しました。Passengerは以下の様な設定にしました。
LoadModule passenger_module /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-3.0.13/ext/apache2/mod_passenger.so
PassengerRoot /usr/local/ruby-enterprise-1.8.7/lib/ruby/gems/1.8/gems/passenger-3.0.13
PassengerRuby /usr/local/ruby-enterprise-1.8.7/bin/rubyHeader always unset "X-Powered-By"
Header always unset "X-Rack-Cache"
Header always unset "X-Content-Digest"
Header always unset "X-Runtime"PassengerMaxPoolSize 40
PassengerMaxInstancesPerApp 2
PassengerPoolIdleTime 3600
PassengerUseGlobalQueue on
PassengerHighPerformance on
PassengerStatThrottleRate 20
RailsSpawnMethod smart
RailsAppSpawnerIdleTime 86400
RailsFrameworkSpawnerIdleTime 0
ギリギリまでいじったのは
- PassengerMaxPoolSize 40
- PassengerMaxInstancesPerApp 2
の2項目だと思います。メモリが余っていたのでPoolSizeを上げてみてもっとキャッシュできないかと試したり、インスタンス数をCPU*2にしたりなどして調整しながら一番いい値の時の設定を採用しました。
my.cnfは
と本当に何も考えずコピペしただけでした。
max_connections = 500
bulk_insert_buffer_size = 8M
nice=5
query_cache_size = 16M
query_cache_limit = 1M
thread_cache_size = 1
innodb_buffer_pool_size = 512M
innodb_additional_mem_pool_size = 4M
innodb_log_buffer_size = 8M
innodb_log_file_size = 64M
innodb_log_files_in_group = 2
今回このようなチューニング方法を採用した理由はrx-7乗りのnamikawaさんのブログを見つけたところからこのようにしました。
3年前のエントリーですが、基本は変わらないので採用してみました。
当日はアルバイト時代にインフラコンビを組んでいたYosuke Yamamotoさんにわからないところをちょいちょい聞いて教えてもらったりしたので1人で結果を出したわけではないので次回は本当に1人で結果が出せるようにしたいです。
今回の1位2位の上位者たち。
VOYAGE GROUPさんのアジトを会場で懇親会が行われました。いつもいつも会場提供とお酒の提供をありがとうございます。
AWSの提供をして頂いているAmazonさん、取材にいらした技術評論社の方、運営をして頂いているゼロスタートの方々いつも楽しいイベントにして頂きありがとうございます。
自分が優勝するまで続けてくださいw優勝したら勝ち逃げしたいですwなので数年〜10数年続けていただけるとwwww
そして2次会は近くの権八で技術話をつまみにお酒と翌日の朝は起きるのが辛かったです・・・
TwitterのURLの部分やgistの部分がちゃんtp表示されるかわかりませんが、参加したエントリーになります。
rackhubの時刻がおかしかったので直してみた
時刻がおかしいことに気づいた
watchコマンドでとあるコマンドを1秒間隔で実行していたのですが、watchコマンドを実行すると時刻が表示されるわけです。
まずはntpが入っているか確認したらインストールされていなかったのでインストール。
debianなのでaptitude
# aptitude install ntp
インストールが終わったのでまずはntpqで現在の設定を確認
# ntpq -p
remote refid st t when poll reach delay offset jitter
==============================================================================
+219x123x70x90.a 192.168.7.123 2 u 60 64 1 10.250 942.395 0.066
+ns.bio.keio.ac. 131.113.1.16 2 u 59 64 1 13.035 945.438 0.050
-chiba.ocn.likk. 133.100.9.2 2 u 25 64 1 39.404 960.892 4.935
*laika.paina.jp 203.178.137.183 2 u 30 64 3 10.073 944.949 0.040
ん?大丈夫そうだぞ?でもいつまで経っても9時間くらいずれているので/etc/ntp.confを編集しました。私が使うのはntp.nict.jpとntp.jst.mfeed.ad.jpの2つです。
これを設定したのですが、10分以上経っても反映されず・・・9時間というずれ方に疑問は感じていたのですが気づかず・・・
ntptraceでntpサーバへ接続してみることにしました。
# ntptrace ntp.nict.jpタイムアウトになりました。(実際他のサーバからやってもタイムアウトになったので仕様のようです)。全く違うclock.tl.fukuoka-u.ac.jpに実行したところ普通に返ってきました。
ntp-b2.nict.go.jp: timed out, nothing received
***Request timed out
# ntptrace clock.tl.fukuoka-u.ac.jp
clock.tl.fukuoka-u.ac.jp: stratum 1, offset 0.000000, synch distance 0.000645, refid 'GPS'
なのでこのドメインも追加してntpを再起動したのですが変化なし・・・
友人の助言
HI_PONが「rackhubようわからんけど、UTCなんじゃないの?JSTにすればいいんじゃね?」
( ゚д゚)ハッ!そういえばそんなん前に見た気がする!ということで調べたら見事UTCになってました。
# date
Tue May 1 13:53:50 UTC 2012
UTCからJSTに変更するために下記コマンドで環境変数を変更
# export TZ=Asia/Tokyo
そしてntpサーバを再起動かけたら日本時間に直りました。
# date
Wed May 2 01:06:28 JST 2012
とりあえず、これでtmuxとかwatchを使ってる時にターミナルで時刻を確認できるようになりました。
※Macの電源が切れそうで走り書きしたので汚くて申し訳ないです・・・
memcachedの自動再起動スクリプトを書いた
「おかしい」とか「間違ってる」などありましたら、バンバンご教授くださいませm(_ _)m
実装環境
私が管理しているサーバはすべてNagios+nrpeによる監視をしているのでnagiosのpluginが入っています。
もし入っていない場合はtelnetで書き直すなどtcp接続のコマンドを利用してください。
実行するコマンドの出力確認
今回利用するpluginのオプションは以下の通りになります。
# /usr/lib64/nagios/plugins/check_tcp -H localhost -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime'
このコマンドを実行すると下記の出力が得られます。
TCP OK - 0.001 second response time on port 11211 [STAT pid 26729
STAT uptime 2213898
STAT time 1334472012
STAT version 1.4.5
STAT pointer_size 64
STAT rusage_user 6.167062
STAT rusage_system 8.447715
STAT curr_connections 10
STAT total_connections 27880
STAT connection_structures 11
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT get_hits 0
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 195184
STAT bytes_written 22385028
STAT limit_maxbytes 134217728
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT evictions 0
STAT reclaimed 0
END]|time=0.000521s;;;0.000000;5.000000
この出力の中から不変的な文字列を抽出し、比較することで異常を検知することが可能です。
今回利用した文字列は”TCP OK”になります。
スクリプトの詳細
1回のチェックで失敗した場合に再起動をかけてしまうと誤検知による再起動がかかってしまう可能性があるので複数回チェックを行います。
自動再起動のスクリプトは以下の通りです。
#!/bin/bashTCPCHECK_CMD=/usr/lib64/nagios/plugins/check_tcp
CHK_OK="TCP OK"
COUNT=1while [ $COUNT -le 3 ];
do
RES=`$TCPCHECK_CMD -H localhost -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' | awk '{print $1,$2 }' | head -n 1`if [ "$RES" = "$CHK_OK" ]; then
echo "memcached status OK"
exit 0
else
echo "memcached status NG"
fi
COUNT=`expr $COUNT + 1`
sleep 30if [ $COUNT -gt 3 ]; then
/etc/rc.d/init.d/memcached restart
echo "RESTART"
fidone
exit 0
実行した時の出力
次にmemcachedが応答しない場合にスクリプトを実行します
memcachedが応答しない場合を作るためにあえてmemcachedを停止してから実行しました。
# sh memcache_restart.sh
memcached status NG
memcached status NG
memcached status NG
memcached を停止中: [失敗]
memcached を起動中: [ OK ]
RESTART
再起動されたかをpsコマンドで確認します。
# ps uaxf |grep memcached
root 21438 0.0 0.1 65460 832 pts/0 S+ 15:57 0:00 \_ grep memcached
root 21150 0.0 0.1 69016 764 ? Ssl 15:57 0:00 memcached -d -p 11211 -u root -m 128 -c 1024 -P /var/run/memcached/memcached.pid
現在時刻でmemcachedが起動していることが確認できました。
正常に再起動されることがわかりましたが、これだといつ再起動がかかったのかわかりにくいのでrestartをかけるところに|を利用して自分のメールアドレスに対してmailコマンドを実行すればいいと思います。
複数サーバに仕込む場合にはどのサーバが再起動されたか確認するために件名にホスト名が入る様にするのもポイントになります。
〜忘れていたので追記〜