Java
Kotlin
リファクタリング
spring
RDB

この記事はリクルートライフスタイル Advent Calendar 2018の6日目の記事です。

@tunanosuke です。今年リクルートに入社し、今はホットペッパービューティーの開発をしています。
ホットペッパービューティーはサービスリリースされてから10年以上たつプロダクトです。ビジネスとしては大きな成功をしている一方で、技術的には負債だらけです。これまで社内のエンジニアが少ない中プロダクトの成長を優先してきたという背景もありますが、少しずつ整備をしている段階です。そんな10年物システムが今こうなってるんだという裏側と今どう整備しているかを少しご紹介します。

現状

テーブル、カラム名がローマ字

結構な頻度で出てくるローマ字。そしてたまに省略されている。たとえば 予約 というワードに対して

  • YOYAKU
  • YYK

といったような表現方法が存在していて、さらにアプリまでそのまま返されてるとかある。
ローマ字ならまだ理解できるから許容?できても省略はなかなか厳しい。
ただ、もうここを変えるのは大きなコストとリスクを伴うので、変えられるものと変えられないものを切り分けて、変えられないものについてはできるだけ近いところで塞き止めすることが大事ですね。今そのように整備しています。

1テーブルのカラムの数がすごい

横に長い、とにかく長い、、
ただ、RDB考える時まずは横にどう持つかってことから考えることが多いと思うので気持ちはわかる。機能を継ぎ足し継ぎ足しで拡張してきた成果が見えます。
フラグがたくさんあり、1つのテーブルでいくつもの状態を管理しているので、それに引きづられてアプリケーションコードも複雑になっている状態です。一方で「えっ? ここは正規化するんだ」ってのもあり、いろいろ意図を推測しながらやっています。

結構この推測できることには救われることは多くて、細かい視点でツッコミどころはあるにせよ、なんでそうしたんだろうとか、なんでそうなったんだろうとか、なんとなーく意図は読み取れます。もちろん当時の設計者やドキュメントがあればそれに越したことはありませんが、これまで社員にエンジニアがいない、少ない中やってきたのでそれはできないです。なので、「まぁそうしたくなるよね」って感じられる状態なのはまだ救いだなと感じてます。

サブクエリ ジョイン ジョイン サブクエリ ジョイン ユニオン

縦に長い、とにかく長い、、そりゃ1回で取れたら楽、やるやる
ホットペッパービューティーは様々な方々が関わってきて機能が拡張されてきました。結果、場当たり的な設計になってしまっていて統一性がありません。そのため、O/Rマッパー使ってマッピングして ok ってなるようなデータ構造ではないし、かと言って SQL 1回で取るにもなかなか無理がある状態です。結果スロークエリとして1つの負債になっています。
おとなしく SQL 分割してアプリケーション側で自分達に合った構造にマッピングしてあげるレイヤーをアプリケーションに持たせることが今のプロダクトには適切で、ここも1つ1つ整備しているところです。

大量のバッチ

バッチチームがあります。つまりそれくらいあります。
バッチ大好き!

もうできてしまったのは仕方ないとして、一番難しいのはどのバッチがどのデータに影響あるのか把握すること。参照ならまだ良いにしろ、なにをトリガーにどのデータに対して更新があるかは見えにくい状態です。更新処理の走るバッチが Master DB のテーブルをしばらくロックしてしまうなんてことも、、んっ?

API 設計

まず前提としてホットペッパービューティーは大きく2つのサービスからなっています。

  • ヘアサロン
    • 美容室の検索や予約ができる
  • キレイサロン
    • エステやリラクゼーション、まつげなどのサロンの検索や予約ができる

このヘアとキレイは性質が異なっていてドメインが全く違います。それを1つのサービスとして展開しています。
それに引きずられるように API のエンドポイントもヘアとキレイが区別されていないことが多いです。性質が違うので必要なデータやレスポンスデータもヘアとキレイで異なるので、アプリケーション内には多くとヘアキレイ分岐があります。美容のサロンという意味では同じ属性も多く存在しますが、異なるドメインを1つで表現することは今後を見据えたときに厳しいですね、、
今はここを明確に分離するように設計をしている段階です。

リソース取得時に POST メソッド

:thinking:

リプレイスなど過去の負債を解消するためには、プロダクトの歴史やそうなった経緯など把握することはとても大切ですしそれをしないと改善はできませんが、ときには敢えて深追いしないという判断をすることも必要だったり。これはそういったケース。

今後の展望を少しだけ

sda replace.png
これまでのモノシリックなアーキテクチャから BFF - Backend 構成にリプレイスを進めています。Backend はこれまで通り Java、BFF は Kotlin を採用しています。
Backend に変えられない負債をできるだけ閉じ込めて各プロダクトからシンプルに見えるようにすることが肝です。
このあたりの詳細については今後弊社エンジニアブログでも発信していこうと思います。

まとめ

ここに挙げたのはほんの一部です。こういったことがたくさんあります。一方でプロダクトととしてものすごい成長を遂げてきたのはすばらしいですし、それに感謝しつつ今後を見据えたアーキテクチャに変化させていこうと思います。