大森s ISUCON5 初参加6位でした

毎年TLから見学していたISUCON、今年は社内メンバーの勧誘に成功したので初参加しました。
メンバーは みね, @yukiex, @shun0922 の3名で参加してきました。チーム名は会社の所在地ということで 大森s に。

本戦も予選も役割分担はだいたい以下のような感じで、お互いの領域を少しずつカバーしながら作業しました。

  • みね ・・・ App
  • @yukiex ・・・ インフラ
  • @shun0922 ・・・ DB, KVS

当日の朝

今は横浜ですが、東京在住の頃から渋谷は怖くてあまり近づかなかったので迷うかと思って早めに出発。
9時頃には11Fに到着し、先に到着していたのは2組程度でした。
個室ゲットできるといいなと思っていたら、メンバーが乗車している電車で人身事故が発生したと連絡。
到着が遅れチーム全員揃わないと入れないバリアに阻まれ立ち往生。それでも10時前には入場できました。

普段 MBA 11' に外部モニタという構成なので、モニタのかわりに MBA 13' を追加で用意したり、メンバーのために燃料(カフェオレ)を用意したりと、バッグがいい感じの重量(20kg程度)になってました。

開始直後

配布された封筒からホストとIPがわかった時点で開発機などに hosts ファイルを配置しメンバーに共有。
開始と同時にキューを入れ、それが記念すべきISUCON5Fの初キューだったらしくスコア1064で1位!

レポジトリにソースを取り込み App をのぞきはじめたメンバーからAirbnbを3行で説明しろと言われたので、

一般人が
一般人を
泊めるサービス

と説明。「えっ?ホームステイ的な!?」となっていたので「空き部屋に」を補足。

こちらではまず OS が Ubuntu 14.04.3 なことを確認。
Chef のレシピが適切なものを準備出来ていないため iTerm2 の Broadcast Input と、pssh を駆使して3サーバの環境を同時に修正。
hosts, shell, key 修正 (isucon, root ユーザ)、dstat, htop, zsh などを入れる。
ミドルウェア周りはDBサーバが psql (PostgreSQL) 9.4.5 で nginx が 1.4 なことを確認。この辺で15分経過。

メンバー2名はここ数ヶ月 PostgreSQL と過ごしてきたので小さくガッツポーズする。
App 担当は PostgreSQL の経験がほとんどなく、さらに開発環境が Mac じゃない上に VM 環境もないということで手元に開発環境が構築できないため、VPN越しに社内に環境を作る。しかし直接API接続できないということで諦めて c サーバに居を移す。

vim の設定やら ag もいれつつ、スーパーバイザーを探して perl に変更、自動起動などを変更する。
そして nginx に worker 数、静的コンテンツ配信と UNIX domain socket の設定、supervisor 側に Gazelle の設定など、同時に変更するもなぜか nginx の configtest で fail する。
なんとか設定変更を最小限にとどめ、とりあえず nginx start する。

午後

となりでDB担当が pgBadger を使って slow query をまとめてくれたので眺めてみるも、あまり最適化の余地がない。この辺で12時15分頃。

App 側で JSON モジュールを JSON::XS に変更。
アクセスログalp で集計して眺めながら 外部API 呼び出しをなんとかしないと、他にはあまり余地が無いという話になる。
気休め程度に endpoints をコードにインプリメントする。スコア2781。

13時30分頃、Redis でキャッシュする方針で、サーバインストールと設定、Perl設定、App実装とそれぞれが実施。
ついでに前回調査時に Furl より Net::Curl のほうがベンチ結果が良かったということで Net::Curl も cpanfile に仕込む。
Redis の実装が完成する前に API とのやり取りを確認したかったということもあり Varnish をプロクシとしていれるように作業。エンドポイントをバックエンドにマッピングしてひとまず動作する。

