ホットペッパービューティーコスメをリリースしました

CETチーム兼ホットペッパービューティーコスメ開発チームの寺下です。

先日 ホットペッパービューティーコスメ という新サービスをローンチしました。
コンセプトは「『似合う』が見つかるコスメ投稿・検索アプリ」で、現在はiOS版のみ配信を行っています。

本記事ではホットペッパービューティーコスメ(以下HPBコスメ)のアーキテクチャ・開発チームについて簡単に紹介していきます。 なお、iOSアプリの開発については今回は割愛します。

アーキテクチャ

インフラはGCPを利用しています。
GCPを採用した理由としては主に以下の点が挙げられます。

  • Kubernetes(GKE)を利用して高可用・スケーラブルなインフラを手軽に構築・運用できる点
  • 分析環境(BigQuery)との統合が強力な点
  • 弊社内で運用実績が多くあり、運用のノウハウが確立されている点

また、原則として運用負荷を下げるために可能な限りマネージドサービスを利用するようにしています。 例えばRDBMSとしてはGCPのCloud SQL for MySQL、全文検索エンジンにはElastic CloudのElasticsearch Serviceを採用しています。

全体構成

全体的には、主にGKE(一部GAE)上にデプロイされた10個弱のサービス群で構成されています。 各サービス間は必要に応じてCloud Pub/Subを介したメッセージングを行う疎結合な構成になっています。 ただし、完全なマイクロサービスを目指しているわけではなく、バックエンドロジックの大部分(8割ほど)は単一のRailsアプリケーションに集中させています。

設計思想

まず、APIの大部分にRailsを採用した理由としては特にプロダクト初期の開発スピードの速さが挙げられます。 しかしながら、Railsアプリケーションは一般的にあまりリソース効率が良いとは言えず、 Kubernetes内で水平スケーリングさせるにしても相応のインフラコストがかかるという弱点があります。 また、近年の画像処理・NLP・機械学習等は、Rails内(Ruby)で実装するよりもライブラリが充実しているPython等で実装するのが効率的であると判断しました。

そのため、HPBコスメでは原則としてRails APIを中心に据えつつも、画像処理等の複雑な処理かつサービス境界が明確な処理は別サービスとして切り出すようにしています。 他にも画像のアップロード処理としてRailsのActive Storage等を利用せず、Goで単体のマイクロサービスとして実装しています。 これは比較的簡単に切り出せる上、パフォーマンス・スケーラビリティを向上を見込めるためです。

とはいえ、先に述べたように過度なマイクロサービス化は行わないようには注意しています。 これは、チーム規模が小さかったり、プロダクトの初期フェーズで過度にサービス分割を行ってしまうと開発効率が著しく低下してしまうという問題があるためです。 HPBコスメのケースでは、上述したようなRails単体だと非効率になってしまうような一部の処理だけを小さなサービス群に逃し、 あくまで補助的にマイクロサービスを利用するような構成になっています。

実装例

上述したRails + マイクロサービス連携の簡単な例として、ユーザから投稿が行われた際の処理を表現すると以下の図のようになります。 実際にはテキストと画像に対していくつか処理を行っているのですが、 以下の図では簡略化のためテキストのチェックを行うサービス(Text Analyzer)だけを表現しています。 また、Subscriptionも複数作成可能ですが、図では1:1で表現しています。

ex1

ユーザから投稿が行われた場合、Rails APIはPub/Sub Topicに対して投稿Eventを投げます (この時点でユーザには2xxレスポンスを返しています)。 次に、Subscriber(Text Analyzer)が投稿Eventを拾い、何らかの処理を行った後、Rails API経由で処理結果を登録します。

ここで、Text Analyzer側でDBを持って永続化を行うという選択肢も取り得るのですが、DBを分割すると不要な複雑性を生んでしまいます。 そのため、各サービスは可能な限りステートレスに実装し、Rails API経由で永続化を行うようにしています。

アーキテクチャのまとめ

一般的にプロダクト初期では基本的にマイクロサービスは適さないケースが多いと思います。 理由としては以下のようなものが挙げられると思います。

  • プロダクト初期は開発チームが小さいケースが多い
  • モノリシックに作った場合が早く、効率的に作れる
  • ビジネス要件が不安定でありサービス境界の見極めが困難

しかしながら、今回HPBコスメでは上述したように部分的にマイクロサービス化を導入しています。 実際に開発・運用してみて、以下のような場合ではプロダクト初期でもマイクロサービス化の恩恵が大きいと感じました。

  • モノリシックなアプリケーションで開発するのが困難な場合(例: 機械学習等)
  • 非同期・イベント駆動にした方が良い場合(例: Push通知、画像のリサイズ等)
  • ストレージを持たず、ステートレスに作れる場合(チーム規模が小さいうちにストレージを分割すると運用コストが大幅に上がってしまうため)

開発体制

HPBコスメの開発チームについて簡単に紹介します。

現在エンジニアは新規体制用の少人数体制で開発を行っています。 チームとしてインフラ(SRE)・バックエンド・アプリという境界はあまり設けておらず、各人が領域を跨いで開発を行っています。

マルチスタックのエンジニアが多いことで、実際に以下のような利点を感じています。

  • リソース効率が柔軟であり、重要な案件から着手しやすい点
  • 属人性が低下することで、ベロシティが比較的安定する点
  • コミュニケーションコストが低下し、共通認識が形成しやすい点

例えば自分の場合はSwiftのビルドを待ちながらTerraformやKubernetesのmanifestを書いたりRubyやGoのコードを書くコンテキストスイッチの多い生活を送っていますし、Elasticsearchの運用設計・チューニングをしながらiOSの検索画面を実装しているエンジニアもいます。

また、リリース以前から1週間1スプリントの短いイテレーションでのスクラム開発を行ってきています。 初回リリースを行い状況も少々変わって来たため、今後も小さく仮説検証を回せる仕組みを模索している最中です。

まとめ

本記事ではHPBコスメの開発の概要について紹介してきました。 今月リリースしたばかりの非常に若いサービスで、技術・プロダクト両側面でまだまだこれから面白くなるフェーズだと感じています。

最後になりますが、 HPBコスメ開発チームではモバイルアプリエンジニア・フロントエンドエンジニア・サーバサイドエンジニア・インフラエンジニア・機械学習エンジニア等々幅広く募集しています!!!