Cookpad Lounge #7 世界最大級のモノリスcookpad_allどうする会議
マイクロサービス化して、現状いろんな問題が出てきているので、どうするべきかを話す
cookpad_all について
ウェブ(cookpad), APIサーバー(panty), バッチ(kuroko), 管理画面(papa)を集めたレポジトリ。
2014年くらいには、クックパッドのほぼ全てのコードがあった。
名前通り cookpad_all レポジトリ。
改善したもの
- 100%コンテナ化した
- service meshを導入した
- rrrspecというcookpad_all専用の並列テストシステムを消した
- 高速化 & 普通に行けそうだったので消した
- いくつかの古い機能を消した
- いくつかの機能を分割した
- ガラケー
- 検索機能
- ブックマーク
- 作者向けレポート機能
マイクロサービスとして、追加したもの
- スマホのviewをreactで開発した
- ブックマーク
- BFFを追加した
お題 0:マイクロサービスでよかったのか
マイクロサービスにガンガン進んでいったがshopifyはモジュラーモノリスと言っている。
@hokaccha さん
- railsのバージョンアップに時間がかかったりする
- ガラケーなどほとんど開発されていないが、システムのアップデートの障害になるものが分離できてよかった
@s4ichi さん
- 前に進んで学びがあったのでよかった
- 学びがあって、選択肢できるのがよかった
- 楽しかったのもある
@riseshia さん
- やってよかった
- とりあえずcookpad_allに突っ込んでおけば良いという社内の人の意識が変わった
@mineroaoki さん
- やるしかなかった
- cookpad_allを改善する手段として、適切だった。
- コードを削らないと、リファクタできなかった。
- アプリケーションを分けた方がよかった。
Q&A
ビジネス視点でマイクロサービス化して良かった点を聞きたいです?
マイクロサービス化したので、高速で機能を追加できるようになった
microservice化を始める前にもし戻れるとしたらこれをやりたい、みたいなのはありますか?
マイクロサービス化 or モジュラー化は、どちらもコストがかかる。
shopifyは成功しているが、ドメイン特性上cookpadが同様のことで成功するとは限らない
お題 1:マイクロサービスに分割するの難しすぎる問題
10年経ってもマイクロサービス化が終わらない可能性もある。
- 分割する上で、一番何が辛いのか?
- 分離するドメインが絡まっているDB情報をどう分割するか
- 期待するAPIが返さない場合にどうするかを考えるか
- ActiveRecordで考えているのをAPIベースで考える必要がある
- 歴史を知っている人が少ない
まずはリファクタして、綺麗にするところから始まる。分けたサービスの負荷がどれくらいかを考える必要がある。分けるのが大変なのではなくcookpad_allのリファクタ・分割が大変
今からcookpad_allに戻すはある?
あるかもしれないが、この5年はなさそう。
cookpad_allが受け入れる体制ができればいいが、まだできていないので、難しそう。
cookpad_allを綺麗にするのが一番の目的。なので、どちら人進むにしろやり切る必要性がある。
今から戻すとなると、技術的なチャレンジがしず楽なり、人間のモチベーションを保つのが難しくなる。
モチベーションを保つために難しくするのがベストなわけではない。
うまくできないかな〜
ActiveRecordっぽいAPIの繋ぎ方をできるようにできればいいんじゃないか?
API作らない程度の大きい粒度で分割できないのか?
cookpadはレシピを共通で使っているので、レシピを使う瞬間APIが必要になる
お題 2:マイクロサービスをいつ分割したらいいかわからない問題
分離した方は開発速度が向上する。そのため、これからビジネスとして進める部分を分割していきたい。
マイルストーンを置いていけばいいが、どうやっておけばいいのかわからない。
最初のうちは、DBはMysqlレベルで分かれていたので、最初のいくつかは自明にできていた。
だんだん自明ではなくなってきたので、どうしたらいいのか?
依存が薄いいものから外していけば良い。しかし、依存の薄いものは利用率が低くて、あまり旨味がない。欲張ると、コストが高くなるので、どうしたらいいのか悩んでいる。
git logから変更が大きい箇所を眺めていくことも良いのかな?
過去の傾向から見ることが良いのではないか。将来のことは分からないので、今あるものをどうするべきかを考えた方が良さそう。
活発でなくても、定期的に更新されているものをマイクロサービス化させていくのが良さそう
あまり使われていない機能は、一箇所に押し込んでいいんじゃないかと思っている。
分離するとなると、バッチも分割しないといけないし...難しい...
パッケージ化について
複雑すぎて、dependency graphを作ってみても、悩ましい...分類を頑張ってみたが2000パッケージ残っている
ファイル名だけでは分からない依存がある。
お題 3:マイクロサービス分割に失敗してデータが泣き分かれ問題
分割してから、新しい機能を載せればよかったが、並列で走ってしまった。分割したサービスと新機能のサービスの2サービスができた。
諦めて、DBを共通化させて、テーブルレベルで共通化させて、徐々にマイクロサービスに移行させていく。
DB共通化して、放置が事故を生みやすいので、やるなら最後までやり切る必要がある。
もともとcookpad_allが分割されていたら、発生しなかったんじゃないかな〜
お題 4:マイクロサービス分割がうまくいっても複数サービスでデータを共通したくなる問題
deletedのフラグをもったりして良いが、共通化する手段が欲しい...
マイクロサービスでは、変更が起こったらイベントを送ってもらうのが良さそう。そうすると毎回発行しなくて良さそう。
プロダクト間の通信を行うためには、transactionと同じレベルの信頼性が求められる。ので、binlogを活用するのが良さそう
binlogの活用例: https://debezium.io/blog/2020/02/10/event-sourcing-vs-cdc/
どこまでしたとかいうidを共有する必要になる。
schemaがほとんど変わらないものに関しては、read情報を共有していいのではないか?
schemaが増えたりする可能性があるので難しそう。
DBが落ちた時にエラーしないようにするのが大切
お題 5:マイクロサービス分割失敗を補うために全てが、オーケストレーション層に集まり始めて第二のallになりそう問題
必要な情報をBFFに集めたら、BFFに全て集まってき始めた。モダンBFFを活用した既存APIサーバーの再構築
「BFF = データの集約だけしたい」が、コードが書けるので、ロジックを書いてしまう...
イベントとかを使って、マイクロサービス間をよしなにすることができればいいのにな〜
GraphQLでできるものは対応して、できないものは、しちゃだめみたいな方針にしても良さそう
違反するものを追い出していきたい。
お題 6:いろいろなマイクロサービスを触るのが大変問題
- ローカルの環境構築
- それぞれのプロダクトによって構成が違う
- 1つの機能でもPR/レビューが分かれちゃう
- API設計を分けたりする必要がある
など大変な問題がある
モノリシックなレポジトリにするのは解決策の1つとしてもあるが、現実的なのか?という問題がある
お題 7:マイクロサービス境界と組織境界が全然一致しない問題
組織は何を指しているのか?レシピ事業本部のことを指しているのであれば、分けやすいのではないか?
広告では部署が分かれているので、そこは難しそう
既存コードを綺麗にして、マイクロサービスに分割して、モノリシックに戻すのがベターだと思っている。
世間的に言って、マイクロサービス分裂期になっていて、これから悪い部分も見えてくるフェーズに入る。
最後に:最終的にcookpad_allはこうしたい
@hokaccha さん
大きなGraphQLで管理したい。フロントエンド側で見ると、幸せな世界になる。
@s4ichi さん
cookpad_allが失敗したと言われているものがまとまっている世界
@riseshia さん
いろんなことを試して、開発できるcookpadだといいな
@mineroaoki さん
開発メンバーが10名増えるといいなぁ