ほとラボ

It works!

ISUCON 6 予選に出て 0 点だった

f:id:hoto17296:20160918092910j:plain

今年も ISUCON 予選に出場したけど、最終スコアは 0 点だった。

写真はあまりの不甲斐なさに食べた地獄谷麻婆豆腐

3回目の出場で、練習会も開催して、当日までの準備もバッチリ整えてやった結果が 0 点というのかなりヘコむ事態。

blog.hotolab.net

事前にやったこと

  • Slack にプライベートチャンネルを作る
  • Azure に慣れる
  • NewRelic と Mackerel のアカウントを作る
  • 事前に「Node でやろう」と決めておき、プロファイルの仕方などを調べておく
  • Azure でインスタンスのクローンするの大変そうだったので1インスタンス内で全員作業することにする
    • そのため、インスタンス外にリポジトリは作らなかった

午前中まではよかった

  • 開始30分前に全員集合
  • インスタンスを立てるのは難なくクリア
  • サービスふたつあるし、isupam とかいう謎サービスも動いてるし、お題「マイクロサービス」っぽい
  • Node 実装、どうせ Express だろうと高を括っていたらまさかの koa
    • Node の初期実装がバグっていたのもあって「ここで頑張るのはやめよう」と判断し、Ruby に切り替え
  • NewRelic と Rack::Profiler 入れてベンチマークを回してみる
    • まあどう見ても htmlify がボトルネック

実装力が低かった午後

  • 毎回 htmlify するのどう考えても無駄なのでどこかにキャッシュするしかない
    • htmlify 済みの文字列を MySQL にカラム増やして突っ込めば良さそう
    • エントリが増減する度にすべてのデータを更新する

ここまでは誰でも思いつくはず

DB 初期化

エントリが増減すると初期データのレコードが更新される → 初期化処理が「id:7101 以降のデータを削除する」だけではダメ

MySQL の初期データを作って /initialize 時に5秒以内にツッコめばいい、ということになる。

  • mysqldump : 軽く5秒以上かかるので無理
  • xtrabackup : MySQL 5.7 で動かずに困惑
    • 今思えば MySQL を 5.6 に下げればよかったでは

どっちもうまくいかなかったので「MySQL のデータファイルを直接置き換える」という力技で突破

Unicorn 再起動

  • MySQL を再起動すると Ruby からのコネクションが切れる
  • コネクションが切れたときの貼り直し方がわからない
  • /initialize 時に Unicorn を再起動しよう
  • Unicorn が自分自身を再起動させるとうまくいかない
  • 初期化用の別アプリケーションを実装して、/initialize のアクセスをそっちに流す
  • 初期化用アプリケーションが MySQL と Unicorn を再起動する

なんか・・・コレジャナイ感が漂ってきた・・・

MySQL が死ぬ

再起動はできたものの、initialize 後に MySQL が死ぬ現象に戸惑っていたところで時間切れ

反省

  • 初期化処理に時間かけすぎた
    • 初期かそんなちゃんとやらなくてもベンチマーク通った気がする
  • 1インスタンス内で全員が作業するの良くない
    • 検証したくなる度に「いまブランチ切り替えていい?」って気にしなきゃいけないの無駄
    • 多少時間使ってでもインスタンスは複数立ち上げるべきだった

他にも色々と試みてたけどそのへんは他のメンバーが書いてくれるはず

まとめ

  • ISUCON 4 は何もわからないまま終わった
  • ISUCON 5 は頑張ってチューニングした箇所が大してボトルネックじゃなくてスコアが上がらなかった
  • ISUCON 6 はボトルネックの見極めまではできたが、実装力の低さと時間配分ミスから爆死 ← NEW!

少しずつ成長してはいるけど、まだ決勝行ける実力ではない・・・

はーーー 悔しさ〜〜

謝辞

今年もとてもおもしろい問題でした、運営の皆様ありがとうございました!

ISUCON 練習会をするために InfluxDB + Grafana でポータルサイトを作った

