Infrastructure カテゴリのアーカイブ

ISUCON8 予選に参加して再起動試験に落ちました

Infrastructure Programming

おはようございます。名取さなにハマっている kyontan です。

最終スコア

チーム「hhkb」で同期3人 (自分 @kyontan, @hogashi, @h-otter) 2回目の参加で2日目で Go 実装でした。学生枠突破ならずでした、悔しい。というよりは 55,982点で全体4位の点数で落ちました。ちなみに hhkb は h-otter, hogashi, kyontan, :boom: ???? の略です。
スキルセット的には、 @h-otter がインフラ(ミドルウェア含)なんでもできる+Goの経験が一番あるマンで、 @hogashi がアプリケーションなんでもできるマンで、 @kyontan はアプリとインフラとDBを一通り見られるマンみたいな感じでした。

今回は真面目に本戦に行きたかったので前々日に ConoHa で ISUCON7 の予選を解き直して練習しました。具体的には ConoHa の練習用イメージを使って 1GBプラン x3台で予選環境を再現しました。結果、10時間程度で 5,204点から509,190点まで持っていけることが分かり、計測と試行の反復を効率的に行えば ISUCON の予選は突破できるという確信を深めていました。
また、前回は最後の最後でベンチマーカを走行させた結果点数が下がって落ちたので、前回の直後に「泣きの1回はやらない」というスローガンを掲げ、1年越しでそれを達成しました。

ベンチマークの初回走行の結果しばらく1位になった

事前に準備したのは Prometheus のサーバ (@h-otter がいい感じにやってくれた)と、やること/できることチェックリストぐらいでしょうか。だいたい大会では開始した瞬間にテンパってそのまま撃沈するのが常なので、思考停止状態でもコピペで動くようなコード片とかを用意しておくと便利ですね。あとは思考が無になったときに確認するべき事項とかを作っておくと良いのではないでしょうか? 頻繁に無になって帰りたくなりました。メンタルは大事。

例えば下のような感じです。

当日は3人がローカルで開発し、本番環境のVMへバイナリを転送して検証する、という進め方でやっていました。Go はクロスプラットフォームでのビルドがしやすいのが便利ですね。

具体的にやったことを羅列します。というか @h-otter が書いていたのを未承諾引用します。順番は適当

  • SELECT * する系のクエリを必要な列しか取らないようにした
  • /api/usersuser_idreservations を全部とってきて、アプリ側で処理してやったらめっちゃ速くなった
    • ここでベンチマーカが重いと言ってくるエンドポイントが /users/:id から /api/events/:id/actions/reserve になった
  • getEventgetEventWithoutDetail と分けた
  • getEventgetEvents を2クエリに
  • sheets へのクエリを消す
    • 効果があったのかは良くわからない
  • MariaDB のチューニング
  • Prometheus と Grafana で可視化
  • ログインのクエリを1つに
  • パスワードを平文で突っ込むようにした
  • DB にインデックス張った (けどあまり良い結果がでなくてもんにょりした)
    • 最初に mysql コマンドでインデックス張ったけど結果が全く変わらなくて、なぜ? と思ったら毎回 /initialize でテーブルを作り直していることに気がついた。
  • IN句を使いたかったので DBにアクセスするライブラリを sqlx に切り替えた
  • トランザクションの開始がおかしいところがあったので直したり デッドロック時にエラーを返さずリトライするようにした

最後は予約時のシート決定を高速化するコードが安定化しなくて入らなかったり、Redisでいい感じにやろうぜみたいなことを思うだけ思ってやらなかったりしました。多分ここができると数万点上がったはず。

あとはスコアに関係ないけど作業便利になる系として、 エラーログでソースコードの行番号を吐くようにしたり、 Makefile 弄って1コマンドでデプロイできるようにしました。
開発は3台のサーバでバラバラにやっていましたがDBは1台だけを参照するようにしました。これはDBのチューニングとかがあって、1台でやった変更を他に反映したりするのが面倒くさかったので。こうすると、やりたい人間が適当にベンチマーク対象のサーバを変更して実行してやればいいので楽でした。

ソースコードは GitHub で管理し、いい感じにやりました。コミットログは下の通りです。

数字がタグに付いていることがありますが、これはいいスコアが出た時にバイナリごとコミットしてタグつけておこうぜ、みたいな感じにした結果でした。

今回の僕の活躍はよく分からなくて、いい感じデバッグ担当だった気がします。PRを見るなりとりあえずマージしてベンチマーカを落としたりバグ探しをしていたりしました。とにかく @h-otter がぶち壊しつつ @hogashi がいい感じに安定化するコードを書いてくれてよかった感がある。

Webサーバはh2oで十分高速だし、画像のトラフィック詰まりもないしで、とにかくアプリケーションコードの改善に注力した/するしかなかった8時間でした。

最終的に残り30分でベンチマーカを叩いたところ3万点前後のスコアが5万点に若干跳ねてそこで打ち止め。一度再起動をしてブラウザからアクセスできることを確認し天命を待ったところ、無事再起動試験で落ち失格となりました。天命……

(追記: スコアが跳ねたのは、最後に実行先サーバを変えた時に インデックスを張る処理を init.sh に書いたサーバで実行したからかもしれないことを思い出した。)

なぜ失格になったのかは分かっていなくて、おそらく /admin/api/reports/events/:id/sales の処理が遅くて不整合が起きて落ちたのかなあなどと思っていますが、2回連続で落ちるのは運が悪かったなと……

なんやかんやでやることがなくならない8時間で、やることが見つからない8時間よりは良かったのではないかと思います。