13時45分頃、DBにインデックス create index users_email on users (email, passhash) を追加し少しスコアあがる。
Net::Curl で Last-Modified 対応と、Accept-Encoding 模索するが、Redis 待ちで一旦放置する。
14時30分頃、Redisの実装が完了、5000〜6000程度までスコアが上がる。

後半残り3時間

そして運命の15時15分から数分前、再度 nginx の設定を変更していてやっぱりおかしい。作ったはずのソケットがない。
あ、俺 supervisorctl reload するの忘れてるやん!!と自分の凡ミスにいまさら気づく
15時15分頃、やっとワーカーが増え Gazelle と UNIX domain socket の導入ができたのでベンチする。スコア 30807 。ワーカー数を倍にして 61552 、更に調整して 65295 に落ち着く
その間、App 側は着々とキャッシュの実装を追加し Expire の個別対応、token_key の設定などを実施。

15時45分頃、そろそろ複数サーバで負荷分散できるようにしたいということで、2台で調整を開始。
/initialize の初期化対象DBホストがローカルだったのを見落としていて少しハマる。
redis の bind など変更してテスト、Varnishも外す。
DB担当は pgpool-II を入れるかどうかでやきもきしていたようです。

2台の構成

isu08a DB, App  
isu08b LB, Redis, App  

isu08b (nginx) -> (App)  
               -> (nginx) -> (App)  

上記のように nginx to nginx の若干、変則的な設定を実施。
16時30分ごろ、スコアは 69880 となり3位になったので reboot テストなどを実施する。

残り1時間

17時10分頃、userjs のレンダリングをやめて直接生成に変更。スコアを 83776 まで上げ3位を維持。

たまに fail するので Tenki API のキャッシュ保持をいつまでするかを調整開始
また reboot 直後に fail することがあり、PostgreSQL で App が DB 接続した後に DB が落ちると接続がロストすることを思い出す。念のため env.sh に sleep を仕込む。

17時30分頃、サーバを3台体制に変更しベンチを実施。スコア 90120 とチームとしては今大会の最高スコアを記録。

17時40分頃、fail 対策で Tenki APIのレスポンス日時からキャッシュ時間を調整するように変更。
全サーバ reboot テスト。スコア 84983 にダウン。

17時50分頃、更にTenki APIのキャッシュタイムを5分から60秒に変更。

結果

17時56分の段階で best score で5位、上位陣の fail などでなんとか入賞に望みをかけましたが結果6位でした。
後になってみると、ツメが甘い上に対応も甘く反省しかない結果でした。
なにより上位陣がしっかり着手していた、並列リクエストができていなかった点は痛かった。
データのシリアライズに関しても MessagePack やもっと効率のいい方法を使うべきだったし。
gzip_static などもヘッダをしっかり読み、基本に忠実であればできたはずでした。
非常に悔いが残りましたが、自分たち(主に自分の)未熟さがそのままスコアに反映された結果なため満足です。

来年までにクソ精進する。

最後に、941 さん、tagomoris さん、kamipo さんをはじめ運営・出題チーム、スポンサーの皆様、本当にありがとうございました。
非常に楽しかったです。

Score History

