Open12

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年経ってもマイクロサービス化が終わらない可能性もある。

  • 分割する上で、一番何が辛いのか?
    1. 分離するドメインが絡まっているDB情報をどう分割するか
    2. 期待するAPIが返さない場合にどうするかを考えるか
    3. 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名増えるといいなぁ