chigichan24のお気持ち表明

イケてるエンジニアになりたい.

ものさしの話

この記事はProlab Advent Calendar 2017の8日目の記事として書かれています.

adventar.org

こんばんは.

KashiwagiHinoki君からバトンを受け取りました.

久留米高専プロラボ部OB 兼

沖縄高専ICT委員会OG 兼

高専エンジニア勉強会OB(自称)のchigichan24です.

老害です.プロラボが好きなのでノリと勢いで参加登録しました.

書いてみて思ったのですが完全に老害です.やばい.

続きを読む

ISUCON7-finalに参加しました

こんばんは.chigichan24です.

この前の土曜日,ISUCON7の本選に参加してきました.

チームはもちろん予選のときと変わらず,k5342euglena1215 です.

予選のエントリは,

chigichan24.hatenablog.com

chigichan24.hatenablog.com

前日

チームの人と5,6限の授業おなじだったので授業後にちょっとだけ話しました.まあぶっちゃけ,予選から何もしてなかった(別のことで忙しかったという言い訳)のでやばいねという話や.とりあえずredisでオンメモリ(笑)みたいなのはやめようとか,レギュレーションきちんと読もう(予選で帯域制限のことを考えられなかった)とかそこら辺を話しました.

土曜日の集合は朝早く,どう考えても起床でfailしそうだったので,ホテル( @tanishi345 宅)に泊まりました.

当日

インターンシップ以来のミライナタワー.一ヶ月新宿生活してたので,駅で迷うこともなく流れるようにオフィスへ行けました(天才)

去年同様,スーパーかっこいいカードが配られました.スーパーかっこいい.

問題

(設定が)社長だったか,取締役だったか誰だったか忘れたけどまあ8時間後にリリースするから(笑)適当に高速化してくれ,みたいなおもしろ動画が流れた後詳細の説明がありました.

クッキークリッカーを複数人でやるみたいなゲームの高速化でした.その複数人でできるルームは複数個作られるといった感じでした.

コードもなにも読んでいないときの印象はwebsocket周りの高速化ゲーなのかなぁと思ったりしてました.

サーバーは4台構成でした.

やったこと

なにもできなかった...... 

というと,あれなんですが取り敢えずDBの設定見たりnginxの設定を見ても明らかに問題のある箇所が少ない.というか,DBとか複数カラムでPrimaryKeyになってて他のカラムはほぼinsert時にしか使わないみたいな感じになってるお陰でindexも貼れないし,nginxも一応静的コンテンツをキャッシュしたりしたけど,なにも変わらなくてなるほど,これはアプリケーションの改変ゲーか!?!?みたいになりました.インフラの仕事ほぼゼロやんけ....

インフラの仕事が無くなると k5342 パワーが使えないので悲しい事になりました.それでも途中までは彼にいい感じにチューニングしてもらって,スコアが7000前後に安定するようにしてもらいました.

一方私はいろいろ眺めていたら,m_itemsなるtableがDBに置いとく必要もなさそうだったので,全部オンメモリ上に吐けそうと気がついたので,euglena に投げました.

なんやかんやしていたら(まじで記憶がない),m_itemsの移植に失敗してつらそうだったので,取り敢えず放置して,一番重そうな calc_statusを倒そうと話し出しました.

こいつは total_milli_isutotal_powerという2つの値を計算しているのですが,差分で計算できそうなのにいちいちはじめの状態から再計算していて頭が悪そうだったので差分で計算できるようにしようと話しました. 0.5[sec]ごとに処理が走るくせに,こんな激重っぽいやつが動いていたら出るスコアも出ねぇよ(名推理)みたいな気持ちでした.これをeuglenaに投げました.

一方私は,1000[ms]先の状態をシミュレートして未来の状態のタイムスタンプを生やしてjsonをぶん投げるという部分が,1msごとにイベントが起きるか判定して,このjsonを作っていたのですが,これは明らかに頭が悪くて,イベントごとに処理できるように書き換えるのをやりました.

まあ,ところがこいつらを改変しようとするといろんなところの依存がすごすぎて回収不可能(死亡)みたいになりました.

