読者です 読者をやめる 読者になる 読者になる

ISUCON6 3万点台で予選敗退

会社の同僚と一緒に「尿酸値E」としてISUCON6出ました。
Ruby実装を選んで、最終的に「32660」というスコアで予選敗退。今年こそは本戦出るぞと意気込んでいたのでとても悔しい。

事前準備

前回出場時に、序盤の解析系作業で手こずったため
今回はかなり念入りに解析ツールの準備を行っていました。

事前に立てていた作戦

  • 午前
    • アプリケーションをサーバー上で動かしてベンチマーク流す
    • 同様にローカルで動かす
    • コマンド一発でデプロイできるスクリプトを置く
    • kataribe, pt-query-digest, stack-profなどで各種解析データを揃える
    • 解析データを元に作戦を立てて、各自作業していく
  • 午後
    • まずはベタにまずいクエリをつぶす (index効いてない, n+1)
    • 同様にミドルウェアもチューニングする (普段の業務で使っているnginx, unicorn, MySQL, sysctl.confを用意)
    • ↑やりきってからキャッシュ戦略考えよう

今回は午後の作戦を事前に話してしまったことで、キャッシュ戦略への切り替えが遅くなったのが敗因ぽい。
htmlifyボトルネックだということに午前の段階で気づけていたものの、ロジック改善を頑張ってしまい
結果スコアが伸びずキャッシュに切り替える時間をロスした。

当日タイムライン

9:30

無事に集合。前回に引き続き、会社のオフィスで作業させてもらうことに。
普段なれてる環境で作業するのが1番でした。

10:00

Azureにデプロイ。
最初なぜかインスタンス起動でエラーが出て、30分ほどリソースグループごと作り直したりしてた。

  • とりあえず1度ベンチマークを流す
  • 「isudaってなんだ? 増田か!!」
  • 「メモリ7GB近くあって結構いろいろのせられそうだね」
  • nginx.conf見て「isudaとisutarがマイクロサービスっぽくなってる」
  • githubにコードを上げておく
  • dumpを取る
  • ローカルで動かす

最初のインスタンス起動トラブルで焦ったものの、アプリケーションが動き出してからは比較的スムーズにいった。
この時点では作戦通り、まだアプリケーションを読み始めていない。

11:00

事前に準備をしていた解析ツールを入れて導入検証を進める

この辺の作業は

ISUCON予選突破を支えたオペレーション技術 - ゆううきブログ

ゆううきさんのブログを参考に用意していた。
特にデプロイスクリプトミドルウェアごと再起動するあたりは、忘れがちなので用意しておいてよかったと思う。

作戦会議の結果、特に事前に話していた作戦とは差分なく

みたいな配分で作業していくことになった。
ここまでは予定通り。

12:00 - 15:00

各自の改善を入れて少しずつスコアが上がる。しかしこの時間帯はスコアが1万にものらない。 以下のようなことを試した。

  • nginx -> unicornunixドメインソケット化
  • staticなファイルをnginxで返す
  • unicornのworkerを増やす 5 -> 10程度
  • istarをisudaに統合
  • MySQLにインデックス追加
  • keyword_pattern, htmlifyのロジック改善
  • ispamは解析始めると時間がかかりそうなのでいったん放置

ロジック改善以外はそこそこ効果があった。 正規表現部分だけどうしようもなくて、徐々にキャッシュの方に話がいきはじめる。

15:00 - 18:00

15:00すぎから、少し作業を止めて話し合い、キャッシュ導入を検討しはじめる。

最初は htmlifyまるごとredisにキャッシュ。たしかこれでスコアが1万を超えた。

そこからまた少しスコアが伸び悩み、再度ロジック改善に走る。
その間に htmlifyの処理を細分化し、さらに細かくキャッシュしていく。これでスコアが2万を超える。

また17:00の時点で一度インスタンスごと再起動してベンチマークが走りきるか確認。