9/17,18日に迫る ISUCON 6 予選に向けて、某若手エンジニアコミュニティで参加者を募って ISUCON 練習会を開催した。

お題は今年の出題者である pixiv さんが社内 ISUCON を開催したときの AMI を活用させていただいた。

inside.pixiv.net

やってみた結果については同じチームだった sota1235 さんがまとめてくれているのでここには書かないが、まあここままだと決勝進出はまず無理だしもっと予習を頑張らないといけない。

ポータルサイト使えない問題

本番の ISUCON ではポータルサイトが用意されていて、ベンチマーカーを実行すると自分のチームのスコアがページに反映され、また他チームのスコアもリアルタイムで確認することが出来る。

しかし ISUCON 終了後に練習用 AMI が公開される際にはポータルサイトの AMI は公開されない。一人で予習復習する分にはポータルサイトは必要ないのだし、そりゃそうだ。

しかし今回の練習会のように複数チームでわいわいやるのであれば、本番さながらに他チームのスコアがリアルタイムで見れたほうが間違いなく楽しい。こうなったら自分で作るしかないので、試行錯誤を重ねてそれっぽいものを作った。

1行もコード書きたくない

まず思いつくのは、愚直に「スコアを MySQL か何かに保存して Google Charts のようなグラフ描画ツールで表示する Web アプリケーションを開発する」こと。 ただこれは極力やりたくない。 超汎用的な手段で無理矢理解決しにいっている感じがあって、面白くもなんともない。

21世紀という便利な時代なんだから、きっと他にもっとこのニーズに最適化された解決策があるはずだ、と思う。 エンジニアだからこそ、安直にプログラミングで解決しにいってはいけない。 「送られてきたデータをグラフで表示する」くらいのシンプルなニーズであれば、1行もコードを書かずに解決したい。

あと思いつくのは Mackerel にスコア飛ばすくらいだけど、無料プランだとホスト5台までだから5チームまでしかできないのかー、でも有料プランを使うと1ホスト(チーム)あたり1800円かかってしまって現実的ではない、という感じでコスト的に除外。

そんなことをあれこれ考えてるうちに、時系列 DB を使ってみようと思い立った。

時系列 DB の機運

時系列 DB はその名の通り時系列に沿ったデータを取り扱うのに特化した DB。 用途が限定的だ思うかもしれないが決してそんなことはない。 よくよく考えると多くのデータにはタイムスタンプがついていて、それを可視化しようとなったら時系列に沿ったグラフを表示することが多いので、時系列 DB が活用できる場面は思っていた以上に多い。

時系列 DB にもいくつも種類があるが、今回は

  • 簡単に扱えそうだから
  • 比較的新しいっぽいから
  • オシャレっぽいから

という雑な理由で InfluxDB を使ってみることにした。

趣味プロダクトだし、ダメだったらそのときに次の手段を考えればいいんや。

他の時系列 DB についてはこんな感じ。

  • Elasticsearch
    • fluentd → Elasticsearch → Kibana でログ可視化、という話はよく聞く
    • 単純なデータのグラフを表示する程度のニーズで使うには複雑すぎる
    • そもそも時系列 DB じゃないし
  • RRDtool
    • 枯れてる(らしい)
  • Graphite

詳しくは: 時系列DB・可視化のいまむかし - Qiita

今回は用途が小規模かつ1日だけだったので、可用性だの何だのということは一切考えていない。 長期的にメトリクス監視をしたいなどの場合はもっといろいろと検討した方がいいと思う。

ポータルサイトでスコアを集計する仕組み

  • 競技の参加チームにはベンチマークサーバにスクリプトをひとつ入れてもらう
    • ベンチマークを実行する際にはそのスクリプトを実行する
    • スクリプトを実行すると、ベンチマークが実行されると同時に InfluxDB のサーバへデータが送信される
    • そのスクリプト: ISUCON/bench.sh at master · ngineerxiv/ISUCON · GitHub
  • InfluxDB のデータは Grafana でリアルタイムに可視化される

