The paradigm shift

saboyutaka’s diary なんかかく(ブログn回目)

Rubyエンジニアはsleep 1で殺せる、をngx_mrubyのAsync.sleepで乗り越える

そろそろ今年のISUCON、ISUCON8まであと1ヶ月ちょっとになったのでひとりリハーサルをそろそろはじめてるさぼです。去年ISUCON7に初挑戦してRubyを選択してsleep 1が乗り越えられず人権を失いました(原因は他にもあるけど...)。

ngx_lua での sleep

去年、予選終わったあとに感想戦で聞いた、Openresty、ngx_luaを使ったsleep方法を試したりしました。Rubyでsleepを行うと処理をブロッキングしてしまうので、nginx側で1秒待った上でRubyに処理を渡すことでRuby側では処理を待つ必要がなくって捌けるリクエストを増やす算段です。

Async.sleepを実装した ngx_mruby v2 がリリースされる

rubykaigi.org

hb.matsumoto-r.jp

今年のRubyKaigi2018での @matsumotory さんの発表で、nginxでのmruby実装である ngx_mruby module のv2をリリースする話をしていて、その中でnon-blockingなsleepが出来る Nginx::Async.sleep が出来るという話でした。今回はこれを次のISUCONまでには使えるようにして sleep 1 に対策出来るようにしておこうと思って実装してみました。

実装

github.com

@matsuu さんが公開しているVagrantfileからアプリケーションを立ち上げて、なんとなくDocker化するのが最近趣味なのでDocker composeで置き換えて実装しました。

dokcer-compose の設定

isucon7q/docker-compose.yml at 201808 · saboyutaka/isucon7q · GitHub

# dokcer-compose.yml 抜粋
version: '3'
services:
  web:
    build: .
    command: "bundle exec rackup -p 8000 -o 0.0.0.0"
    volumes:
      - .:/app
    ports:
      - 8000:8000
  ngx-mruby:
    image: saboyutaka/ngx-mruby
    ports:
      - 80:80
    volumes:
      - ./public:/var/www/public
      - ./config/ngx_mruby/nginx.conf:/usr/local/nginx/conf/nginx.conf
      - ./ngx_mruby/hook:/usr/local/nginx/hook

https://hub.docker.com/r/saboyutaka/ngx-mruby/

@matsumotoryさんもDockerfileを公開しているけど、latestが ngx_mruby 1.19.5 だった(気がする)ので2.1.1で作り直しました。

Ruby app.rb の処理を変更

https://github.com/saboyutaka/isucon7q/blob/0e6cc831d5cf1011d117598ab38536b377c53b34/ruby/app.rb#L154

def fetch
  ...

+  # sleep をコメントアウトする
+  # sleep 1
-  sleep 1

  ...
end

nginx の設定

https://github.com/saboyutaka/isucon7q/blob/0e6cc831d5cf1011d117598ab38536b377c53b34/config/ngx_mruby/nginx.conf

