開催2018年9月12日、メドピア株式会社が主催するイベント「MedBeer」が開催されました。今回のテーマは「Rails開発での技術的負債との付き合い方」。そのノウハウを語ります。アプリケーションの改善」に登壇したのは、小室直氏。その歴史と変遷を振り返ります。小室直氏(以下、小室):始めさせていただきます。これ、たいした意味もなく出してるんですが、この会場に来たときにこれを見て「あ~すごいちゃんとイベントバナー作ってる。クックパッド、クラッシー。あ、クックパッドもなんか絡んでるんだな~」って思ったんですけど。考えたら僕がしゃべるからクックパッドって社名も出てるんですね(笑)。(会場笑)単にそれを言いたかっただけです(笑)。中身のほうをやってきたいと思います。クックパッドから来ました、小室(@hogelog)です。今日は『クックパッドの巨大Railsアプリケーションの改善』というタイトルで話をさせていただきます。前にしゃべった方々と違う内容になっているのでよかったかなという気もしています。Railsアプリケーションの改善と言っていますが、Railsの中身についてはろくに触れずに進めていきます。自己紹介はたいしたこと書いてないんですけど、クックパッドに2013年に入っていろいろやって、今は技術部開発基盤グループというところでcookpad.comの裏側にあるcookpad_allという巨大Railsアプリケーションの面倒を見るというのが主な役割です。今日のテーマはRailsで開発をしている人々、技術的負債に興味がある人たちが参加しているということなので、おそらく大きなRailsに気持ちがある人たちだと思います。大きなRailsアプリケーションがなぜすごく辛いかとか、そういう話は、みなさん辛いことはわかっていると思うのでサクッと省きます。(会場笑)クックパッドではその巨大Railsアプリケーションをどう改善していったか。今までやってきたことをざっくり紹介していきたいなと思います。cookpad_allの歴史まずは、巨大アプリケーションがいくつも詰まっているcookpad_allというリポジトリですね。それについての今昔を紹介したいと思います。前提知識なんですが、cookpad_allとはcookpad.comの裏側を支える巨大なRailsアプリケーションが複数ぶち込まれていて、その共有ロジックをまとめたsharedというgemが含まれているリポジトリです。cookpad_all内の各アプリケーションはほとんどモデルとDBの共有によりロジックの共有をしていて、まあDB共有いいですよね。(会場笑)ね、早いし。あるとき限界が来るまでは。ひと昔前のクックパッドの開発風景は、だいたい社内のエンジニアみんながcookpad_allのアプリケーションに対してやたらめったらコミットしていて、みんなそこで開発していっている状況でした。開発基盤やインフラのリソースもcookpad_allに集中しています。みんなで巨大なモノリシックRailsアプリをどんどん整備していって。Alesというイベントで発表してきた内容です。世界最大のRailsモノリスということで、クックパッドという会社が超巨大なRailsアプリケーションをどうやってメンテナンスしているかみたいなタイトルで発表しました。これがクックパッドのモノリシックRailsアプリ最盛期みたいな時期でした。2016年頃の開発風景ちょっと時代が進みまして、クックパッドにもマイクロサービスの波が来ました。DockerやECSなど、いろんな便利な道具が揃って増えてくる中で、マイクロサービスが広がっていく。cookpad_allはもう巨大なモノリシックRailsアプリとして依然残り続けていて、どんどんレガシーで辛いものになっていきました。(参考:クックパッドにおける最近のMicroservices事例)ここで紹介している記事はcookpad_allでマイクロサービスがどうやって広がっていったかという記事です。実はそのときの内情を話すと、そのころcookpad_allっていう最後の砦みたいなところだけはほぼ手付かずで巨大なモノリシックRailsアプリとして残っていました。2017年にお台場プロジェクトという、『ふつうのHaskellプログラミング』とか10年SQL本とか『ふつうのLinuxプログラミング』とかそういう本をいろいろ書いていたりする青木峰郎さんという、この人もRubyコミッターですね、が立ち上げたcookpad_all改善プロジェクト。お台場プロジェクトというのが発足しました。時間が厳しそうなのでこのへんの裏の目標とかはサラっと飛ばしていきます。お台場プロジェクトというcookpad_allの巨大Railsアプリをいくつも抱えているリポジトリの改善プロジェクトが2017年7月ごろに発足して今までずっとやってきました。お台場プロジェクトが誕生というわけで、お台場プロジェクトを実際にどういう感じに実践していったかというを紹介したいなと思います。こんな感じで、開発メトリクスを定点観測して、いらないシステムを削除したり、システムをcookpad_allから分割していきました。あとコードを削除していろいろやってきました。詳細に触れていきます。開発メトリクスの定点観測。これに関してはtechlifeという技術ブログですでに紹介しているところではあるんですけれども。コード削除などをいい感じにしていくには、まず今がどれくらいダメで、日々どれくらいいい感じにできているのかを可視化しなければいけないと思いました。ダッシュボードを作って可視化できるようにしました。実際にcookpad_allの改善、お台場プロジェクトでどのようにやってきたのか、最近までの数字を出しています。いったことをやってきました。昔はCIで10分くらいかかっていたのが、最近では5分くらいまで短縮できたとか。短いやつだと7分くらいかかっていたのが3分くらいになったとか。そのくらいになっりました。これも可視化していたおかげで、日々こうして「このへんをがっつりやっていったことで、これ時間短縮できたんだな」みたいな。日々自分たちの心を慰めながら改善を進めることができました。これはアプリのロード時間ですね。sをしてからちゃんと動き始めるくらいまで、という感じで考えてください。10秒くらいかかっていたのが4秒くらいまで短縮できています。statsみたいなやつですね。cookpad_allに含まれている一番巨大なRailsアプリであるcookpadは、コードラインで40万行くらいあったのが30万以下くらいに減っています。示すと、一番ガクッと出てるところやこういうところに注目したくなる気持ちかもしれませんが、お台場プロジェクトに参画してやっていた身としては、日々ちょっとずつ下がっていってるところに注目してほしいです(笑)。日常的に細かく削除していって、ちょっとずつでもちゃんとやっているという気持ちがこの図に出ていて、どちらかと言うとなだらかな曲線のほうが見ていて心が温かくなるという、そんな話ですね。statsの数字を出してみたんですけど小さくてあんまり見えないので、トータルのところだけ触れます。cookpad_all内にはRailsアプリが今で4つ5つくらい入っているんですけれども、その中で一番巨大なcookpadというRailsアプリケーションの数字です。ほかにも同等サイズのものが3つくらいあったりしますが、そのcookpadのやつで2017年7月1日時点でトータルで54万行ありました。それが今朝測ってきた数字だと34万行ということで、20万行くらい減っているというですね。いやー、がんばりました。書いたコード量で給料が決まるような会社だと、きっと僕はマイナス給料で会社にお金を数千万円払うとかそんな感じになってたのかなと。なくてよかったです(笑)。しょうもないことを言いました。(会場笑)これは依存gem数みたいなのを出していて、Gemfile.lockを見るだけで出せるので2011年頃まで遡って出してみました。おもしろ半分なんですが。2017年7月ごろ、このころにちょっとだけそういうことを始めたので上限がたまに下がるところがあるんですが、そういう努力をしない限り、基本的にgem数はどんどん膨れ上がっていきます。Rails自体が依存するgem数なんかもすごく増えていってますし。とあるgemを導入したいときに「あ~こっちのgemと依存関係だ」とか、みなさん感覚としてわかると思います。それは時間が経つと増えていく。昔はRailsももうちょっと素朴だったみたいでそういうのはあると思いますが、それが図に出ていて、減らすと減るという。(会場笑)これはGemCollector、依存gemの最新度みたいなのを取っていて、これは社内にあるRubyアプリケーションの数値から相対的に出している数値です。cookpad_allのRailsアプリケーションになにも触らなかったとしても、cookpad_allがRailsをアップグレードしない間にほかがRailsアップグレードしていくとどんどん数値が下がっていくという。そんなものになっています。2017年7月ごろ、お台場プロジェクト発足と前後していますが、気持ちをもってエイっとbundleアップデートしたのが左側にガツンと上がっているところで。それまですごく少なかったのがちょっとずつ上がりました。がんばらないとどんどん下がっていって、たまにがんばって上げて、みたいなことをやっています。毎月1日に上げるとか、そういうことをやるべきかもしれません。2017年ごろのcookpad_allの構成システム削除の話に入ります。cookpad_all内にある不要なシステムを削除していきます。これはとくに工夫はありません。(会場笑)2017年当初のcookpad_allの構成はこういう感じです。cookpadというアプリケーションは恐ろしいことにデプロイ先が4ヶ所くらいあったと。「これいらねぇよな」みたいな。いらなそうというのはわかっていたので、がんばって削除しました。がんばって削除したら1個減りました(笑)。worker、これは新しい仕組みがすでにあったのに残っていた非同期処理システムみたいなもので、それもがんばって削除しました。1個残ってるのが気になる。気になるけど、これはまた次のところで。システムを正しく分割する次にシステム分割をしていきます。システムを正しく分割する。DB共有はやっちゃいけないので、アプリ間はAPIとかそういったもので通信する。pantryを分割します。これはcookpad_all内で分割します。さっきの図は明らかにここに誘導していたんですが、こうなってたら普通こうしたほうがいいですよね、という感じに分割しました。1アプリ1デプロイ先という自然な状態になりました。さまざまなマイクロサービスアプリに切り出していきました。これはもういろんな、いい感じに切り出していったというそれだけです。いろんなアプリを切り出していきました。いうサイズで切り出すという明確な境界があるわけでもなく、機能群とかいい感じの......本当にいい感じのサイズで切り出していったとしか言いようがないですね(笑)。Clusterみたいな、そういうのはすでにあったのでそっちに載っけていきました。載せる先はマイクロサービス化の流れで整備されていたのでそこは困ることはありませんでした。その中にmobileというのがありました。mobileといったら普通にスマホかな、みたいな感じですが、これはクックパッドでは携帯電話版向けサイト『モバれぴ』というものがございまして。うちではまだアクティブに稼働していますので、それをやるmobileというアプリケーションなんですが、誰も開発していないんですね。メンテナンスくらいはしているんですが、アクティブな開発はしていない。作り直すのにブロッカーがなにもないからモダンな技術で作り直そうという意思決定をして、モダンな技術で作り直していきました。いうわけでcookpad_all内のアプリは4つになりました。不要なコードやgemを探す次に、不要なコードをがんばって削除していってます。いろんなやり方を書いてます。具体的なやり方をなにも書いてないのがいくつかありますが、そうですね、がんばって削除しました。Contestみたいなものを社内で開催して、期間1ヶ月で「みなさんコード削除してください、豪華賞品もらえます」みたいなこともやりました。別にそのために時間を取るわけではなく、みんながスキマ時間に高い意識でやるみたいな。いうのも開催したこともあります。棚卸しIssueの自動作成みたいなこともやりました。半自動化、手元でスクリプトを回したらガーっといろんなものを見て、「このコードもう動いてないんじゃないですか?」みたいなIssueが立てられて。Gitのコミットログからそのコードを触った人に「お前触っただろ、これ?」みたいな感じで。「お前がこれをどうにかするんだ」みたいな感じで自動でアサインされていく感じで動かしていっています。(会場笑)これもちょっと回しすぎたからか反応が鈍くなってきたので、削除可否だけ聞いてお台場プロジェクトメンバーが削除するみたいなのが最近増えてきました。あとはGemfileをじっと眺めて不要gemを探す。これはじっと眺めて「不要そうだな」みたいな。あとはがんばって削除。jquery-rjsとか、最近ようやく消せました。Gemfileから消さなきゃいけねぇや。aws-sdk-v1とか、みなさんの中にも思い当たるフシがある人がいるかもしれません。あと、iSeq実行処理を記録し不要コードを探したりとかもしています。@mame)Ruby2.6では素のRubyでこういうことが可能になるかもしれません。@mameさんがそういう感じの提案をしているので興味があったら見てみてください。その他にもまあいろいろがんばってやっています。1からFactoryBotに移行してみたり、EC2インスタンスを入れ替えたり、いろいろやりました。うまくいった要因けっこうがんばってやっていて、いろいろうまくいったなと思います。うまく進んでいる要因、名前が付いたというのが1ついいかなと。名前があると自分も他人もこういうことをやっているということを認識しやすいです。あとは単純に優秀なエンジニアをアサインして人々がやっていってる。みなさんの会社でも、Rubyコミッターがいるかなと思うんですけども。Loadingの活用とかがっつりそのへんの人たちにサポートしてもらったりしています。そこから逆に、@mameさんの提案はそこから知見を得て提案してきてくれたのかなみたいなのもあるので、お互い与えているものもあるかなと思いたいところです。