Azure App ServiceのMysql In Appが自由でよかったメモ
昨日AzureのApp ServiceというPaaSがレンサバみたいにつかえて便利!というある意味怒られそうなエントリを書きました
しかし、レンサバにはFTP以外にもう一つ重要なものがあります。そう、DBですよね。
PHPerとしてはMysqlがつかいたい、そしてApp ServiceにもMysqlはあるのです!
App ServiceでつかえるDB
まず、Azureには「SQL データベース」という機能があります、AWSで言う所のRDSです。本来これをつかうのが正しい道だとおもいますね。ただ、SQL Serverなんですよね…。後、高くはないんですけど、月500円くらいからです。
この他に「Clear DB」というものが「あった」っぽいんですけど、いまはどこにあるのかよくわからないです。
あとはVMのテンプレートにMysqlもありますが、せっかくのPaaSだと思うと、ちょっと面倒ですよね…。
さて、ここまでもったいつけましたけど、タイトルの通りMysql In App
のお話です。
DISCLAIMER
このエントリでは、AzureとそのAppServiceが提供する拡張性や可用性をほとんど活用してません。このエントリは単純にセコいエンジニアがAzureで遊びでApp Serviceにトライしてみた感想です。つまり、試用や遊びの割り切った範囲で活用する方法の紹介で、(おそらく)「正しいプロダクション環境の運用」とは方向性がちがいます。(そもそも、mysql in appがそういうものじゃないしね)
また、後半にmy.cnfとかの事をかいていますが、マネージドのサービスで公式に用意されていない手段を模索するのは(一般的に)お行儀が悪い行為です、こういったことを推奨するものではありません。ただ、お行儀がよくないと理解しつつ、App ServiceとMysql In Appの理解にはつながると思いますので掲載させていただきます。
Mysql in app(プレビュー)とは?
App Serviceのコンテナ内に、専用のmysqldをつくる事ができます。
説明文をコピペしますと、「MySQL In App (プレビュー) では、アプリでローカル MySQL インスタンスを実行しつつ、App Service プランのリソースを共有できます。MySQL In App を使ったアプリは、運用環境での使用を意図したものではありません。また、単一のインスタンスの範囲を超えてスケールすることもありません。」だそうです。
ということで、やはり肝心の所は良く解らないのですが、まあ極小規模な主に開発用なんだと言いたいのは伝わります。
使い方
「MySQL In App (プレビュー)」のスイッチをオンにするだけ!(?)
「お作法」
次は管理ですね、テーブルとか作りたい。すぐさまその画面上の「管理」をおしましょう!すると我々に馴染み深いphpMyAdminが立ち上がります!
…が、実は地味にわかりづらい作法があるようです。もし以下のようなログイン画面が表示されたら、一見さんお断りで失敗です。
この画面をみたら人はかけずり回ってID/PASSを探すでしょうが、実はどこにもID/PASSは書いていません…。*1
なにいってるのかわからないでしょうが、兎に角この後の手順を踏んでみて下さい。
- 一旦閉じて、概要にいってアプリを再起動(これは大抵不要)
- なんでもいいのでアプリ内のphpのURLを開きます(phpinfo()だけとかでもよい)(これは必要)
プロセスエクスプローラー
をひらき、最新の情報に更新を押します(これは任意)- あらためて
Mysql in App
の中の管理
をひらいてみてください
うまくいけば「ログインした後のphpMyAdminが開けるはずです!やりましたね!!
(「なにいってんの」って思われるかもしれませんけど、本当にこれ気付くまで地味にハマったので)
うまくいった場合のプロセスエクスプローラーの表示は(個人差あるでしょうが)こんな感じです*2
あと、この画面もダメですが。これも上記の手順をおこなったり、phpのURLをなにかひらけばもどってくると思います(多分mysqlプロセスが終了してしまっている)
phpMyAdminについて
説明いらないじゃろ?
mysqlの状態や、渡される権限について
phpMyAdminで接続してみると、azure
というアカウントがわりあてされ、azuredb
というDBが最初から作成されているのがわかります。なるほど、これをつかえばええんじゃな…と思うのは早計だ!(いや、これでも十分なんですけど)
User Accountを確認すると、なんとazureには「ALL PRIVILEGES」が付与されているのだ!すごい!!つまりDBをドンドンつくれます!(GRANT権限はないけどね)
共有サーバーなのにどういうことなのと思われることでしょうが、先程のプロセスビューザーでみた通り、自分専用のmysqldが立ち上がっているのでこういう感じなんでしょうね。富豪的だ。
となれば、勿論mysqlのdata dirも見える所にあります。data/mysql
以下にあります。my.cnf(いや、Windowsだから、my.iniでもいいか)も、その中に置けば読んでくれるはずです。(残念なら後述)
ちなみに、Mysqlのバージョンは5.7.9でした。
PHPからの使い方
phpMyAdminがさわれれば、初期のスキーマ流し込みとかは問題無くできたとおもいます。次はアプリからの接続ですね。
詳しくは以下のURLをみていただきたいのですが、(一部の人には残念)英語です。
端折って言えば、Mysql In Appの接続情報は環境変数経由で渡されます。$_SERVER["MYSQLCONNSTR_localdb"]
にはいっています。(このキー名は固定ではないかもしれない。Mysql In Appの画面にありますので、そこからコピペしましょう)
こいつは(ここにサンプルは貼りませんけど、なかなか「なんでやねん」「マジか」感のある)文字列ですので、これを切った貼ったしましょう。上のURLの中にサンプルコードがあります。
私は「なんでやねん!」と言ってしまったので、自分で書きました。一応以下に置いておきますが、公式のコードをつかうのが一番でしょう。
<?php if(!isset($_SERVER["MYSQLCONNSTR_localdb"])) throw new Exception('MYSQLCONNSTR ENV is not defined'); $azure_mysql_connstr = $_SERVER["MYSQLCONNSTR_localdb"]; $azure_mysql_connstr_match = preg_match( "/". "Database=(?<database>.+);". "Data Source=(?<datasource>.+):". "(?<port>.+);". "User Id=(?<userid>.+);". "Password=(?<password>.+)". "/u", $azure_mysql_connstr, $_); if($azure_mysql_connstr_match === false) throw new Exception('Could not parse for MYSQLCONNSTR ENV'); $db_settings = [ 'host' => $_['datasource'], 'port' => $_['port'], 'database' => $_['database'], 'username' => $_['userid'], 'password' => $_['password'], ]; var_dump($db_settings);
さあ、これで無事にmysqlがつかえるようになりましたね!(?)
まとめ
良い点
- 本物のmysqldである
- 自由度が高い
- mysqlのバージョンも新しくて最高
- 基本無料である()
- 「(慣れ親しんだ)phpMyAdmin最高!」
悪い(悪かった)点
本物のmysqldを管理者権限で渡してもらえるみたいなので、そこらのレンサバより断然自由度が高い。これは遊びや開発だと最高ですね。(まあ、コンテナのクオータにかからないように注意する必要はあるでしょうが)
とはいえ、最初からユーザーもDBもつくってはあるわけで、初心者でmysqlよくわからんという人も、そこらのレンサバと大差無く使えるのではないか(ユーザー名とかを環境変数から引いてくる、というのに慣れないかもしれませんけど、まあ慣れるやろ)。壊してもすぐに作り直せるし、mysqlの練習にも最高ではないでしょうかね。
これをそのままプロダクションには使えないとおもいますけど、まあ中々面白いですね〜。 PHPとMysqlがあれば、8割くらいのPHPerの雑な遊びは満足するのではないかなとおもいます。 是非みなさん試して見てはいかがでしょうか。
こちらからは以上です。(多分、続きます)
(ところで、Mysql一つで200Mbyteくらい食うので、省メモリなmy.cnf設定というあまり考えた事がないことをやらないとな…)
追記
プロの着眼点による指摘
5.7.9!! default_password_lifetime(おっと誰か来たようだ)
— yoku0825 (@yoku0825) 2016年9月25日
とのこと!!!! pic.twitter.com/nx3k4lCfBk
— uzulla (@uzulla) 2016年9月25日
select @@default_password_lifetime
で確認したところ、5.7.9の有名な時限爆弾があるようです。(詳細は後述の参考リンク)
さっそくmy.cnfに修正をいれてみようとしました…が。どうもmy.cnfが反映されない。
んんん?とおもいつつ、いろいろやった結果以下の出力を得ました。
んんん〜〜〜〜(;´Д`)
D:¥home以外は共有されない気がする…
まあ、360日経過するよりも前に5.7.9が5.7.11以降になるんじゃないですかね!?
(参考リンク) yoku0825.blogspot.jp
(この作業でAdvanced Toolsの使い方になれてきましたので、またエントリ書きます…)
追記 my.cnf(あるいはmy.ini)の設置について
調べた結果、以下のmy.ini(cnf)を読むようなのですが、どれもデバッグコンソールからいじる権限がない。
Default options are read from the following files in the given order: D:\Windows\my.ini D:\Windows\my.cnf C:\my.ini C:\my.cnf D:\Program Files (x86)\mysql\5.7.9.0\my.ini D:\Program Files (x86)\mysql\5.7.9.0\my.cnf
ウーム、ダメかー。
AzureのApp Serviceを試したら、なにげにレンサバ属性が高いとおもったメモ
DISCLAIMER
このエントリでは、AzureとそのAppServiceが提供する拡張性や可用性を全く!活用してません。App Serviceは実際に中〜大規模のサイト運用でつかわれていると聞いていますが、このエントリに示すやり方は単純にセコいエンジニアがAzureで遊びで、App Serviceにトライしてみたものです。
このエントリでは一部安く利用する事について書いていますが、特にお金周りは保証も補償もできないので、自分で調査してください。(わりとカジュアルに錯誤課金できるWeb UIです)
私もドキュメントは読んでいるつもりですが、なにか「正しくない」かもしれません。Azureは公式ドキュメントが充実しているので、是非読んでみてはいかがでしょうか。*1
マクラ
先日ISUCONでAzureを触って以後引き続きちょこちょこ触っており、段々とAzureに対する印象ができてきた感じがある当方です。
Azure識者いわく、App Serviceを是非さわってみて!との事でしたので、つらつらと読んでみたら「タダっぽいプランがあるぞ!」と貧乏性をくすぐられ、俄然意欲が湧きました。やってみて色々おもしろかったんですが「ほほう、そう来ますか」「たしかに定石は破る為にあるよね」などといった独り言が多かったので、メモとしてこのエントリをかきます。
先取りのオチとしては「タダ(に近い安価)で遊べるやん!!最高や!!だがしかし…」です。
App Serviceは平たくいえばPaaSであり、Azure版のHerokuです。GCPだとGAE、AWSはElastic beanstalkでしょうか。*2
所で、私を含めてPHPerはあんまりPaaSに縁がない気がしますね、試しでもつかった事がない人も多いのでは?多くのPaaSが(意外かも知れませんが)PHPをサポートしているのに、使われている話を(私は)あまりきかない。
理由は様々でしょうが、PHPには昔から「レンサバ」というPaaSっぽいもの()があるんですよね。最近の言語を用いたウェブアプリ開発には存在しない概念ですし()、もう若い人は使ったことすらなさそうでありますが、Herokuあたりが出てくるまではPHPとCGI以外に対するアドヴァンテージでしたよね(ホントか?まあ、ここでは他所に置きます)。
で、PaaSを使う事についてのハードルの高さ、あるいは腰の重さがどこにあるかといえば、そのレンサバ(や、LAMP)世界観の影響がある気がします。実際に実務でつかうことを検討すると、よくあるご要望がPaaSでネックになることが多いのです。
たとえば…コストはワンコインがいいとか真顔でいわれたり(PaaSは決して安くない)、「すでに入稿済みの広告に掲載されたURLがあるから、そこにWPをいれてくれ」っていわれた結果「突然アプリのレポジトリにwordpressが爆誕!!!」とか(PaaSは普通git経由でデプロイする)とか…、いやそれは案件次第だろといわれればそうなんですが、PHPはやっぱりそういう所あるので…。
話がずれました(そのような「世界線のお客様(案件)」は若い人には本当に通じない事があるので、一応書きました)
勿論PaaSはレンサバでないし、そうあるべきでもない、だからこそクラウドでありカッチョよく便利なわけですし、オートスケールやそのクラウド特有のオブジェクトストレージがあったりして、レンサバとは価格も機能も自由度も一緒にする必要はないんですが、まあ悲しいかな日常の歯ブラシ業務はレンサバで十分、むしろ歯ブラシくらい雑に何にでもつかえないと困る事が多く、PHPはPaaSはあまり普及せず、レンサバ、VPS、専用サーバー、みたいな感じが多い気がします。
AzureのApp Serviceの話にもどしますが、App Serviceをちょっとさわってみて「これは使えるかもなあ」と思ったのは、悲しいかなその辺りの関係であり、わりとレンサバっぽい使い方もできないことはない…のがPaaSとして逆に新しいな!という所でした。たとえばFTPとかね!つかうかはさておき!
こう言うと、「ゲーッ」っておもいます?僕も他人事ならそう思うんですけど、でも突然お客さんが「今日からこの協力会社さんとやってくれたまえ!まずはFTPアカウントをメールでください!」ってなるんだよな!助けてくれ!
App Serviceのレンサバ風使い方
さて、大まかな手順がこちらです。わかるひとはこれで十分でしょ、運がよければ一発でクリアできます(?)
なお、クリック数は作業の面倒くささの心境を表しており、実際のクリック数とは乖離があります。
- App Serviceを作る(10クリックくらい)
- 「Web + モバイル」とタイトルにあるテンプレート一覧*3から、素の「Web App」をえらぶ
- (コンテナについては)今回無料にしたいので、必ずApp Serviceプランを変更する(ミスると月額8000円)
- App Service プランのロケーションは日本なら「Japan East」或いは「Japan West」がよいでしょう
- 0.00JPYの「F1 Free」は右上の「全て表示」を押さないとでてきません
- App ServiceやApp Service プランやResource Groupとかの名前は適当に
- App Serviceの概要をひらき、サイトがひらけるか確認(4クリックくらい)
- デプロイ設定をする
- デプロイ(アップロード)できれば後は確認(3クリック)
どうですか?できました?できた人はお疲れ様でした。
ということで
スゴくお手軽にサービス(?)をたちあげられたぞ!しかも「コンテナの分は」無料っぽいぞ!やった!雑に客見せとかするとき最高かもしれんね(?)
一応書いておきますが、これは「完全無料」ではなく「コンテナの分」についてのみ無料。つまりコンテナのマシン(CPU+ローカルStorage)について適用されるもので、転送量とかは勿論従量課金のはずです。いやでもコンテナが無料なのは結構すごい事ですよ、そういうのが無料でなくなったPaaSもありますし。
ハマリ所や疑問ポイント等をつらつらと
色々不思議な所もありますので、書いていきます。
「再起動するとデータは消えるの?」
App Serviceに再起動ボタンがあるが、これをおしてもファイルは消えない。FTPでデプロイできるのだから当然といえる。
なにかの操作で消えるかもしれないが、いまのところ消す操作を見かけていない。
アクセスがないとプロセスは積極的に終了しているようにも見える(ので、再起動は頻繁にされているようなもの?)
無料コンテナは何個までつくれるの?
10個っぽい。
ただし、クオータがありCPU、Disk、帯域などの上限がきまっています。まあ無料レンサバでよくあるやつです(時間経過でリセット)、課金することでシームレスにクオータは外れる模様。
FTPアカウントの「このユーザー名とパスワードを使用すると、Microsoft Azure アカウントに関連付けられているすべてのサブスクリプションのどのアプリにもデプロイできます」ってなんなの
「それな」
書いてある通りですが、「Azureの中では自分がつかうFTPのIDとPASSが全部統合されています」。なので、ここで設定したID/PASSは他のApp Serviceでも同じものを(厳密には、IDはPrefixが付くのですこし違って、パスワードは同一)使う事になります(一度設定すれば、二度は設定しない)。
ただし、これは「このApp ServiceにアクセスできるFTPアカウントが一個しか発行できない」…ではなく!ユーザーはリソースグループで追加できるわけで、それらのユーザーが「自分で自分のFTP IDとPASS」管理できる、剥奪もRG経由で綺麗にできる、ということ(のよう)です。
さすがマイクロソフト!Active Directoryで培われた縦横無尽な大統一認証基盤だ!すげえ!…といいたいところではありますが、普段からしょぼいUnixのACL*4になれしたしんでると、本当に不安になるのでもうちょっとなんか書いてくれるとUNIX系原始人に優しい。
Github連携の挙動がおかしいんだけど
- 認証がうまくできない>ブラウザをとじてやりなおしたり、日をあらためてみよう
- 本当によくわからない感じになっている>
概要
からアプリを再起動してみよう、プロセスも見よう - リポジトリ一覧、ブランチ一覧がでない>裏でがんばってるかも?数分(なにも動いてなさそうでも)待ってみよう。リロードしてみよう
- pushして反映されない、状況がわからない>
デプロイオプション
で状況がみれるはず、最初はなんか反応悪い気がする…。 - 本当に(どこに)ファイルがおかれたの?>FTPや、
コンソール
をつかってファイルがどう配置されているか確認しよう
ログはどこ?
ログ周りは私が把握しているかぎり一番辛いポイントです。
まず、すべてのログはデフォルトオフです。よって診断ログ
から、Web サーバー ログ
(アクセスログ)をオンにしましょう。
するとログストリーム
から見る事ができます…が、ものすごい遅延するし、過去分を見れません(ログとは…?)。
しかたないので我々は生ログを見る事になります。ログファイルはLogFiles/http/Raw/Logs
にかきだされており、「FTPで」DLできます。FTPか…。
まあ、アクセスログなんてどうでもいいですよね、必要なのはエラーログです。やはりデフォルトではエラーログはどこにもでません、さらに厳しい事にGUIからは設定ができません、なんでだ絶対必要でしょ。
出力されない理由はphpinfoをみるとわかりますが、log_errorsがoffになっていますのでonにしましょう。設定すればLogFiles/php_errors.log
に無事に書き出しはじめます。やっぱりFTPでDLは必要なんですが。
onにする手法は皆さんご存じの通りですが、コードにini_set("log_errors", 1);
とか書いちゃう方法と、php.iniに指定する方法です、php.iniはいじれない(と思う)ので、Document Root直下等に.user.ini
を指定するとよいのではないでしょうか*5。
なお、他にも診断ログ
画面ではアプリケーション ログ (ファイル システム)
、詳細なエラー メッセージ
などがありますが、これらはPHPにおいては一切意味なさそうです(IISのエラーHTMLが出力されたりしています)
その他、聡い人は気付くとおもいますが、「PHP デバッグ」という項目がありAzure App ServiceはなんとZ−rayがつかえるのです!デバッグとありますし、もしかしてこれでなんとかなるのでしょうか!
残念!なんとかなりません!オチからいえば
- Exceptionは見れるが、Fatal Errorはみれない(PHPのバージョンにもよるかもしれない)
- (Free版で)Enableにすると、あらゆるアクセスでZ-rayのダッシュボードがでてしまう(まあこれは開発用なら正しいが)
- (多分)CPU時間や、ディスクスペースを消費するので、クオータを使い切る要因になりそう…
まあ、Z-ray自体は便利なので、使ったことが無ければためしてみるといいとおもいます。
まあ色々かきましたけど、ここは男らしくPHPの最高機能、display_errorsをオンにしてしまうのが一番なのではないでしょうかね…(苦笑)。
最後に重要なことを書くと、ディスクスペースが潤沢ではないのですから、調査なりがおわったらログは切った方が良いでしょう。(多分)ログローテーションの仕組みはありません*6。
追記、ログについてエントリかきました
PHPのバージョンや、directory index変更はどうするの?
アプリケーション設定
から変更できます。
Directory Indexは既定のドキュメント
項目です。まあPHP的にはindex.phpとindex.htmlだけで十分ですが、色々あります。htmlがphpより上なのだけはさっさと直した方がよいでしょう。
ところで、既定のドキュメントを見て見慣れない布陣だとおもいましたか?そうです、これはIISです!Apacheではないのです。
.htaccessはどうすればいいの?
フレームワークをつかってアプリをかいたらmod_rewrite相当のことは必要になりますよね、しかし上述したとおり、App Service はIISであり、.htaccessはよみこめません。web.configを書いて代わりに置くことになります。
あなたが利用しているフレームワークが有名なものなら大抵IIS対応のweb.configも配布しているでしょう。まあそこまでスゴイ難しいものではないので、ググればどうにかなります。
あくまで一例ですが、slim frameworkは以下のように書くようです。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="slim" patternSyntax="Wildcard"> <match url="*" /> <conditions> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="index.php" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
なぜか403でアクセスできないファイルがある
私は/vendor/css/bootstrap/bootstrap.min.css
というパスのアクセスがどうしても403になりました。
「The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.」とか言われます。
よくわからないんですが、/css/bootstrap.min.css
と、ファイルを移動し、パスを変更したら動いたので、IISかなにかの予約語を踏んだ気がします。
(こういうときに詳細なエラーログが役立つ!のかなとおもったんですが、これは念力で解決しました…)
まとめ
良い点
- 別途のツールが不要(Tool beltとかいれなくていい)
- git不要!FTP(FTPS)!
- (協力会社さんにやさしい!!(かもしれない…))
- 試すだけならほぼタダで始められるし、遊びにもつかえそう
- なんだかんだ最初の自腹が安く済むのは重要
- PHP7がちゃんとある(という安心感)、なお5.4〜7。
- Freeコンテナでもhttpsが無言で付いてくる、流石
- ちゃんとつかえば、ちゃんとPaaSっぽい(使い込んでないのでまだなんとも)
- 課金は1000円くらいから(共用サーバー、独自ドメイン)
- 「グローバルにリージョンがあるレンサバと考えると唯一無二感でるな!」「その需要、ニッチすぎるのでは…」*7
悪い点
- 「これはWindows(IIS+PHP(fcgi))です、郷には入れば郷に従え」
- ログを見る環境が致命的に酷い
- display_errorsで解決…(?)
- (追記、ログについてエントリかきました Azure App Serviceで快適にログをtail -fしたい話 - uzullaがブログ
- (使えなかったから書いて無いけど)コンソールが予想の3倍つかいづらい
- 左右カーソル移動ができない、なんとファイル名補完もきかない(懐かしい)
- 上下で履歴は出ます
- viがない(これは言いがかりだな)
- sshさせてくれ!
Advanced Tools
はなんかまともそう、PowerShellがつかえる(つまりtailも?)これは後で試すぞ!- (追記、試しました Azure App Serviceで快適にログをtail -fしたい話 - uzullaがブログ
- 安定して挙動不審なWeb UI
- 遷移してるだけで設定がまきもどったり
- 昨日できたはずの事ができなくなったり
- こんな時のazure cliだとおもったが、ほぼ対応してないのでWeb UI必須
感想
とりあえず、ゴリゴリのPaaSっぽくない所が良くて、これくらいゆるければ、その内仕事でも使うんじゃないかなーと思っております。
この感想が好感的な感想なのかわからないかもしれませんが、私は好感度高いということです。
(なんか、バックアップとかもあるんですよね…どんだけレンサバっぽいの)
あと、Preview版ではありますがタダのMysqlがあるのもいいですね(疲れたので、後日また書きます)、コンソールも面白いといえば面白くて、notepadとかたたくとどうやら本当に裏でnotepadがうごいてるらしくて面白いです(つかれたので、後日また書きます)、一瞬触ったAdvanced Tools
が実は使える感じなのでは?とおもいましたが、これも後で書きます(疲れたので)App Service Editor(Preview)
がブラウザで動くエディタっぽくて、これもつかえそう(軽微な事ならFTPつかわなくても済む?)とおもった(ry(疲れた(ry
今日のところはこちらからは以上です、面白そうなので、また書きます。
追記
mysqlの件書きました。
写真
無料コンテナ最高
クオーターについて
仮想ディレクトリについて
github連携について
ISUCONでベンチをするたびに、Slackに集計を張り付ける件
みなさんのISUCONの参戦エントリを楽しく読みつつ、心にはダメージを負っているuzullaです、こんにちは。もう一週間くらい後に読もうかな。
さて、一昨日のISUCONでは繰り返しnginxのクエリやDBのクエリ解析結果をみていました。そこらへんを毎回手で叩くと大変だし、ファイルのシェアも面倒なので、解析したらそのままSlackにはりつけていました。その作業は半分くらい自動化されており、そのメモです。
使ったツール(一部)
- alp
- pt-query-digest
- slackcat
alpについては皆さんご存じかもですが、LTSV形式のログをよしなに集計してくれるツールです。このツールで強いのは、/keyword/hoge
と/keyword/ugo
といった最近のバラけるURLを正規表現でまとめる事ができる事ですね。主にアクセス回数やアクセス平均時間などを確認するためにつかいました。
pt-query-digestはもはや説明不要というか、ググったほうがよいでしょうが、MysqlのSlow query logを集計してくれる君です。これは回数や、合計でかかった時間を特に重視していました。(ところでmysqldumpslowがここ最近バグってて集計がおかしいんですが直って欲しいですね)
slackcatは、指定したチャンネルにファイルをULしてくれる君です。とても便利。こういうツールは結構あるけどslackcatはシンプルでよかった。
これらを組み合わせることで、「計測開始」「ベンチ回す」「集計」「Slackにポスト」ができます。
なお、slackcatはデプロイ通知とかにも使えますので、その用途にもおすすめです。
どうやるか
素直にシェルスクリプトでいいんじゃないですかね。
#!/bin/bash set -ex # ログのリセット :> /tmp/access.log :> /tmp/mysql-slow.log # slow query logの有効化 # my.cnfに書くと外すのを忘れるので、動的にONにしている echo "set global slow_query_log_file = '/tmp/mysql-slow.log';set global long_query_time=0;set global slow_query_log = ON;" | mysql -u isucon -pisucon # アプリの再起動 # slow_query_logを変更したらDB再接続が必要なので sudo systemctl restart isuda.perl sudo systemctl restart isutar.perl
ここでベンチをまわし、じっと待つ
終わったら以下を実行
#!/bin/bash set -ex # slow query をオフに echo "set global slow_query_log = OFF;" | mysql -u isucon -pisucon # アプリを再起動 sudo systemctl restart isuda.perl sudo systemctl restart isutar.perl # クエリ集計 export PT_DIGEST_FILENAME=/tmp/ptd-`date +%H%M%S`.txt # ここでteeしてるのは、一応うごいたか目でみてたかったので pt-query-digest --limit=100 --filter '$event->{bytes} <= 100000' /tmp/mysql-slow.log | tee $PT_DIGEST_FILENAME cat $PT_DIGEST_FILENAME | /usr/local/bin/slackcat --channel 80percent --filename pt-digest.txt # アクセスログ集計 export ALP_FILENAME=/tmp/alp-`date +%H%M%S`.txt cat /tmp/access.log | /usr/local/bin/alp --aggregates="/keyword/.*","/stars.*","/\?.*" > $ALP_FILENAME cat $ALP_FILENAME | /usr/local/bin/slackcat --channel 80percent --filename alp-result.txt # 必要に応じて、他の集計もやったりする
後で集計をみかえしたくなるかもしれないので、一応毎回ファイル名は日時を振った。
まあこのように非常に原始的な手法なのだけれど、原始的がゆえにその場で修正しやすく、たとえばalpのaggregatesをへらしたパターンもつくったりできる。(今回だと、keywordのかたよりをみるために、一部のマッチを削ったりした)
pt-query-digestのフィルタはなかなか色々な機能があって、バカでかいクエリは(初期化とかでよくある)捨てるとか、マッチしたものだけをひっぱる、とかもできるのがよい(というかやらないとつらい)。limitは指定しないと集計除外されるクエリがでてくるので、全部出すように指定している。
(ところで、現実世界でmysqlコマンドの引数でパスワード指定とか正気ではないが、まあISUCONだからね!!!)
なお、UbuntuはAppArmorがあるので、デフォだとMysqlのスロークエリログを/tmp/に出力できない。別にここに出力される意味はないのだが、/tmpを使いたいならDisableしましょう。なお、Apparmorをaptで消すとmysqlごと消えるらしい、まじか。
# うろおぼえだが、こうやります。 $ sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ $ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld # 適当にググると大抵古い情報か嘘がみつかりますので、まあ公式ドキュメントをみましょう。 # https://help.ubuntu.com/lts/serverguide/apparmor.html # aa-statusで本当にオフになってるか確認をわすれないように
今後の改善点
消し忘れ怖いので、nginxのログも再起動したらオフになる仕組みがほしいとおもった。環境変数つかえばできるかな(すくなくともApacheではできるのだが、nginxだとあんまりしらべてない、次回までにはやるかな)
Slackにポストされたでっかいテキストファイルは割と見づらい。なにせ集計結果は横幅がでかくなりがち。とはいえ外部のPasteBinに貼れば解決するかってそんな感じでもない(結局、ブラウザを開くので)。
「あるベンチ結果の集計結果をタブでみれるPastebin」みたいなのがあればいいかな〜っておもったけど、割と良い感じではない。
過去のベンチとの比較とかも考えられるけど、それは実際使わんやろ…と思って作らず。
昨今のISUCONではベンチマーカーがウェブで、スコアもブラウザにでるので終了検知が面倒(今回は手作業だった)。ローカルベンチだとなにもかんがえなくていいのだが。
alpの出力そのままだと、keywordの後につづく日本語の文字がパーセントエンコーディングになってて見づらい。ここはもう一段フィルタをいれて人がよめるようにすべき。(終わった今なら、それが重要だったと気付く)
SlackにはりつけるとどんどんSlackが荒れるので、Chをわけるか、GHのISSUEに専用のスレをたてるべきか、とおもっている。まあ…趣味かな。
プレインテキストは目が滑るので、出力された集計結果の注目すべき所の文字を赤くしたいなとおもった。
まとめ
まあ石器時代みたいな手法ですが、普段やっていること以外をやると事故るので…。
こういったタレは当日につくるのは無駄なので、是非とも事前の練習の時につくるべきですね。
しかしまぁ、私が言っても説得力ないよな!すまん!!!