キャッシュを進めていくと今度はまたstaticなファイルを返すのに詰まりはじめたり
ファイルディスクリプタを使い切ったりしたのでカーネルチューニング。

最終的に終了直前に keyword_patternの結果をredisにキャッシュしたあたりで3万オーバーのスコアが出て終了。

終了後

近所のすしざんまいに行って反省会

個人的には

  • キャッシュ戦略の引き出しが足りなかった
  • 正規表現周辺のロジック改善にこだわりすぎた
  • /initializeの5秒を使えず

あたりに後悔が残ってます。

今年けっこう気合い入ってただけに悔しい。本戦出場の壁高い。

しかしISUCON楽しい。出題チームの方々もおつかれさまでした。

表参道.rb #14 でLTしてきた

Ruby

シャドウプロキシのkageを使って安心してFuelPHP -> Railsに移行した話をしました。

表参道.rb #14 ビアガーデン風編 - connpass http://omotesandorb.connpass.com/event/36622/

今回の会場はSansanさんのオフィスでした。
13Fにオフィスがあって、LT中におそらく神宮球場のであろう花火が見えたりしてよかったです。

今年は仕事で使った技術について色々話せるといいなと思います。 よろしくお願いします。

nginx実践入門を読んだ

nginx

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

発売を知って即予約した cubicdaiya さんの本。
タイトルの通り、実践のための内容でした。

特に良いと思ったのが

の4つの章で

3・4章では、普段webサービスを運営する上で使っている基本的な設定項目について丁寧に解説されていて
自分の中で歯抜けになっている知識の整理ができたり

基本的な設定やモジュールに関する解説中心ではあるものの、非常に丁寧で
たとえばngx_http_limit_req_moduleについてはleaky bucketアルゴリズムの図を交えて解説があり
モジュールに対する僕の理解が間違えていたことに気付くきっかけになりました。
感謝。

6・7章ではより実践的な内容を扱っていて

6章では自分も経験のあるphp-fpmやunicornなどの
アプリケーションサーバと連携して稼働するリバースプロキシの細かい解説

7章ではより大規模なトラフィックを扱う場合のキャッシュ戦略や負荷分散についてnginxででき得る対処が解説されていました。

特に7章ではwebアプリケーションサーバにおけるボトルネックとなりそうなハードウェアリソースとその対策の指針が解説されており
nginx実践入門というよりは、webサービス運用実践入門みたいな内容になっています。

普段本を読むのが遅く、読書自体に苦手意識が生まれてしまっているのですが
この本は全体構成としてwebアプリケーションを運用していく上で必ず遭遇するような問題と
それに対処するための方法として、nginxの設定やモジュール、構成が解説されているため
今までの自分の経験と照らしあわせながら読むことができ、ストレスなく読み終えることができました。

デスクに置いてリファレンスとしても活用できる非常にありがたい本です。おすすめ。

#CookpadTechConf 2016に行ってきた

メモ

クックパッドさん主催のCookpadTechConfに行ってきました。

techconf.cookpad.com

いくつか自分のチームで試したいことがあったのでメモ

技術力を事業の強みするために必要なこと

  • とにかくシンプルにする
  • 営業力でなんとかしない、技術で価値をつくる
  • 「とにかくがんばるぞ」という局面において技術は全く役に立たない
    • どの数字にフォーカスするか定義する必要がある
  • 議論や調整じゃなくて決定とテスト

開発した新技術から、新しい価値を作るためのクックパッド検索チームのプロダクト開発手法

  • 技術、解決策のことはいったん忘れる
    • 技術から発想してプロダクトをつくると失敗しがち
  • ユーザーの悩みや、欲求にフォーカス
    • 「あったらいいね」みたいなものは作らない。「ないと死ぬ」みたいな機能をつくる
  • 欲求から解決策を考え、そこに技術を使う
  • 技術→製品→価値ではなくて、価値→製品→技術の順で考える
  • 週に1~2h程度の時間を取って、技術を抜きにした価値に関する議論をする