f:id:hoto17296:20160904205703p:plain

実際の様子

触ってみた感想

InfluxDB は導入・設定も簡単だったし、スキーマレスだし、データ構造がシンプルだし、とっつきやすいことこの上なかった。

Grafana は InfluxDB のみならずいくつもの時系列に対応していて便利。 InfluxDB がシンプルな分を Grafana のリッチさがカバーしていて、良い組み合わせ。

InfluxDB / Grafana ともに公式ドキュメントがちゃんと書かれていて、導入方法とか書こうと思ったけど特に書く必要もないかなと思った。

まとめ

  • InfluxDB + Grafana で ISUCON 練習会のポータルサイトを作った
    • シェルスクリプトちょっと書いたけどほぼ「コード書かずに」作れた
  • InfluxDB も Grafana もとっつきやすくて便利

Gotanda.js #5 in TORETA を開催しました

f:id:hoto17296:20160903160548j:plain

昨日 Gotanda.js #5 を開催しました。

gotandajs.connpass.com

Gotanda.js のイベント会場は毎回違う場所でやっていて、今のところ

  1. モバイルファクトリー
  2. ガイアックス
  3. freee
  4. Retty

(敬称略)

という感じでやっています。 同じ会場でやらないみたいな縛りはないんですが、毎回違うと五反田のいろいろな企業を知れていいですね。

第5回の今回はトレタさんのイベントスペースをお借りしました。 会場提供ありがとうございました。

toreta.in

今回も雑な感じで LT 会がはじまります。

WebAssembly 入門 @pine613

JavaScript から WebAssembly を呼び出したり、WebAssembly から JavaScript を呼び出したりする話。

Vue.js The Progressive Framework @kazupon

Vue.js の重要なコンセプトである Progressive Framework についての話。

フロントエンド辛い問題に陥らないためにはアプリケーションの複雑性と向い合って適切な技術選択をする必要がありますね・・・

個人的には、Progressive Framework の5段階の領域のうちビルドシステムが最後のレイヤーにあるのが不思議だなー、と思いました。

Vue.js 0.12から2.0.0への移行 @nekobato

タイトルの通り、Vue.js のバージョンアップをした話。

「これ本当はやっちゃダメなんだろうな」と思ってた所は動かない

という言葉が印象的でした。

Introducing WebVR API 1.0 & A-Frame Updates @ikkou

ご近所 Meguro.es や VR Tech Tokyo でお馴染みの ikkou さんの、ブラウザから VR が出来る WebVR API の話。

個人的には昔遊んでいた LeapMotion で VR コンテンツが作れると聞いてまた遊ぶしかないな・・・!という気持ちになりました。

APIドキュメントにまつわる試行錯誤 @mizuki_r

API Blueprint から Controller は作れるのか、という人類の限界に挑戦(?)した話。

Apolloを使って、React-Reduxの世界にGraphQLを持ち込む @chuck0523

www.slideshare.net

React / Redux から GraphQL を使うための Apollo の話。

すごく丁寧に紹介されていて、GraphQL 触ったことない自分でも Apollo 使えば出来そうな気がしてきました(出来るとは言っていない)

QRコードwebアプリ作ってみた @tommie

Sails.js を使って QR コードをメモ的に使えるような Web アプリを作ったという話。

おもむろに QR コードが印刷されたシールを配りはじめるという斬新な LT でした。

FLIP Our Animations @ktsn

アニメーションのライブラリである FLIP とフロントエンドの各種フレームワークを組み合わせて使ってみた話。

多かれ少なかれそれぞれのフレームワークに躓きポイントがあり、やっぱアニメーション難しいな〜〜〜という感想でした。

次回は 12 月・・・?

今回もたくさんの方にご参加いただきましてありがとうございました!

次回 Gotanda.js #6 は 12 月に開催される予定です。 乞うご期待〜〜〜

100000000000000ジンバブエドル手に入れた