timestamp score note
11:01:58 1064
11:50:04 1029
12:01:42 0 FAIL:
12:27:59 0 FAIL:
12:35:06 0 FAIL:
12:55:24 968
13:10:44 1012
13:12:53 0 FAIL:
13:16:39 1023
13:34:03 985
13:37:21 0 FAIL:
13:40:42 1094
13:51:48 2781
13:52:37 84 FAIL:
13:56:43 84 FAIL:
13:59:35 1026
14:09:01 2023
14:09:37 84 FAIL:
14:12:26 1899
14:14:59 2658
14:27:46 5268
14:29:13 6298
14:30:44 5759
14:32:21 1173
14:34:25 971
14:41:46 1176
14:44:34 1097
14:51:12 1051
14:52:53 5481
14:57:12 1088
15:02:02 84 FAIL:
15:06:50 6438
15:08:29 84 FAIL:
15:10:17 1013
15:13:04 5624
15:15:12 30807
15:20:01 0 FAIL:
15:21:30 61552
15:24:52 58009
15:26:30 0 FAIL:
15:28:09 65295
15:30:35 58569
15:32:27 0 FAIL:
15:33:50 0 FAIL:
15:34:16 40 FAIL:
15:38:37 57888 FAIL:
15:40:19 71 FAIL:
15:42:53 71 FAIL:
15:45:29 55325
15:57:46 59 FAIL:
15:58:29 59 FAIL:
16:01:23 84 FAIL:
16:02:15 84 FAIL:
16:03:43 53708
16:08:34 84 FAIL:
16:11:24 84 FAIL:
16:13:41 84 FAIL:
16:17:36 84 FAIL:
16:22:53 73 FAIL:
16:24:52 69880
16:25:27 84 FAIL:
16:28:13 0 FAIL:
16:33:58 67431 FAIL:
16:36:00 84 FAIL:
16:38:10 84 FAIL:
16:40:25 63105
16:41:10 84 FAIL:
16:43:49 52687
16:45:34 10450
16:49:10 84 FAIL:
16:51:59 54244
16:54:39 57995
16:56:35 84 FAIL:
17:00:07 40 FAIL:
17:01:41 55920
17:09:08 83776
17:13:31 0 FAIL:
17:15:18 0 FAIL:
17:17:22 0 FAIL:
17:19:33 79152
17:21:39 0 FAIL:
17:24:33 78635 FAIL:
17:27:23 71501
17:29:49 90120
17:33:53 49139
17:39:38 84983
17:42:55 81641 FAIL:
17:46:59 40026
17:51:30 74185
17:56:31 84114

Yokohama.pm #12 に行ってきた!

会場:横浜三井ビルディング 30F KAYAC “ヨコハマ展望台”オフィス イベント内容

場所はこのあたりで、会場はこんな感じ。
入り口にかっこいいポータルがあったのでとりあえずハック。

f:id:yukiex:20141128203353j:plain f:id:yukiex:20141128192855j:plain

KAYAC上場おめでとうございます!

1. @kazeburo さん - Gazelleについて 資料

  • kazeburowareの新しい仲間Gazelleのお話
  • なぜ速いか?
    • クライアントとのやりとり部分がXSで書かれてて高速
    • picohttpparser 利用。高速化の手法など kazuho さんの記事が必読、必見
    • accept4(2)を使って1回のシステムコールで処理
    • writev(2)を使って1回のシステムコールで一気に書く
  • 1PVあたりの利益が小さいサービスでは速度、CPUコスト削減は必要ですよね
  • Livedoor BlogCPU使用率が1〜3%程度減ったとのこと
  • 質問
    • 設定は特に必要なくてデフォルトでOK
    • 上位のReverseProxyはApacheTCPで使っていて上述の結果
    • Redis::Jet まだ使ってない…

色んな意味でGazelleが今回のハマピーの主役な感じでした。 うちのサービスでもStarlet、Starmanを置き換えてみようかな。まずはAPIサーバあたりから。

2. @myfinder さん - Mackerel を使い始めた話と WebService::Mackerel のご案内

内容はオフレコな感じなので詳しくは省略しますが、cloud-init + Ansibleでサーバ構築し、どんどん使い捨ててそれをMackerelで監視しちゃうお話。 Mackerelでは監視データをRRDみたいに間引きしないので素敵!サポーターが強力!はてな!とのこと。 ライブOPSという新しいジャンルを開拓した感じで、いろいろな意味でドキドキ、ワクワクするプレゼンでした。 そしてGazelleでCPU使用率は本当に1〜3%下がったのでした。

WebService::Mackerelのお手伝い募集中だそうです。