「今日なに作ろう?」を支えるデザイン

  • 機能ではなくストーリーで考える
  • ユーザーのどんな問題を解決できるのか
  • プロトタイプで仮説検証
    • イデアの共有
    • エンジニア工数を取らない
  • こういうの作りたい→OK!→最高かよ!
  • デザインもIssue上で議論

確かめながらつくるユーザー体験

いったんサービスの作り方にフォーカスしてメモ。
Rails高速化の話や、DWHの話がくそおもしろかったので
次回あればもっと技術寄りの話も聞いてみたい。

2015年お買い物ランキング

日常

2015年に買ってよかったもの12個書きます

takanamito.hateblo.jp

12位 星野源のアルバム YELLOW DANCER

いま売れ売れの星野源
アルバムとライブDVDの抱き合わせよかった。

Instrumentalの曲とかちゃんと入ってて渋い。
SAKEROCKでまた曲出して欲しい。
ライブの映像あるとニセ明さんの「君は薔薇より美しい」聞けるのでうれしい。

11位 ハイキュー 18/19巻

ハイキュー!! 18 (ジャンプコミックス)

ハイキュー!! 18 (ジャンプコミックス)

ハイキュー!! 19 (ジャンプコミックス)

ハイキュー!! 19 (ジャンプコミックス)

ツッキーが覚醒してる。めっちゃいい。
ウシワカのスパイクをドシャットするとこめっちゃいい。

10位 Wii U + スプラトゥーン

中学の時の初代バトルフロント以来のハマりっぷり。
会社でもやっててめっちゃ楽しい。ボイチャとかないから楽しい。

9位 ビーダマンの電子書籍

発行部数が少ない15巻とか全く見つからなかったので今賀俊先生本当にありがとうございます。
後半で好きなのはフラッシュワイバーンの登場回。タマゴがガンマの背中押すところと、ビー玉半分に割るところが好き。
当時コロコロで読んでてくそテンション上がった。
takanamito.hateblo.jp

8位 イミテーションゲーム

エンジニアはテンション上がるシーンが多い。 劇場でガッツポーズ出そうになった。

7位 仮面ライダークウガ

仮面ライダークウガ(1) (ヒーローズコミックス)

仮面ライダークウガ(1) (ヒーローズコミックス)

なかなか変身せん。超変身せん。アギト出てくる。めっちゃいい。

6位 aiko プラマイ

プラマイ(初回限定仕様)

プラマイ(初回限定仕様)

カップリングの「合図」がいい。
いろいろあったっぽい感じが裏に見え隠れしててめっちゃよかった。
ライブでも「明日もいつも通りに」「なんて一日」歌ってたらしいのでめっちゃ行きたかった。

4位 キングスマン 爆音上映

キングスマン(字幕版)

キングスマン(字幕版)

これ見て高いスーツ買った。
スーツ以外のカジュアルな衣装もかっこいいの多くてすごくいい。
ベタだけど教会の乱闘シーンかっこいい。

4位 キツネとリーボックのコラボスニーカー

クラシック ナイロン アフィリエイト Reebok CLASSIC(リーボック クラシック) [V69742]|Reebok ONLINE SHOP -リーボック オンラインショップ f:id:takanamito:20151231020533j:plain

初めて朝から原宿で並んでスニーカー買っただけあってすごい気に入ってる。
歩きやすいし品もあって好き。

3位 ベッドとマットレス

ヘッドボードに収納満載 引出し付きフレーム(ベガC) | ニトリ公式通販 家具・インテリア通販のニトリネット

すごいQoLが向上した。腰痛かったけど固めのマットレス選んだことで緩和。
セミダブルのベッドにして正解。

2位 スターウォーズ 4DX

見たいやつだいたい見られた。
ミレニアム・ファルコンの登場シーンとか、黒いX-WINGとか最高。

1位 LoopWheelerのスウェット

LW01吊り編み丸胴クルースウェット2015FW f:id:takanamito:20151231015007j:plain