f:id:hoto17296:20160820134454j:plain

16日に26歳になったのだけれど、ウィッシュリストに入れていた100兆ジンバブエドルを id:arata3da4 が贈ってくれた。

ジンバブエドルとは南アフリカ南部のジンバブエで2015年まで使われていた通貨。 2009年には年間インフレ率 2億3000万% に達するなど驚異的なハイパーインフレに陥った。 ちなみに100兆ジンバブエドルは日本円に換算すると 0.34 円とのこと。

ハイパーインフレに至るまでの経緯は以下のカスタマーレビューが詳しい。

100兆ジンバブエドルの経緯

めちゃくちゃな政治をするとこういうワケのわからないことになるぞ・・・という戒めとして(?)大切にしたいと思います。

Angular と React の違い

Anguler 2 ハンズオンに参加してきた。

connpass.com

今まで React ばかり触っていた自分にとってはなかなか刺激的だったので、ハンズオンをやってみて思ったことや、懇親会でサポーターの方と話していたことについて書いていく。

なお、Angular 1 は触ったことがないので「Angular 1 との違い」については触れない。

免責、というか言い訳

React についてはそれなりに理解しているつもりだけど、Angular に関しては本当に「1日触っただけ」の経験値でこのエントリを書いているので・・・その点あらかじめご承知いただきたい。 わかりにくい表現や間違い等があったらご指摘いただけると嬉しい。

Angular 2 はフルスタックではない

「Angular はフルスタック」という言葉をよく耳にしていたので「フルスタックフレームワークこわい」と身構えていたものの、Angular 2 を触った感じでは別にそんなことはなかった。Angular 1 には Controller があったらしいので、おそらく Angular 2 からはフルスタックではなくなったということなんだと思う。

実際 Angular がやっていることは、コンポーネントを定義してそれをレンダリングするということだけ。

ビジネスロジックを担当するオブジェクトをコンポーネントに依存性注入(DI)する仕組みが用意されているものの、注入するオブジェクトそのものは開発者がよしなに設計・実装しなきゃいけないし、Angular 本体はプレゼンテーションロジックに徹しているといえる。

HTTP やルーティングの仕組みもあるが、あれは「Angular が公式で周辺モジュールを用意している」という程度のもので、Angular 本体 (angular/core) とは切り離して考えることが出来る。

Angular 本体がやっていることといえば、ユーザーが DOM を触らなくても済むようにプレゼンテーションロジックをラップするということ。

あれ? これ React とだいたい一緒じゃん。

Angular 1 のことは知らないが、少なくとも Angular 2 は責務が小さくまとまっていていい感じに設計されていると思う。 Angular 2 はフルスタックではない。

DOM 操作つらい問題に対するアプローチの違い

じゃあ Angular と React は何が違うのか。

そもそもが「SPA をやろうとすると人間が DOM にパッチを当てに行くのが辛すぎる」という課題があって、両者ともその課題を解決しようとしているが、そのアプローチの仕方が全く違う。

  • React は「ページ遷移 → サーバから新しい DOM を返却」という、「昔の Web の一連の流れ」をすべてブラウザ上で完結させることで解決する
  • Angular は「DOM のパッチ操作は全部フレームワークが面倒見るわ」という方法で解決する

という感じ。

それに伴ってコンポーネントの表現の仕方も異なっている。

  • React ではコンポーネントを命令的に記述する
    • 更新のたびに呼ばれる render メソッドを実装する
  • Angular ではコンポーネントを宣言的に記述する
    • 表示したい DOM のカタチを記述するだけで、あとは Angular がよしなにやってくれる

全く違う方法で同じ課題を解決しようとしていて面白い。

その他の違い

以上に書いたことが Angular と React の最も大きな違いだと思った。

その他には「React はブラウザ以外での用途*1もあるが、Angular はブラウザに特化している」などの違いがあるが、些細な事だと思う。

