インスタンス立ち上げAMI-IDをゲットしてインスタンスの立ち上げ。全員にそれぞれ検証環境を用意する事を前日話していたのでインスタンス台数は4で一気に立ち上げ。一つを本番用、他3つをメンバー用。無事perlで立ち上がってベンチ実行してスタートダッシュ成功。一瞬でも1位がとれて、「優勝したあ!isucon優勝!」とあほみたいに騒ぐ。(ベンチ+スコア送信用)という名のシェルスクリプトを作る。スコア報告ベンチが走るのでちょっと楽。これにより、「べんべんいく?」「とりあえずべんしよう」とかはたから見たら異様な会話に。git(bitbucket)を使うgitはbitbucketのプライベートリポジトリを使った。このあたりの設定をmemememomoがやってくれた。vimmemememomoが秘伝のvim設定を投入。ログ解析アクセスのパターンを確認できればいいかと簡易のアクセス解析ツールを使った。前日にぐぐって見つけたvisitorsというもの。6え、urlこんだけ!?nginxの設定nginxの設定が必要最低限だったので修正。ついでに静的ファイルはnginxから返すようにやっておいた。8[mysqld_safe]log-error=/var/log/mysqld.logpid-file=/var/run/mysqld/mysqld.pidネットワークやサーバー制限まわりの設定このあたりでつまずくのは時間が勿体ないので、あらかじめ上限をあげておきました。(ですので、ローカルポート枯渇などではひっかかってないです)iptablesをOFFipconntracとか出て時間をくいたくないので念のため。設定この設定はvarnishの公式に「varnish使うならこんな設定まじおすすめ」みたいに紹介されてたもの。56384ファイルディスクリプタでも時間をくいたくないのでlimits.confを設定。65535ここまでやってみてスコアは2500とあまりかわらず。ASC);これと上記のインフラ周りの修正でスコアは20000くらいになった。$count;};となるでも/reportsの修正は怖かったのでlogin_logへのINSERTはそのまま。こんな修正をmemememomoがばばーとやってくれた。のびなくてあるぇえええ?ってなる。files」的なエラーが出るというので見てみると/tmp内にあるセッションファイルがものごっつい量になっていた。これ以上ファイルが書き込めないという状態になっていて1ディレクトリの上限ファイル数でも叩いてたのかな。(あんまり調べてない)こんだけファイルができるくらいだからセッション書き込みにおけるディスクIOも問題となっているに違いない事に気づいてmemememomoにセッションをメモリで管理するように変更してもらった。Plack::Session::Store::CacheCache::FastMmapCHIredis使うよりもこっちの修正のほうが効いてたぶんここらへんで32000いや、まぁここがボトルネックで解消した結果redis修正が生きた、という可能性もありますが。平文のパスワードこのときベンチではもうほとんどがアプリの負荷だったのでどこかアプリで重いとこないかを探した。プロファイルしようかともmemememomoが悩んでたんですがcalculate_password_hashって明らかに重いだろ、、、という事でここをなんとかする事に。元のinitialのsqlデータやtsvデータには元passwordが平文で書かれてたのでこれを入れちゃえばcalculate_password_hash使わなくてよくなる。usersテーブルをコピーしてusers_pwを作成。ここのpassword_hashに平文のパスワードを入れて、平文のパスワードで認証するようにした。これでなんか重そうな雰囲気のcalculate_password_hashを呼ばなくてよくなった。終わりベンチ中topをなにげなく眺めてると、memememomoの秘伝のvimがCPU20~30%も消費してる事を発見。最高スコアを送信してend無駄だったこと1/のエラー文言部分だけを別URLにしてindex.txからSSIで読むようにした。これにより/をnginxでキャッシュできたんだけど、速くなるわけなかった。ssi処理のぶん遅くなっただけで意味がなくて元に戻した。なんでこれで早くなると思ったのか思い返したら謎。無駄だったこと2ログイン失敗数等を別テーブルで持たせてSQLの負荷軽減をした。Redisでカウントする事にしたのでこの修正も無駄になった。やりたかったこと1すべてのデータをredisに入れてmysqlと決別したかった。過去の経験から普段やったことない作業をやると泥沼化が見えてるのでやらない事にした。反省会の焼肉屋でTOPページのindexをエラー文言別に静的に用意しておいてnginxがCookieで振り分けると早くなりそうという案が出た。他の人のブログでもそんな改修があって、これについては気づきが足りなかったなぁと悔しい思いに。実際この作業をやっても43000点くらいまでしか伸びなかったのですが、これをやってたら本戦にもしかしたら出れたかもと思うとうぎゃーとなりました。企画/運営/協賛されておりますLINE/cookpad/DATAHOTEL/Amazonの皆様にはほんとうに感謝しております。ありがとうございます!本戦出場者が決定しました!http://isucon.net/archives/40576269.html京都スイーツはギリギリだめでした。思って読み進めると、失格してました。ログインユーザ名が表示されていないため、表示崩れとみなし、失格といたしました。書き換える時に必要なカラムが漏れてた模様。どちらにしてもスコア足りてなかったので結果は同じですが失格は悲しい。一応チェックされるほどの上位にいけたということで許して下さい、、、と会社に言い訳。ここまでチェックするって運営さんはすごく大変だったろうな、、、と改めて感謝の気持ちでいっぱいです。今年も楽しい問題、ありがとうございました。インフラHPのサーバーをCentOSで使いたい事が出てきてインストールにいろいろ試行錯誤したので備忘録です。Arrayを使ってRAID1を構築し、管理したいという内容となります。B120iコントローラが標準でついているので、これを使ってRAIDを組みます。起動時にF9を押してRBSUなるメニューを開きます。RAIDサポートを有効]の順に選択。Arrayコントローラが認識されず、HDDが2個と認識されてしまいます。Arrayのドライバが存在しない事が原因なのでOSインストール時にドライバを読み込ませる必要があります。ページから入手します。B120iのものはこちらから入手できました。ディスケットドライバをダウンロードします。ドライバをダウンロードしたら解凍します。dd.imgというファイルが出来たのでそちらをUSBメモリにコピーします。CentOSインストール時にディスケットドライバの読み込みさきほどのディスケットドライバを保存したUSBをサーバーに刺し、CentOSのインストールCDからブートを行います。CentOSのインストールメニューが出たら、「ESC」キーを押してインストール起動パラメータを入力します。blacklist=ahciとしてエンターを押します。※上記のような起動パラメータでインストールしないと、カーネルがAHCIのモジュールを自動で読み込みPanicを起こします。ドライバの読み込みするか?といった質問が出るのでyesを選択し、[sda]か何かを開きます。USBの中身がメニューが出ますので保存していたディスケットドライバを選択します。※ここのメニューでHDDがいっぱい認識されていればインストール起動パラメータが間違っているかもです。あとは普通にインストールを行えばOKです。変なとこにインストールしないように任意のタイミングでUSBは抜くといいとおもいます。HPのユーティリティインストールCentOSが起動してからの作業です。ページから入手します。パッケージを入手します。rhel6u4でx86_64のものを選択します。B120i)では以下のページにて入手できました。これらのファイルをインストールしたCentOSサーバーに転送します。RHELとして認識させる為に以下の変更を行います。/etc/redhat-releaseまた、ユーティリティソフトはsnmpを必要とする為、snmpパッケージをインストールしておき、簡単な設定を行っておきます。/etc/snmp/snmpd.confユーティリティのインストールダウンロードしたユーティリティのディレクトリに移動し、以下のようにインストールします。\hponcfg-4.2.0-0.x86_64.rpmsnmpの設定を設定し、hp-snmp-agentsを起動します。restart確認作業まずはCLIが動作しているか確認します。OK)=&gt;ちゃんとOKのステータスが確認できました。続いてWEBUIを確認します。(WEBUI)のリモート接続を許可します。こちらはCentOSの起動時に自動実行させるようにしておいてもよいかもしれません。homepageが開きます。IP]:2381/うまくインストールできていればログイン画面が出ます。Linuxのrootユーザーでログインします。ログインが成功し、さらにcpqacuxeのインストールが成功していれば、ストレージメニューに「アレイコンフィギュレーションユーティリティ」のメニューがあるので、そちらをクリックします。(RAIDコントローラ)の設定が可能なWEBIUが開きます。hpacucliが使えない時WEBUIのSmartArrayを起動するとこんな感じのエラーが出てhpacucliは使用できなくなります。console.=>webUIを使用の際は起動は同じくこちらのコマンドで。wheezyが2013/05/04にリリースされました。カーネルも一気にバージョンがあがって、いろいろなパッケージも新しめのバージョンが入って・・・と、モダンな雰囲気を感じれていい感じです。バージョンが変わったのでsqueezeと同じつもりで使ってるといくつか問題が起きたのでその備忘録です。全体的には思ったよりも問題は発生せず、いままで通り使えています。パッケージがいくつかなくなってる普段使用しているパッケージでは以下の二つがなくなってました。libssl0.9.8libreadline5-devlibssl1.0.0とlibreadline-gplv2-devに変更しました。v1をデフォルトで拒否するようになってた上記に関連して。libsslバージョンアップの影響か、特定のhttpsサイトにcurlやwgetで接続行くときにエラーが出るようになりました。versioncurlに「-1」のオプションをつけると接続できるようになりました。このオプションはtlsv1の暗号化でも接続を開始する、というオプションなようです。https://xxxxx.xxx/xxxwgetコマンドではどうやればtlsv1を許容できるようになるのかわかりませんでしたautoconfのバージョンエラーautoconfのバージョンが上がってる事が原因か、いくつかの古めのソフトウェアのconfigureでautoconf関係のエラーが発生しました。今回の例ではqmailadminをインストールしようとconfigureしたところ、以下のエラーとなりました。インフラMySQL5.6にしていくつかのSQLでエラーが出るようになっちゃいました。valueエラー文からデフォルトバリューが設定されてないカラムにNULLを入れようとした為のエラーのようです。ぐぐるとずばりな回答をされてるブログが見つかりました。iをgに変えるとorangeになることに気づいたoranieの日記MySQL5.6で今までのVerでは問題無かったSQL文がエラーになった場合の対処法http://d.hatena.ne.jp/oranie/20130402/1364906656日々の覚書MySQL5.6が勝手にsql_modeを書き換えてくれる話http://yoku0825.blogspot.jp/2013/03/mysql56sqlmode.html対処法sql_modeの設定がMySQL5.5と5.6で異なる事が原因です。sec)上記だと再起動すると設定が戻ってしまうのでmy.cnfの設定を変更する必要があるのですが注意が必要なのは、mysql5.6から「scripts/mysql_install_db」を実行した場合にMySQLのbasedirにmy.cnfを自動的に作成してくる事です。このmy.cnfには以下のようなsql_modeが設定されていますので値を空に変更します。sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES↓sql_mode=''/etc/my.cnfなど、他のmy.cnfを普段使用している場合、こちら設定してもbasedirのmy.cnfが設定を上書きしてくる為、必ず確認が必要です。STRICT_TRANS_TABLESsql_modeは公式には以下のようにかかれています。チェックを実行するべきかを定義するものmysql5.6で設定されているsql_modeのSTRICT_TRANS_TABLESは通称「ストリクトモード」と呼ばれているもので、無効なデータなどの挿入、更新時にエラーを発生させるモードです。まとめmysql5.6からbasedirに作られるmy.cnfでsql_modeをストリクトモードとして動かすSTRICT_TRANS_TABLESが設定されている。今後、新規につくるサービスなどであればデフォルト通り有効にする事が望ましいと思いますが、すでに運用しているMySQL5.5のサービスを5.6にアップグレードする場合などは上記のようにSTRICT_TRANS_TABLESをはずせばOKです。インフラqmailのキューを削除する方法。原因はスパム、ループ、メール送信テスト、とかでキューがあほほどたまってしまう事があります。実は単にすべてのキューを削除したい場合は以下のコマンドでOKです。/var/qmail/queue/*/*/*大量にキューがある時あるサーバーにキューが120万件たまっていました。キュー全削除の為に上記コマンドを実行しようとしたらこのエラーです。longこういう時はxargsというコマンドを行うとよい。rmただ、上記でも多すぎるとエラーになる時があって以下のシェルスクリプトを作ってみました。こんだけ細かくしてやれば削除できるだろうと・・・。(120万件はうまくいきました)queue_del.shhttps://gist.github.com/4653448すごい力技。forくらい使わないとって感じだけど検証も面倒なのでこれでOK。インフラ最近話題のRedisをさわってみました。KVSとかNoSQLって呼ばれるRedisですが似たようなアプリケーションにMemcachedがあります。Memcachedとの大きな違いとして1)リスト型、集合型とかいろんなデータ構造が扱える2)データの永続化ができる3)レプリケーションができるがあるのではないかと思います。速さは当然Memcachedが最高なんですが、それなりに高速で、しかも結構複雑なことができるようです。インストールインストールはここから。installするかどうかはお好みで。testでこんなエラーが。testこの場合は言われたとおり、以下のパッケージを入れると解決した。tcl8.5起動redis-serverこれでサーバが起動します。デフォルトではポート6379。なんか弁当箱みたいなんが出て、以下のような記述が出ればOK。6379起動させたまま、別のターミナルでredis-cliを実行redis-cliこれでredisを操作できます。地味にクライアント用プログラムがあるのはうれしいですね。こんな感じでコマンドを渡すこともできるようです。pingPONG値を入れたりとってきたり。展開したソースのredis.confが元になるのでこれをコピーしておきます。適当に/etc/に置くことにしました。/etc/redis.confさまざまな設定項目がありますが、とりあえず現在は以下の項目を変更しました。デーモンとして起動する。デバック中とか遊んでる途中ならnoでもいいと思います。yesメモリのダンプファイルを保存する場所。永続化はこのファイルが書き出されることで実現してます。(適当に)使用するメモリサイズ。(適当に)設定したconfを読み込んで起動。このように設定ファイルを指定しないとデフォルト設定で立ち上がるので注意。/etc/redis.confいったん立ち上げたredis-serverを再起動すると設定が反映されます。redis-cliを使ってみます当然こちらを見るよりこ公式ドキュメントが非常に充実していますよ。http://redis.io/commands文字列型これはさっきやりましたが。2リストリストの作成も出来ます。文字列型の順不同の集合だそうで値の重複はできないという性質を持っているようです。"Hello"こんな使い方もできるみたいです。セット型のdiffをとる。逆にするとenptyになっちゃうので渡すセット型の順番は重要です。引数のセットが第二引数のセットと重複した場合消えて、残った文字列型が出力されます。以下の記述で5秒後消えるキーとして設定できる。hoge(nil)DB切り替えデフォルトでDBが0~15という名前で用意されていて切り替えて使用できる。接続したときは必ず0を使うようになっているようです。hoge"hogehoge"永続化のテストredisの目玉?機能にデータの永続化があります。これは定期的にデータをファイルに書き出すことで実現しているようです。redis.confの以下の記述がその設定内容だと思います。1000015分間の間に1回更新があったらファイル書き出し5分間の間に10回更新があったらファイル書き出し1分間の間に10000回更新があったらファイル書き出しって意味になるのかと。redis-serverを起動してたら標準出力にこんなログがでました。successこのタイミングでredis.confで指定した場所に指定したファイル名でダンプファイルを作成してくれてました。この記述を見てから安心してサーバーを停止。その後起動するとちゃんとデータは保存されてました。(saveされてない常態で落とすと当然データは消えます)このとき起動時には「読み込みました」的な以下のログがでてました。機能としては「レプリケーション」や「アトミック実行」、「仮想メモリ」などまだまだためしていないことがたくさんありますが、基本的な部分はさわれたかな、と思います。なんだかとても見通しがよく感じて楽しく遊べました。PHPやnode.js、ruby、perlなどなど、いろんなクライアントから使用でき、そのサンプルもよくみかけるので、ますます触りがいがありそうです。前から問題として認識はあったのですが、社内にもMACユーザーが半数近くになっていて問題が大きくなってきましたので対応。問題点のおさらいLinuxで作ったsambaサーバーへMACをクライアントとして接続した時。・パーミッションが700とか600とかになるという問題。chownしてました。0777といった設定を入れているのにMacからのみどうやら無視されている様子。ちなみにWindowsではこんな事はありませんでした。解決策ぐぐると同様の原因で困っている人がたくさんいました。no続いて再起動を行うと問題は解決しました。UNIX拡張を利用するかどうかを制御する。シンボリックリンクやハードリンクなどを利用可能にする。シンボリックリンクやハードリンクといった機能を提供することが可能となる。yesつまりクライアントがUNIX系のクライアントの場合は拡張機能が使えるようになる、というオプションみたいです。maskとかが無視される様子です。(Windowsの場合はこの項目は無視されていたのだと思います。)特にシンボリックリンクなどの使用は考えてませんし、現状maskが無視される方が問題なのでnoに設定しました。インフラDebianはすべてフリーのライセンスでできたもので構成されている。そのため、非フリーのドライバを使用するNICを使用しているサーバーの場合は以下のようなエラーがでてNICを認識してくれない。あなたのハードウェアの一部では、操作するのに非フリーのファームウェアファイルが必要です。ファームウェアは、USBメモリやフロッピーなどのリムーバブルメディアからロードできます。rtl_nic/rtl19168e-2.fwそのようなメディアを今利用できるのであれば、それを入れて続けて下さい。説明にある通り、USBメモリを用意した上で作業します。みつからないファームウェアファイル名でぐぐります。今回だとrtl19168e-2.fwですが検索するとDebianのnon-freeパッケージにて配布されているようです。http://packages.debian.org/squeeze-backports/firmware-realtekまずはこちらからdebファイルをダウンロードします。適当なDebian系のLinux上で以下のコマンドを実行する事でdebファイルが展開されます。hogehoge[/code]上記を実行するとカレントにhogehogeというディレクトリを作成してdebパッケージが展開されます。こちらの中にインストールで必要な「rtl19168e-2.fw」があるのでそちらをUSBメモリにコピーします。今回は以下のパスに目的のファイルがありました。[code]./hogehoge/lib/firmware/rtl_nic/rtl19168e-2.fw[/code]USBメモリにコピーする際はDebianが指定するファームウェアのパスと一緒にする必要があります。今回の例ですと「rtl_nic/rtl19168e-2.fw」が見つからないとなっている為、USBメモリ上にrtl_nicという名前のディレクトリを作成し、そこへ「rtl19168e-2.fw」を持ってきます。あとは完成したUSBメモリを刺してインストールを続行すればOKです。インストール後インストール完了後は念のため、パッケージ自体をインストールしておけばいいかもしれません。non-freeパッケージをリポジトリに追加します。update[/code]以下のようなエラーが発生しました。updateしろって書いてるけどもちろん鍵認証のエラーなので解決しない。T310・ShuttleのPC(XPCとか)の機種で何回か遭遇しましたが、ほとんどが「realtek」か「broadcom」ですね。どちらもDebianにはnon-freeとしてドライバが配布されています。インフラnode.jsのインストールnode.jsのインストールはただ公式からソースを取ってきてインストールするだけですが、バージョンアップのサイクルがとても早い為、バージョン管理用のソフトも入れなければ管理的なコストが高くなってしまいます。今回はnodebewを使ってnode.jsを管理、インストールしてみたいと思います。nodebrew?nodebrewはnodeのバージョン管理や環境を管理してくれます。同一の事が行えるソフトはnvmやらいろいろありますが、nodebrewは以下の点がお気に入りです。・シンプルでわかりやすい・perlで書かれてるので環境に依存しにくい・管理者権限がいらない・バージョンを簡単に切り替えられるこちらで公開されています。https://github.com/hokaccha/nodebrew事前作業opensslとかpythonのパッケージが必要なのであらかじめ入れておく。あとcurlパッケージもあると便利なので入っていなければ入れておく。nodebrewのインストールnode.jsを使用したいユーザーでログインして以下のコマンドでインストールできます。setup[/code]これでインストールは完了。ホームディレクトリに「.nodebrew」というディレクトリができています。続いてインストールしたnodebrewにパスを通します。~/.bashrc[/code]これでログインする度にnodebrewへのパスがとおるはずです。nodebrewを使ってnode.jsのインストールインストールは簡単で以下のようなコマンドで完了。latest[/code]上記のコマンドだと最新のnode.jsがインストールされます。続いてインストールされているnode.jsを一覧します。バイナリが用意されてる場合バイナリインストールしてくれます。listv0.9.6[/code]インストールしたバージョンのnode.jsを使用します。useって実行しないといけないので.bashrcは以下のように書き換えるといいかもしれません。v0.9という形で止めるとv0.9の最新のものを使用してくれるみたいで便利です。サンプルでチャットプログラムを動かすnode-chat-demoというものが@ITで公開されていたので入れてみます。update[/code]npmってのはnodeのパッケージ管理ツールらしくインストールしたらついてきます。updateで今回のアプリに依存のあるパッケージをインストールしてくれます。npmはそのまま実行すると実行したカレントにnode_moduleというディレクトリができてパッケージが展開されるので、パスには注意して下さい。3000[/code]なにやら3000番のポートで待ち受けますよ的なメッセージが出ます。あとはブラウザからこのサーバーのポート3000へ接続したらチャットのデモが動いてるはずです。helpでどんなオプションが用意されているか確認できます。ls-remoteでインストールできるnode.jsのバージョンを一覧できます。