会社の同僚から聞いてまず最初に定番のパーカーを買って
あまりの着心地の良さに感動してスウェットも買ってみたけどこっちも超よかった。
オートミール色なのでやわらかい印象になるし、着心地もパーカーと変わらずふわっとしていて最高。
吊り編み機についていろいろ調べていくうちにがっつりファンになってしまっていた。

お金使うの気持ちいいですね。
来年もたくさん散財したい。

一人暮らしを始めて5年間悩んだ末に見つけた排水口の詰まり対策ソリューション

日常 ライフハック

ついに来た!!!

台所、お風呂場、洗面台と
掃除が嫌いな僕は、長期間掃除をサボって
排水口が詰まってしまうことが多かった。

最近になってお風呂の排水口は
髪の毛キャッチのネットを使い始めて改善。
↓こんなやつ


ただ、台所はどうしても油を使ったあとのフライパンとか
鍋の出汁を捨てたりするときに油が詰まって、どうしようもなくなることが多かった。

そして一度詰まると手が付けられなくてすんごい大変。
パイプユニッシュとか、タブレットタイプのやつとか市販の洗剤けっこう試したけどダメなことが多かった。

んで、こないだたまたま時間あったので
排水口の詰まり対策をネットで調べてたら、だいたいこの商品を使ってる記事にたどりついた。

ピーピースルーF 600g 業務用排水管洗浄剤

ピーピースルーF 600g 業務用排水管洗浄剤

とりあえず一般市民が手に入れることのできる洗剤の中では最強らしい。
その割に値段もべらぼうに高いわけではない。でもさすがに市販のものに比べるとちょっと高い。

というわけで、最近台所が詰まり出してたので
土曜にamazonで買ったら、通常配送なのに日曜に届いたので早速使ってみた。

ボトルの1/4ほどの粉末を台所の排水口付近に撒く。
そこに40~50度のお湯を注ぐ。

すげーしゅわしゅわしてきて、同時に刺激臭。やばい。
この辺、写真撮りたかったけど、流しがリアルに汚いので自重。

1時間ほど待ってから、水流しまくって
薬剤を全部流す。







きれいに詰まりがなくなりました!!!!!!!!!!!

最強ゆえに、取り扱いには少し注意が必要で
マスクと手袋、メガネは必須な感じ。

体感値でも、防具ないとヤバい感じはしてて
肌に直接つくと間違いなくえらいことになるし
マスクしてても鼻にツンとくる感じした。あれはメガネなしで薬剤目に入ったりしたら死にそう。

しばらくはこれで排水口は安心して使えそうです。

レコメンドエンジンのcicindelaを動かしてみる

Perl メモ

cicindela
cicindela2 - a highly customizable recommendation engine written in perl + MySQL - Google Project Hosting

livedoorで作られたレコメンドエンジンのcicindelaを使ってみる。
mod_perl + apacheな環境で動かすチュートリアルがあったのでそれに従う。

なんだかんだperlに触るのが、学生時代以来で
めっちゃハマりまくったのでメモ残します。

環境

もくじ

  • perlのインストール
  • cpanmのインストール
  • apacheのインストール
  • mod_perlのビルド
  • cicindelaの環境構築

perlのインストール

最初はシステムPerl(5.10系) + yumcpanモジュール入れて構築してたけど
極力新しいバージョン使いたかったのでperlbrewでもうちょい新しいやつを入れます。

$ curl -L http://xrl.us/perlbrewinstall | bash

// perlbrewにパスを通す
$ vi ~/.bashrc 
source ~/perl5/perlbrew/etc/bashrc // 追記

// インストール可能なバージョンを表示
$ perlbrew available

// インストール
$ perlbrew -v install perl-5.18.4 -D ccflags=-fPIC // mod_perlのビルドのためにccflagsオプション必須

// バージョン切り替え
$ perlbrew list // インストール済みのバージョンを確認
$ perlbrew switch perl-5.18.4