総じて感想

  • Angular と React は「やろうとしていることは同じ、アプローチが全く違う」という印象で面白い
  • 個人的には Angular に「なんか気持ち悪そう」という偏見を持っていたので、実際に触ってみて「Angular ええやんけ!」ってなった
  • Angular は最近だいぶいい感じになってきた*2とのことで「いまが Angular 始めどき!」という感じ

*1:サーバーサイドレンダリングや React Native など

*2:公式のルータ(v3)がようやくマトモに使える出来になってきた、など

はてなブログに引っ越した

昔はブログのメンテが好きで自分で様々なツールを使ってブログを作っていたものの、最近は面倒くさくなってしまってとうとう はてなブログ Pro に登録してしまった。

Jekyll からの移行

こないだまでは Ruby 製のブログフレームワークである Jekyll を GitHub Pages で動かしていたのだけど、Jekyll で書いた記事をはてなブログに移行するのがかなり面倒で、Selenium WebDriver を使った自動投稿スクリプトを書いて移行した。

github.com

この辺の話はまた後日詳しく書こうかと思う。

というかはてなさん是非 Frontmatter な Markdown ファイルからはてなブログに移行できる機能作って欲しい。

課金してモチベーションを上げる

はてなブログ無料でも使えるのになんでわざわざ Pro なのかというと、「課金してるんだから」ということをモチベーションにしてブログを書くためだ。

ブログって (コメント機能を Disqus とかでやってしまえば) 静的なウェブアプリケーションだし、全然無料の静的ファイルホスティングでも運用できるんだけど、放置しがちになってしまった。課金しておくことで、自分の中のケチな精神が「そろそろブログ書けよもったいないだろ」と勝手に煽ってくれる。高校生がギター買うときにちょっと無理してでも高めのギターを買うことによってモチベーションが長続きするのと同じような話だ。

人間生きているうちは色々なことを考えるもので、それをアウトプットせずに忘れ去ってしまうのはもったいないと思うし、がんがんアウトプットしていきたい。

いま結婚する意味

リアル知り合いの方々には Facebook でお騒がせしていますが、先日結婚しました。

雑なノリでウィッシュリストを公開したところ、思っていた以上にたくさんの方からお祝いの品をいただいて感謝感激雨あられです。この場を借りてお礼申し上げます。

結婚の報告というだけでは味気ないので、2015年の振り返りも兼ねて(?)僕の結婚観についてまとめました。

書いてから「誰得なんだこれは」って気づいたけどまぁ書いてしまったものはしょうがないので公開します。 年末年始でどうしようもなく暇なときがあればご一読ください。

なぜ結婚したか

結婚してみて、周囲から予想外な反応がいくつかありました。

「自分(男)からプロポーズしなくてよかったの?」(嫁からプロポーズされた)
「お前は当分結婚する気がないのかと思ってた」

などなど。

「誰と」結婚するか という意思決定は超重要なので慎重に考えますが、「いつ」「どのように」は割とどうでもいいことだと思っています。 ちなみに僕は「誰と」に関しても特に悩むことがなく、付き合い始めた時点で「まぁこの人と結婚するだろうな」という謎の確信があったので、そういう人と出会えたというのは運が良かったとしか言いようがないです。

もともと結婚したいと思っていて、
「誰と」に既に答えが出ていて、
「いつ」「どのように」に全くこだわりがない。

この三拍子が揃っていて 「よーしもう結婚しちゃうか〜〜〜 ₍₍⁽⁽(ી( ・◡・ )ʃ)₎₎⁾⁾ 」 という気持ちになったのが結婚した理由です。

式は挙げません

「式挙げないの?」とかなり多くの人に訊かれますが、挙げません。

結婚式・披露宴は、個人的には「当事者がやりたいならやればいいんじゃ」程度のものだと思っているのですが、 「(普通はやるであろう)結婚式・披露宴をやらないなんて珍しいですね!」という反応が意外と多くて驚きました。