最後の30分くらいでk5がサクッとdiff_baseで一部を移植していたので,早いとこ彼に投げればよかったとなりました.

最後は例のごとく再起動テストをしてみたり,変な落ち方をしないか確認したりしてました.

で,最後の数分はスコアガチャをしてました.スコアが全然上がらなくて4000点くらいを叩き出していて,これは初期実装投げるほうがスコアが高いやんけという悲しい気持ちになりながら,ガチャガチャしてましたがタイムアップ,maxは9800くらいだったのに,最終スコア4000位でフィニッシュしました.

完全にお通夜状態でした.終了直後のみんなのツイート

解説 & 懇親会

作問の方からの講評を聞きました.「最初のステップとしてルームをポートで分けて処理を分散するこれは皆さんやりましたよね?」とか言っていて完全にお気持ちになりました.なにそれ...このステップを越えると私達が戦っていたcalc_stateをどうにかする話になり,さらに進むとBigIntとの戦いになったらしい.やべぇ何もできてない.

懇親会は,あんまり他のチームと喋れなかったのですが,インターンシップで一緒だった人を発見して適当にお話したり,優勝チームが何やったか聞いたり,作問の方が他の人と喋っているのを聞いてはぇええとなったり,W社の方と少しお話したりしました.

そうこうしていると,全チームのスコアが出ました.下から自分のチームの名前を探しているとなかなか見つからないので,あれっってなっていたら,19位にいました.普通に惨敗なんですが,ビリだと思っていたのでなんか嬉しかったです.救われた気分でした.

f:id:chigichan24:20171127220518p:plain

全体だと19位,学生だと8位みたいです.

予選だと全体29位,学生11位だったので若干上がっている..

反省

反省点は大量にあります.実装担当だったはずなのに何もできなかったのがただただ悔しいです.プログラミングやってますと公言できるように精進します.しばらくはプログラミングやったことありませんって言うか....

感謝

何はともあれ,まずチームを組んでくれた k5342 君と euglena1215 君ありがとう!!!二人のやっていることをタダぼーっと椅子に座ってたらいつの間にか本選まで行けてました.

そして,作問をしてくださったKLabさん,サーバー提供のさくらインターネットさん,会場提供のLINEさんありがとうございました.とってもとっても楽しいISUCON7でした.

流石に去年よりはまともになったので,次はもっとまともになってISUCON8に臨む(あわよくばまた二人とチームを組みたいね)

最後に

今回のおもしろPR

f:id:chigichan24:20171127221357p:plain f:id:chigichan24:20171127221400p:plain f:id:chigichan24:20171127221406p:plain f:id:chigichan24:20171127221403p:plain

ってだいたいchigichan24がふざけてるだけやんけ.....

ISUCON7の真面目な話

メンバーが真面目な記事を書いていて,自分のやったことがピザをデプロイしただけと思われると悲しい(?)ので,多少技術的なムーブメントというか真面目な補足を書こうかなというエントリです.