// perlbrewで入れたPerlにパスを通す
export PATH=ホームディレクトリ/perl5/perlbrew/perls/perl-xxx/bin:$PATH

$ perl -v // バージョンが5.18.4ならOK

cpanmのインストール

perlbrewでcpanmもインストールできる

$ perlbrew install-cpanm

apacheのインストール

apacheは普通にyum

# yum install httpd httpd-devel

mod_perlのビルド

最初この手順すっ飛ばしてたので
apacheがぜんぜんperlbrewで入れたバージョンのperl読みにいってくれなくて悩んだ。

$ wget http://ftp.jaist.ac.jp/pub/apache/perl/mod_perl-2.0.8.tar.gz
$ tar -zxvf mod_perl-2.0.8.tar.gz
$ cd mod_perl-2.0.8
$ perl Makefile.PL USE_APXS=1 WITH_APXS=/usr/sbin/apxs EVERYTHING=1
$ make
$ make test
# make install

オプションで指定しているapxsについて何も知識がなかったので下記記事を参考にさせてもらいました。
apxsとは | For Want Of A Better Word
apxsコマンドでApacheにモジュールを追加 : ブログというか、メモ?(引っ越しました)

cicindelaの環境構築

// mysqlのインストール
# yum install mysql-community-devel mysql-community-server --enablerepo=mysql56-community
# service mysqld start

// 依存モジュールのインストール
$ cpanm --sudo DBI DBD::mysql Ima::DBI Time::Piece Log::Log4perl Module::Pluggable Class::Singleton

// cicindelaのチェックアウト
$ cd /home
# svn checkout http://cicindela2.googlecode.com/svn/trunk/ cicindela

// my.cnfとhttpd.confの修正
$ ln -s /home/cicindela/etc/mysql/my.cnf /usr/local/mysql/my.cnf
# vi /etc/httpd/conf/httpd.conf
Include /home/cicindela/etc/httpd/modperl.conf // 追記

// ハードコードされたperlのパスの変更
$ cd cicindela/misc
# perl substitute_project_paths.pl --perl_path=ホームディレクトリ/perl5/perlbrew/perls/perl-5.18.4/bin/perl

// デモデータのチェックアウト
# svn switch http://cicindela2.googlecode.com/svn/branches/demo_data/misc misc

// データベースの作成
$ cd /home/cicindela/misc
$ perl create_init_sql.pl --db_name=cicindela | /usr/local/mysql/bin/mysql -uroot

// ロードスクリプトに必要なモジュールのインストール
$ cpanm Text::CSV_XS

// ロードスクリプトに必要なファイルの生成
$  cd clip_data
# touch pages.txt clips.txt tags.txt
# chmod 766 *.txt

ここでチュートリアルではimporter.plを動かすんですが
僕の環境ではエラー吐いたので修正

if ($tags) {
     # utf8フラグをoff
    $tags = Encode::_utf8_off($tags);

    for my $tag (split(/\s+/, Encode::decode('utf8', $tags))) {
        my $tag_id = ($tag_hash->{$tag} or $tag_hash->{$tag} = ++$last_tag_id);
        print TAGS_OUT join("\t", $tag_id, $user_id, $page_id, $timestamp)."\n";
    }
}

つづき

// ロードスクリプトを実行
$ gzip -cd ldclip_demo_dataset.csv.gz | perl importer.pl --work_dir=`pwd` | mysql -uroot cicindela

// 設定の変更 DB名とユーザー名とパスワードを変更
# vi lib/Cicindela/Config/_common.pm

// レコメンド集計バッチ実行
# bin/batch.pl --track=1 // 2回実行。このパスで実行しないとエラーを吐く

動作確認

# service httpd start

ブラウザから
http://サーバーのIP/cicindela/recommend?op=for_item&set=clip_simple&item_id=39102
にアクセスするとレコメンド結果のitem_idが一覧で表示される。

おつかれさまでした。