正直、結婚式・披露宴というのはそうそう気軽にできるイベントではないと思っていて、貴重な時間と高いご祝儀を頂くならばそれに値するほどの超おもしろイベントを主催して然るべきなのですが、今の僕にそれを成し遂げる自信はありませんでした。 あと二人とも普段からスポットライトを浴びるような主役キャラではないですし、プロポーズされたイベントのときに珍しく主役をやってだいぶお腹いっぱいになったので当分はいいかなという気持ちです。 「結婚式呼んでね!」と言ってくれた方々には申し訳ないですが、そういう感じです。

個の時代の結婚観

「結婚って何の意味があんだっけ?」という話を長々とします。 (このへんは持論です。というか空想です。ちゃんとした裏付けがあるわけではない話です。)

結婚観というか、「人の生き方」というものは昔(100年以上前)と今とではだいぶ違っていたんだろうと想像しています。

はるか昔の価値観では、「その人の人生はその集落(コミュニティ)のもの」でした。

なぜなら、所属するコミュニティの意に反することは死を意味していたからです。 一度コミュニティから追い出された者は社会的な信用を失い、生きていくことが困難になりました。 コミュニティが絶対であるがゆえに個人の意志に価値はなく、コミュニティ全体でひとつの意思を持つ生命体のようでした。

そのため、「結婚」のようなイベントはそのコミュニティ(地域・家系)全体に関わる一大イベントでした。 「許嫁」のような風習もそういった背景から生まれた文化なのだろうと思っています。

しかし時代が経つにつれて暮らしが豊かになり、地域や家系に縛られないコミュニティが増え、どこに所属するかは個々人が能動的に選択できるようになりました。 たとえ家を追い出されたとしても、どこかしらかのコミュニティに所属して生きていくことができるようになりました。 それに伴って「意思」の単位も「集落」から「一族」「家」と徐々に細かくなっていきました。 「◯◯村の繁栄のために」「◯◯家の繁栄のために」という価値観から、「自分の人生を幸せにするために」という価値観にシフトしていきました。 今や「その人の人生はその人自身のもの」という個人の時代です。

「地域」や「家系」といった括りは「いくつもあるコミュニティのひとつ」に過ぎない存在になり、それに代わって「個人の意志」がより重要になりました。 だから、結婚の在り方もそれに合わせて変わっていっていいと思います。 結婚は「家と家のお付き合い」ではなく、あくまで「個人と個人の出来事」です。 そういう意味で、現代における結婚は昔ほどの重さはないと思います。

意思表明としての結婚

「じゃあ個人が主体となったこの時代に結婚というイベントの意味はないのか?」というと必ずしもそうではありません。

結婚の本質は「誓い」、つまり公に意思表明をすることに大きな意味があります。

何かしらについて「やるぞ!!」と公に宣言すると「よっしゃ応援したる」と誰かが賛同してくれる、という流れは世の中の至る所で起きていることです。 仕事のしかたとか、投資とかもだいたいそんな感じです。 やると宣言することで応援してもらえる。 ただしやると言ったからには必ずや達成しなければならなくて、様々な見返り(応援など)が得られるのはその責任を負うことによる対価です。

結婚も同じで、「自分はこの人と添い遂げるぞ」という意思を、自分に・相手に・社会に対して表明することによって、 祝福してもらえたり、法的な優遇が受けられたり、社会的な信用を得られたりするのだと思います。

一時は 「結婚って昔ほど一大イベントじゃなくなったし、既に同棲もしてるから実生活に何か変化があるわけじゃないし、もはや結婚ってしてもしなくても大して変わらないのでは?」 とさえ思っていましたが、やはりその意味は大きいです。

世の中というのは、こういうポジティブな期待の連鎖によって回っているのだなぁと実感します。

まとめ

「結婚に伴って何をするか」は、昔に比べるとだいぶ自由に自分たちでハンドリングできるような時代になったと思います。

慣習に囚われすぎずに、しかしお世話になった方々への感謝を忘れること無く、自分たちなりに「結婚」というイベントをアレンジしていけばいいんじゃないでしょうか。