新しいサービスでは、サーバデプロイメント戦略もですが、ディストリビューションCentOSからUbuntuにしたり、 監視はcloudforecastからMackerel、構成管理ツールはPuppetからAnsibleと、ドラスティックに構成を変更されたということでかっちょいいなと思いました。 自分はMackerelを本番サーバ1台だけ入れてみて、お試し期間終了放置状態ですがグラフが結構見やすそうだったので、Mackerelでどんなカスタムメトリックスを取得しているかお話聞ければよかったな。

Norikra で行動ログ分析は @fujiwara くみちょも使い始めているというお話で、こっちはまだ試してないので試してみたい。

3. @acidlemon さん せっかくなのでYokohama.pmでGoとPerlの話 資料

レアキャラの @acidlemon さんが7月にGo宣言をされたそうで、GoGo!やっていたのだけれど少し辛くなったのでガッとPerl使えるようにしてみたお話でした。 資料表紙の花火の画像は会場だったKAYACから見える花火なのかな。めちゃキレイ。

4. @karupanerura さん - 高速なParser実装が必要になったのでXSを700行くらい書いてみた感想

MySQLに溜め込んだ過去データ11億行。 古いデータは削除して運用していたが、過去データを分析したい要件が発生。 しょうがないからダンプしたSQLを直接パースして分析したいのだけど、SQL::Tokenizerだと11年かかるのでXS書いてパースしたお話。 いろいろな方のお力でXSの開発環境も充実しているようで、自分もXS書いてみたくなりました。しかし2週間で実装したというのはすごいの一言。

参考文献、利用ツールなど

5. LT

  • @uzulla さん - YAPC::Asia 2015のご案内
  • @papix さん - Perlでがんばる社内基盤
    • Keeman 公開鍵管理ツール(退社しても安心!)
    • RMS リソース管理ツール
    • TwinkPing 障害対応ツール(電話する機能付き、 Twilio 使ってるらしい。UI凝っててよかった。使ってみたい。)
  • @debug_ito さん - Perlと本気で向き合いたくない人と向き合う僕ら
  • @yusukebe さん - 横浜に住んで。横浜から離れて(仮)
  • @moznion さん - 飛び入り参加!
    • Regexp::Lexer を作ってる話(正規表現の別実装…を書いてる気分とのこと)

6. 感想

3回目の参加でした。今回も楽しかった。しかし横浜在住の参加者は少ない様子… 会場のKAYACさんのオフィスがかっこよかった。双眼鏡覗いてみればよかったなあと、あとから後悔… 今度はぜひ花火の日にお邪魔したい! 終わった後は崎陽軒で焼売食べながら、HipChatのディスして帰りました。焼売美味しかった。 皆様お疲れ様でした!

f:id:yukiex:20141128220707j:plain

OS X Yosemite で Cisco VPN の強制タイムアウトがなくなったらしい

Cisco VPN タイムアウト問題

OS X 付属の設定で Cisco IPSec VPN を選択することで簡単に Cicso の VPN が利用できる。ただ、Mac OS 10.9.x では1時間弱で強制的に切断されるというバグがあった。

こういう対策方法は以前からあったのだが、どうやら Yosemite では解消されたらしく14時間接続しっぱなしでも切断されなくなって非常に快適。

f:id:yukiex:20141021113947p:plain

MacDNS グローバル問題

こっちは Yosemite 関係ないのだけど、Windows と違って MacDNS はグローバルに定義されているものが優先されて、Network を Split していると VPN 先の DNS が引けなくて困っていた。

以前、自前で split tunneling していた際にお世話になった vpnc (vpnc 0.5.4beta (Debianバンドル版と同じパッチがあたっているバージョン) )を使って強制的に /etc/resolv.conf を更新したりしていたが、最近もっといい方法があることを知った。

/etc/resolver/ 配下に検索させたい domain を指定した resolv.conf もどきを配置するだけ。

yuki@silver:~$ cat /etc/resolver/office.example.co.jp
domain office.example.co.jp
nameserver 172.16.0.100

それでは皆様 VPN で快適なリモートワークを!