Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
クックパッドの巨大 Rails アプリケーションの改善
hogelog
September 12, 2018
Technology
9
9k
クックパッドの巨大 Rails アプリケーションの改善
hogelog
September 12, 2018
Tweet
Share
More Decks by hogelog
See All by hogelog
hogelog
0
8.9k
hogelog
0
700
Other Decks in Technology
See All in Technology
comucal
PRO
0
270
p1ass
15
5.5k
brtriver
1
240
fabiangosebrink
0
210
ihcomega56
2
140
tetsuyaisogai
0
150
ishiayaya
PRO
0
130
nghialv
2
240
rnakamuramartiny
0
980
aamine
4
800
oztick139
0
650
kema1015
0
560
Featured
See All Featured
dougneiner
119
8k
tanoku
86
8.6k
danielanewman
2
550
roundedbygravity
84
7.9k
paulrobertlloyd
71
3.7k
holman
447
140k
paulrobertlloyd
72
1.5k
sstephenson
146
12k
geeforr
333
29k
trishagee
24
3k
shpigford
370
42k
jacobian
257
20k
Transcript
クックパッドの巨大 Rails アプリケーションの改善 クックパッド株式会社 技術部開発基盤 @hogelog (小室直)
hogelog (小室 直) • 2013/8 クックパッド株式会社 入社 ◦ レシピ投稿関連の開発等(Web, Android)
◦ 会員事業関連、OEM 向け API 開発等 (Web, Android) ◦ 技術部開発基盤(いろいろ)
大きな Rails アプリケーション 開発してますか?
クックパッドでは 巨大 Rails アプリケーションを どう改善しているか
巨大 Rails アプリケーション リポジトリ cookpad_all の今昔
cookpad_all とは • cookpad.com を支える複数の Rails アプリと共有ロジック をまとめた shared gem
を含むリポジトリ • cookpad_all 内の各アプリはほとんど共有 DB
一昔前のクックパッドの開発風景 • 大多数の社内エンジニアが cookpad_all で開発する状況 • 開発基盤、インフラのリソースも cookpad_all に集中 ◦
強いモノリシック Rails アプリの時代 ◦ The Recipe for the World's Largest Rails Monolith by @a_matsuda https://speakerdeck.com/a_matsuda/the-recipe-for-the-worlds-largest-rails-monolith
2016 年頃のクックパッドの開発風景 • Microservices が進み cookpad_all 以外の開発が増える • cookpad_all は巨大だし辛い
• cookpad_all は基盤からレガシーな部分が多く整備コストも 高い ◦ Microservices 基盤は整っていく ◦ クックパッドにおける最近のMicroservices事例 by @adorechic https://techlife.cookpad.com/entry/2016/03/16/100043
2017 年、お台場プロジェクト発足 • @aamine により立ち上げられた cookpad_all 改善プロ ジェクト • 裏の目標は「開発基盤」というチームの解散
◦ cookpad_all はもうサービス開発チームが高い意識による片手間程度でメ ンテナンスできる規模ではない ◦ cookpad_all を徹底的に改善し、普通の開発チームでメンテナンスできる 状態にする
お台場プロジェクト やったこと
お台場プロジェクトでやったこと • 開発メトリクスの定点観測 • システム削除 • システム分割 • コード削除 •
その他
開発メトリクスの定点観測 • コード量、起動時間などの開発メトリクスを InfluxDB に記 録、Grafana のダッシュボードで定点観測 ◦ 大きな Rails
アプリケーションをなんとかしよう。まずは計測と可視化からは じめよう。 by @hogelog https://techlife.cookpad.com/entry/2018/06/08/080000
CI Duration • CI にかかった時間
App Load Time • アプリのロードにかかった時間
Code Statistics • rails stats を記録
2017-07-01 時点の stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC
| Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 55217 | 44464 | 619 | 4505 | 7 | 7 | | Helpers | 16853 | 13810 | 21 | 1582 | 75 | 6 | | Models | 95824 | 75336 | 1892 | 8854 | 4 | 6 | | Mailers | 2011 | 1612 | 45 | 199 | 4 | 6 | | Workers | 841 | 712 | 25 | 40 | 1 | 15 | | Chanko units | 8656 | 7160 | 2 | 169 | 84 | 40 | | Libraries | 50869 | 42003 | 660 | 3779 | 5 | 9 | | Feature specs | 58694 | 47269 | 0 | 189 | 0 | 248 | | Request specs | 56536 | 48938 | 0 | 24 | 0 | 2037 | | Routing specs | 544 | 437 | 0 | 0 | 0 | 0 | | Controller specs | 63233 | 52246 | 6 | 123 | 20 | 422 | | Helper specs | 5318 | 4389 | 1 | 10 | 10 | 436 | | Model specs | 91372 | 75504 | 5 | 85 | 17 | 886 | | Worker specs | 1150 | 954 | 0 | 1 | 0 | 952 | | Chanko unit specs | 7845 | 6293 | 0 | 8 | 0 | 784 | | Library specs | 26156 | 21905 | 23 | 123 | 5 | 176 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 541119 | 443032 | 3299 | 19691 | 5 | 20 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 185097 Test LOC: 257935 Code to Test Ratio: 1:1.4
2018-09-12 時点の stats +----------------------+-------+-------+---------+---------+-----+-------+ | Name | Lines | LOC
| Classes | Methods | M/C | LOC/M | +----------------------+-------+-------+---------+---------+-----+-------+ | Controllers | 32080 | 25883 | 305 | 2690 | 8 | 7 | | Helpers | 13212 | 10739 | 17 | 1214 | 71 | 6 | | Models | 73703 | 58028 | 1282 | 6540 | 5 | 6 | | Mailers | 1663 | 1336 | 38 | 165 | 4 | 6 | | Workers | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko units | 6154 | 5142 | 2 | 147 | 73 | 32 | | Libraries | 33604 | 28014 | 373 | 2449 | 6 | 9 | | Feature specs | 43505 | 34908 | 0 | 176 | 0 | 196 | | Request specs | 809 | 637 | 0 | 0 | 0 | 0 | | Routing specs | 406 | 328 | 0 | 0 | 0 | 0 | | Controller specs | 48137 | 39729 | 2 | 76 | 38 | 520 | | Helper specs | 4151 | 3430 | 0 | 9 | 0 | 379 | | Model specs | 63788 | 52339 | 2 | 52 | 26 | 1004 | | Worker specs | 0 | 0 | 0 | 0 | 0 | 0 | | Chanko unit specs | 2961 | 2359 | 0 | 1 | 0 | 2357 | | Library specs | 16383 | 13588 | 17 | 86 | 5 | 156 | +----------------------+-------+-------+---------+---------+-----+-------+ | Total | 340556 | 276460 | 2038 | 13605 | 6 | 18 | +----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 129142 Test LOC: 147318 Code to Test Ratio: 1:1.1
Dependent Gem Count • 依存 gem 数
GemCollector Up-to-date Point • 依存 gem の最新度 ◦ この gem
を使っているアプリケーションを探す by @eagletmt https://techlife.cookpad.com/entry/2018/06/08/080000
システム削除 • cookpad_all 内の不要なシステムを削除する ◦ 工夫はとくになし
2017 年当初の cookpad_all 構成 • cookpad というアプリが特に厳しい(1アプリでデプロイ先4つ)
api の削除 • cookpad 内のレガシー HTTP API 機能を削除 ◦ 社内でも動作確認不可能な古いモバイルアプリだけから使われていた
◦ 関係者、責任者と話を詰めて削除
api の削除 • cookpad のデプロイ先が1個減る(デプロイ先3つ)
background worker の削除 • cookpad 内のレガシー非同期処理システムを削除 ◦ resque 製非同期処理基盤 ◦
モダン非同期処理基盤としては barbeque が整備されていたので移行 ▪ ECS を利用したオフラインジョブの実行環境 by @k0kubun https://techlife.cookpad.com/entry/2016/09/09/235007
background worker の削除 • cookpad のデプロイ先が1個減る(デプロイ先2つ)
システム分割 • システムを正しく分割する • DB 共有はしない。アプリ間は API でやりとりする
pantry の分割 • cookpad と pantry を分割 (cookpad_all 内で) ◦
デプロイ先により挙動が変わる不思議なアプリを分割 ◦ 本質的に共有するものは多くなかった (切り離しはもちろん大変だった)
pantry の分割 • 1アプリ1デプロイ先という自然な状態に
様々な Microservices アプリへの切り出し • 検索機能、料理きろく API、モバイルアプリ AB テスト用 API、ユーザ認証関連機能、など数々なアプリを cookpad_all
から切り出し ◦ 切り出す単位は組織構造にフィットする、それでいてひとまとまりになってい て細かすぎないサイズ ▪ つまり「ちょうどいいサイズに」
様々な Microservices アプリへの切り出し • 色んな機能群を Microservices アプリ として切り出し
mobile の作り直し • ガラケー向けサイトモバれぴバックエンドのmobile ◦ アクティブに開発していないので作り直しのブロッカーがいない ◦ モダンな基盤で作り直す ▪ Hako
(ECS) 環境, gRPC, Service Mesh, ...
mobile の作り直し(移行中) • cookpad_all 内の アプリが4つに
コード削除 • 不要コードを削除する ◦ がんばって不要コードを探して削除 ◦ Gemfile をジッと眺めて不要 gem を探す
◦ lazy loading を利用し不要 gem を検出 ◦ 棚卸し Issue の自動作成 ◦ Iseq 実行処理を記録し不要コードを探す
がんばって不要コードを探して削除 • 不要コードをがんばって探して削除する • Code Cleaning Contest を開催 ◦ 期間一ヶ月のコード削除コンテスト
◦ 掃除にちなんだ豪華景品も
棚卸し Issue の自動作成 • 棚卸し Issue 作成、コード削除うながす作業を(半)自動化 ◦ 不要そうなコードを検出しコミッタからランダムにアサインしてコード削除か 必要なコードであるか記録するよう促す
◦ 元データはアクセスログ、バッチ処理実行ログ等 • 削除可否だけ聞いてお台場プロジェクトメンバーが削除する ことも
Gemfile をジッと眺めて不要 gem を探す • Gemfile を見て不要そうな gem を削除 ◦
jquery-rjs, aws-sdk-v1, …… • 工夫特になし
lazy loading を利用し不要 gem を検出 • ruby に手を加え lazy loading
利用し不要 gem を検出 ◦ Ruby の lazy loading の仕組みを利用して未使用の gem を探す by @riseshia https://techlife.cookpad.com/entry/2018/04/04/080000
Iseq 実行処理を記録し不要コードを探す • ruby に手を加え Iseq 実行ログを記録し不要コードを探す ◦ 本番で記録したログを Redshift
に蓄積 ◦ 詳細は近日中に @riseshia から techlife かどこかで発表など ◦ ruby 2.6 では素の ruby で可能になるかも ▪ Feature #15022 Oneshot coverage by @mame https://bugs.ruby-lang.org/issues/15022
その他 • gem の更新 ◦ rails, rspec など様々な gem のアップグレード
◦ Machinist 1 -> FactoryBot 移行 ◦ リポジトリに埋め込まれていた改造 gem を捨てて OSS 最新版に更新 ◦ bootsnap の導入 • ruby アップグレード • EC2 インスタンスの式年遷宮 (CentOS 6 -> Ubuntu 16)
うまく進んでいる要因? • 「お台場プロジェクト」という名前をつけた ◦ 名前があると自分も他人も認識する • 人をアサインしている ◦ メインタスクとして稼働している優秀なエンジニアが何人もいる •
すぐ近くに ruby コミッタが二人いる ◦ Iseq 実行ログの記録や lazy loading の活用なんかはガッツリサポートして もらいました
まとめ
まとめ • とにかく不要なコードを消したり分割したり、やっていってま す • まだまだ「ふつうの Rails アプリケーション」とは言えないの でチャレンジはいっぱい残されている