昨年は チーム (´・ω・`) としてISUCON6本選に出場していたので,その時の様々な反省を今回のISUCONでは(部分的には)活かせたかなと思います.

去年参加した経験を活かして,今回は自分はoperationの中心となり,問題の性質に応じてコミットする領域をわけながら取り組むことに注力しました.

インフラ,ネットワークの知識,設定に関する知識に k5 は長けており,また,euglena はRubyのコーディングスキルに秀でているため,彼らの力を最大化できることを目標に動きました.

唯一,彼らより私が秀でているのは競技としてプログラミングすることだと思います.プロダクションのコードではこういうことをしないとか,benchmarkerをjudgeのような振る舞いで使うことで普段はできないようなデバッグ方法をするように話をしたのですが,これはすぐには身につかなかったかなぁと思ったりしています.

やったこと

オペレーションな面

議論で大きく衝突することはないのですが,基本的に割れたときは最後に決断をバサッと下すことを心掛けました.短時間の競技は無駄に悩むくらいならやってみるというのが大事です.

また,コードのバグを無駄にとろうと必死になるくらいなら,競技の規模程度のコードに限っては絶対に書き直したほうが速いです.

技術的な話を含めた時系列

my.cnf,nginx.cnf,redis.confの導入をしました.昨年の経験や,練習会を通してwikiとしてためておいた汎用的な設定ファイルを導入しました.sysctlに関してだけはlinuxに関する知識がうすすぎたので,k5に投げました.

ktaribeでアクセスログを解析し,明らかにicons/によってログが埋まっていたため,すぐに静的配信することにしました.また,3台構成であったので,

1. まずiconsのGETをnginxで捌く.
2. 画像の管理をDBでするのをやめて,パスだけ保存する.
3. サーバの1つをコンテンツ配信用とする.

という方針をk5と話してたてました.

一方,アプリケーション改修担当のeuglenaはslow queryを見た結果そこまで遅いクエリがないという報告をうけたので,早急にindexを張るのを考える必要はないと判断して,line-profの導入をしてもらいました.

と言われつつ,userのnameでindex貼ったりしましたが,あんまり効果がなかったように思います.

このタイミングくらいで,euglenaからline-procの結果を渡されて,sleepが無意味に挟まっていたので直したり(sleepの意味に気がついていなかった),line-procをみても画像に対してWHERE掛けてるところが重いのが確定したので,早急に静的配信することにしました.

euglenaと話していると,redisに載せたい部分があるという相談を受け,少々悩みましたが,悩むくらいならやってみて早ければ導入するという感じでGOサインを出しました.

静的配信をnginxで設定したもののなぜか200で返っていたので,少々調整をしたら,10000点にのり,icons/ 以外の静的コンテンツも載せると 15000点に乗りました.

しかし,cacheのサイズを変えたりするとワーカーの数(並列度)は上がっても,2000点まで下がったりと不安定な挙動をしていて,私とk5で同居人との競合みたいな考察をしましたが,これは多分間違っていて,実際は帯域制限を食らっていたという k5 の考察を今日見て,納得しました.

何はともあれ,このときはそれに気が付かなかったので,設定ファイルを一から書き直しつつ最適化するというのをk5にしてもらっていました.

その間は,アプリケーションの一部をredis化していたので,私はそれ以外のN+1を直すため,また,アプリケーションのロジックをもう一度確認するためにコーディング側に回りました.

この間にrebootしてみると,Pythonが起動したりして,危ないところでした.

この間にも,k5 によって並列度を保ったままスコアを徐々に上げてもらい,euglenaにはredis化のコーディング & バグ取りをしてもらいました.

このあたりで,私達のチームはまだ,課題の本丸にたどり着けていないという焦りを感じながらコードを眺めてました.

一箇所,slowqueryに出なかったからといってい,WEHRE句で多用されているカラムなのに,indexを貼っていないところがあり,試しに貼ったらスコアが39000程でてびっくりしました.これはこの変更だけで30000点が上がったのではなく,今までの設定がやっと効き始めたという感じがありました.

再度kataribeを見ると,loginやregisterが少々重いので,nameとpasswordにindex貼って高速化したかったのですが,saltを発行しつつSHA1に掛ける実装をしていたので,難しかったです.今思えば,その実装も外して無理やりpassを平文で保存しても良かったかもしれません.

このあたりで,k5にDBから画像を切り離す実装をしてもらい,スコアが40000に乗りました.

その間私は SELECT *をなくし,必要最小限のカラムを取るように変更して,少々スコアを上げました.

そうこうしているうちに,euglenaの実装がほとんど終了しそうだったので,隣にいってバグ取りしました.力にならなくても相手に説明させることで,バグが取れるという経験は私は多くしていたので,行きました.

やっと手元ではredis化ができたようなので,benchmarkerを投げてみたら500が返ってきたので,終了30分前ほどだったのもあったので諦めました.

最後はきちんと指差し確認をしてログを切りました.再起動テストをすると, pumaに権限がなくて起動できないなどあったので,そこらへんを直して,最後はガチャをして,40088のスコアで終了しました,

まとめ

椅子に座ってイスコーンってしてたら,メンバーに本戦に連れて行ってもらえそうなので,良かったです.