イキっているなどと言われてもこれは事実だと信じていて、典型的な N+1 を潰すなどすれば予選は通過できるはずなことは分かりましたね。くぅ〜〜

来年はちゃんと本選に行けたらいいですね。頑張りましょう。

そして、参加会場を提供していただいた mixi 様、惜敗の悔しさを教えてくれる最高のコンテストを運営をしていただいたISUCONの運営の皆様、お疲れ様でした、ありがとうございました!

以下は画像です

CoreOS で Docker Swarm クラスタを作ってみた

Infrastructure

こんばんは。kyontanです。JobHunting 活動は順調ではないので頭を抱えています。

寒いです。12月10日です。10日ということは、 whywaita Advent Calendar 2017 の10日目ということです。なんとあと1枠らしいです。

9日目は @kadokusei (~= @hyr3k) さんで 体重 – /var/log/ でした。

ところで文脈もなにもないですが Just Because! が良いです。小宮恵那さん……

read more »

ISUCON7 予選に参加しました

Infrastructure Programming

チーム「まだチーム名で消耗してるの?」で同期3人 (自分 @kyontan, @hogas, @h-otter) 初参加で2日目でした。学生枠突破ならずでした。

Ruby実装で挑み、最終スコア 38605点@2017-10-22 20:59:30, ベストスコア: 67792点@2017-10-22 20:44:59 でした。
ベストスコアでは予選ラインは超えていたんだなあと思いますが、最終的には伸び悩んだチームも多いようで、結局落ち着くところに落ち着いたのかなと思います。

ソースコードは kyontan/isucon7_qual です。踏み台でやっていた影響でコミッタが僕に見えますが、だいたい僕ではない。

ISUCON7 予選での Score / LoadLevel の変化

次回も参加したいなという気持ちになってきたので、ひとまずはやったことを記していきます。

read more »

Zabbix で収集したデータを Datadog へ投げる

Infrastructure Programming

こんにちは。これを書いているのは JST 4:30 ですが、最近は JST+0900で生きているので、昼間です。そろそろ夕方でしょうか。
最近の仕事の成果は Zabbix に投げ込む XML をエイヤで自動生成するような何か、もしくは SQL を生成する何かです。

成果物は kyontan/datadog-zabbix-history です。

長い前置き

ところで皆様は Datadog を使われていますでしょうか?
インフラ監視系の SaaS やソフトウェアというと、今挙げた Datadog を始め, Mackerel や Zabbix, Nagios, AWS Cloudwatch 等々、現状では様々なプロダクトが存在しています。最近だと Datadog や Prometheus の名前をよく見かける気がします。

そんな中最近、自分のバイト先では使われているのが Datadog です。サーバの監視なんかだと、 Integration の種類も多く、デフォルトで様々なメトリックが取れることや、ダッシュボードの見やすさなどがイケているかなと。
特に SaaS だと、バッファリングがあるにしてもメトリクスの抜け落ちや一時アクセスできなくなる問題などはあり、クリティカルなものを全部載せるわけにもいかず、ただ SaaS の恩恵は受けたいというのが正直なところでしょう。
(mackerel-agent のログを眺めているとたまに何故か 404 が返ってきていて笑います)

ただ、設定が複雑化したり、そもそも設定数が多くて移行がダルいというのが正直なところです。エイヤでやる体力があれば良いですが、ホスト数が増え、監視項目が万の単位であるとそれはそれは……

おそらく皆さんは Zabbix のアイテムやらなんやらを XML で書き出してごにょごにょしたり、それを Prometheus の設定にいい感じに変換する何かを書いたりされているかと存じます。そしてそんなコードは短いから/特定のドメインに特化しているからと公開せず、誰もが誰かは書いているだろうと思いながら書いていることでしょう。そうですよね?

今回ご紹介するのはそんなあるあるプロダクトです。やることは記事のタイトルに書いてありますね。

read more »

CloudStack の VM を cs コマンドでデプロイしようとしてハマった

Infrastructure

こんばんは。タイトルだけ書いた下書きが溜まっているので書いていきますということです。

ICTSC6 で CloudStack を使用していた話はまだ書いていなし多分書かないですが、使用していました。

その中で、API を叩いてくれる薄っぺらいラッパーコマンドであるところの exoscale/cs を叩いてデプロイなりVMの起動停止なりボリュームのアタッチなどをやっていたわけですが、デプロイ関連で少しハマったので解決策を紹介。

ちなみにこれ: https://github.com/exoscale/cs。 exoscale 、 CloudStack なんですかね……

CloudStack の API はあまりにも愚直なのでパラメータが無限に多くてしんどいという話はさておき

APIの一覧は http://cloudstack.apache.org/api/apidocs-4.9/ にあります。 (4.9 の場合)
VM を作成する場合は、 deployVirtualMachine

書いてある通りですが、必須なパラメータは以下の3つです。

  • serviceofferingid
  • templateid
  • zoneid

それとは別に、IPアドレスを固定したり複数のネットワークにVMを接続するときは iptonetworklist パラメータを指定するわけですが、このパラメータの設定がなんもわからんという感じです。

難しすぎる。なんで突然配列の演算子が出てきて & で繋ぐ必要があるんだ……

実際に直に API を叩いたことはないのですが、 cs ではこの通りにパラメータを書いても上手く動いてくれません。
なので、以下のようにする必要があります

ただ & で繋げずにスペースで区切るだけです。どういう挙動なんだろう……
どこにも仕様が載っていないので試行錯誤せざるを得ないわけですが、やっていきましょう

結局 cs コマンドの引数はこんな感じになってしまうので非常に読みづらい。各位 Ansible のパワーに頼っていきましょう。僕は Ruby でラッパーを書きました。