# nginx.confの抜粋
http {
  ...

  upstream app {
    server web:8000;
  }
  
  server {
    ...

  location /fetch {
    mruby_rewrite_handler_code '
      Nginx::Async.sleep 1000
      Nginx.return Nginx::DECLINED
    ';

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://app;
  } 
}

mruby_rewrite_handler_code directive 内でngx_mrubyを実行しています。ここでNginx::Async.sleep 1000を記述することで、nginxでリクエストをnon-blockingで止めて、時間経過後に処理を再開します。ちょっとハマった点は、rewriteを複数回行う場合、今回は proxy_pass も使っているので、明示的にNginx.return Nginx::DECLINED を書く必要があってそれに気づくのに時間がかかりました。nginxもうちょっと勉強して理解したい.. matsumotoryさん本人からリプライ頂いてありがたい🙏

実行結果

Before

f:id:saboyutaka:20180813215213p:plain

realtime: 1.157 apptime: 1.150

After

f:id:saboyutaka:20180813215021p:plain

realtime: 1.150 apptime: 0.140

apptime(Sinatraの処理時間)が1.150から0.140に変わりました!Rubyの処理が約1秒減ったのがわかります。これで/fetchへのリクエストが大量にきてもRubyの代わりにNginxが処理を止めるので、Rubyでリクエストが詰まることがなくなりました。

おわり

今年も去年と同じメンバー(@tompng, @_simanman, @saboyutaka)で挑戦しようという話になっていてRubyと今年はngx_mrubyも持っていけるようにしておきたいなと思ってやってみました。sleep 1 が2年連続は出ないだろーと思いつつも対策は万全で行きたいと思いますー💪

Hack Yourself ~グロースハックと学習のためのbrain hacking~

1月から始まったプログラミング講座で講師をさせて頂いてて1ヶ月半くらい経過して、受講者の間で日々コードを書いてる人とそんなに学習が進んでない人の差が大きくなったのでこういう話を受講者内Slackに書き込みしました。

以下内容

Hooked を紹介、ハマるしかけはHookedの日本語訳

心理学者が書いたものに対する依存性・中毒性をどう作るかを解説した本だけど

グロースハッカーはみんな読んでる良書で、サービス、商品にたいしてどうユーザー・消費者を中毒症状にさせるかという話

アプリをたくさん使ってもらいたい!自分のサービスを毎日使ってほしい!っていうのは心理学からすると中毒症状そのものなんですよねー

毎日FacebookTwitterを開くことの中毒症状をいかにつくるか

中毒症状にハメるステップとして外的トリガーと内的トリガーがあって、外的トリガーが外からの刺激、内的トリガーが内なる刺激、欲求

最初は外的トリガーで誘いつつ、じわじわと内的トリガーが発生する状態に持っていって、内的トリガーだけでぐるぐる回るようになると中毒症状の完成

で、なんでここでこれを出したかというと、勉強もこれと同じで。やりたいことがあるなら自分を中毒症状に持っていくと楽なんですよね

スクール通うとかは外的トリガーなんですけど、スクールの間で内的トリガーに切り替わる事が出来なければスクールが終了した後に学習をやめるのは目に見えてるので どうにか自分を中毒症状にするように脳をhackしていく必要があります

ぼくは何か学習したいと思ったら、毎日それを習慣にして、無意識に耳に入れたり、それをやってる人と何度もあったり、それに関するtweetを頻繁に目にするようにしたり。結構外的トリガーを整理して環境を作ると内的トリガーに切り替わりやすいという自分の中の実体験、自分の脳の仕組みを少し理解してるつもりなのでそういう感じで仕向けます

やる気って過大評価されますけど、やる気ってあまり関係なくて、脳を中毒症状に持っていければ勝手に自動的に学習する習慣がつきます(たぶん

本の中でも出てきますが、何か自分がアクション起こした時にインセンティブが発生するとスパイラルがぐるぐる回り始めます。

twitter、FB、Instagramだと投稿にいいねがつく、とか。

勉強した自分に何かインセンティブがつくような設計してたほうがいいです、あとはハードルを高く見積もらないこと、自分を褒めてあげること、やってない自分を責めないこと

happy brain hacking ❤

過去にすごい学習に時間を使ったことがある人は、自分を学習モードにするコツをなんとなく理解してたりするので、何か学ぼうとなった時自分をそう仕向ける術を知ってるので楽に学べたりします

逆にその経験がないと、学習できないことへの劣等感で先に進めない人もいます

若いうちに自分の学習パターンを把握してるとあとの人生が楽なので、若いうちに把握するのオススメ。学校教育ってそういうところでもあるんですけどね、何を学ぶかは何でも良くて、自分がどういう学習方法が得意かを自分で把握する期間

僕は資格たくさん取ろうと学生時代ずっと勉強してたのでその時に自分にあった学習パターンを見つけれてて、それが今でも活きてる感じ

紹介してる本はこちら

Hooked が原著

Hooked: How to Build Habit-Forming Products

Hooked: How to Build Habit-Forming Products

ハマるしかけ は Hooked の翻訳本

モチベーションでかなりパフォーマンスが変化すると自分の性格を自覚しているので、精神論苦手で"がんばる"とか"やる気"とかいう言葉はあまり信じないようにしていて。自分が学習する時に取り組んでる方法を書いてみました。

学習するのに外的トリガーを無理やり作る方法として、プログラミングスクールに入ったり、英語を学ぶんであれば海外の英会話スクールに入ったりはアリ。だけど長いあいだ技術を学ぶにはふとした時にやろうかなと内面から出てくる感情を育てる必要があってその感情、内的トリガーに切り替える必要がある。これがないとスクールが終わった途端にやらなくなる。みなさんも経験あるのでは。

ゲームやSNSって気づいたらハマってるんですけど、勉強って誰もハマるしかけを作ってくれないので自分で作る必要があります。(だいたいの場合

Progateとか初学者の方にとてもよくてオススメしてるんですけど、Progateはどんどん出来るけどそこから先がうまく進めないという人がたまにいて、それはProgateが丁寧にハマるしかけを作ってくれてるんですけど、それ以降の学習はそのしかけがなくなるので補助輪外されたような感覚で急になにも出来なくなる感じとか。あったりしません?

プログラミング学習のHookedモデル設計

f:id:saboyutaka:20180302023115p:plain

アクションにつながるような内的トリガーは超個人的な感情。○○さんがやってるからやりたいとか、○○するとモテるとか、かっこいいと思われるとか。恐怖の感情も、やらないと将来不安とか、普通の仕事は出来る気がしないからプログラミングしかないんだとか、絶対にこの状況を変えてやるとか。Hookedモデル的には快楽の感情よりも、負の感情の方がより強力。

以下はぼくが思いつくしかけをあげてみます。自分にあった環境を作ってみてください。

外的トリガー

  • スクールに通う(強制的にスケジュールに入る、意識の近い人と触れ合える)
  • シリコンバレーとか行く
  • 勉強会に行く
  • rebuild.fmを毎回聞く
  • Twitterで技術系の発信している人をフォローする
  • はてなブックマークのテクノロジーを毎日目に入れる
  • Githubの気になるプロジェクトの通知を受け取る
  • メンターを見つける
  • Youtubeの技術系チャンネルをお気に入り登録する
  • TED見る
  • エンジニアから起業した人とかの本を読む

トリガーは意識的に設計して環境整えるのが大切。普段の生活に取り入れる事が重要、やる気がなくても出来る事を準備しておく。

アクション

  • コード書く
  • 情報を見る、聞く
  • 勉強会、カンファレンスに参加する
  • 人と知り合う

あまり高い意識を持ってやらなくても良い。小さく始める。

リワード

  • 書いたコードが動いて嬉しい
  • わかる事が増える
  • できるだけゴールを短く見積もって達成感を得るようにする
  • 数値化出来るものは定期観測して成長を実感する
  • アクション出来たらカレンダーに○を付けてそれを眺める

楽しい、嬉しいが大切

インベストメント

  • アウトプットして人に見てもらう
  • ブログ書く
  • Githubで公開する
  • 自分のライブラリ公開する
  • 勉強会、カンファレンスで発表する

褒めてもらえる、共通点を持った人が増えてまたアクションに繋がる

みたいな感じ。

おわりに

今日この話をして、3月の講義が終わって5月のGW中の休みに、あ、これやってみようかなと自分で思ってコードを書いてるかどうか、が今後の学習を継続するにおけるKPIです、みたいな話をしました。

全員がうまくいく方法ではないとは思いますけど、理解出来る人はいるかも。 よかったら参考にしてみてください

Happy Brain Hacking❤️