4層構成でアメリカの求人サイトを作った

はじめに

求人ボックスシステム部グローバルチームの右京です。

求人ボックスは2015年にリリースされたアグリゲート型求人サイト(求人検索エンジンと言った方がわかりやすい)であり、現在では求人掲載数1000万件・月間800万UUを超える大規模なサービスとなっています(2022年6月時点)。

グローバルチームはそんな求人ボックスの海外展開を進めるチームなのですが、この度アメリカ版求人ボックスとして『Jobcube』をリリースしました。この記事ではどのようにJobcubeを設計・実装していったのかについて、「4層に分ける」という考え方を中心にお届けします。

クラウドでつくろう

Jobcubeアメリカ版求人ボックスという位置付けですが、単なる求人ボックスのコピーというわけではありません。特にインフラ面では大きく異なっています。

求人ボックスは現在国内データセンターを拠点としたオンプレ環境で動いています。対してJobcubeはフルクラウド環境で構築しました。この主な理由としては、海外サイトであるJobcubeに国内サーバーを使うとネットワークレイテンシーが高くなるおそれがあったためです。

新しい試みとしてクラウド環境を採用した私たちは、クラウドネイティブな構成にすべくJobcubeアーキテクチャを考えました。

データフローを整理する

Jobcubeのサービス形態は求人ボックスと同じアグリゲート型求人サイトです。
すなわち、クローリングによってインターネット上の求人情報を収集し、それらを一括で検索できるようにします。データフローをざっくり図示すると下のようになります。図の波線矢印はReadの向き、実線矢印はWriteの向きです。

この図の概略を説明すると、次のような順序でデータを処理し、ユーザーに求人情報を提供するということです。

  1. クローラーが求人サイトを巡回して生データを取得する
  2. 生データを整形・抽出して求人マスタを生成する
  3. 全文検索エンジンに取り込む
  4. リクエストに応じて求人データを表示する

4層に分けてみた

ここで、下表のようにデータフローを4つの層に分けて考えてみることにします。

フェーズ 名前 役割
1層 Crawler 求人生データの収集
2層 Converter 求人マスタの生成
3層 Provider 求人マスタの利用
4層 Presenter 求人データの描画

そして各層に対して「(原則として)1つ前の層からのみ参照する」という制約を設けます。これは層間の依存を最小限に抑えることが狙いです。

概念図

4層に分けて役割を与えたことで、Jobcubeアーキテクチャに対する解像度が上がってきました。図にするとこういう感じです。

Google Cloudを使って実現

ここまでは概念的なお話でしたが、ここから「4層に分ける」考え方を実装に落とし込んでいきます。具体的には、Google Cloudを使ってJobcubeを構築していきます。

1層(Crawler)

クローラーは諸事情により求人ボックスの資産を大部分流用しました。そのためCompute Engine (GCE)VMを立てて常時稼働させるオンプレライクな構成となっています。求人生データを格納するデータストアとしてはMongoDBを選びました。
2層との連携はPub/Subを使ったキューイングで行っています。

2層(Converter)

求人マスタ生成の処理はCloud Runジョブを使ってコンテナで動かしています。Cloud Schedulerで定期的にジョブを立ち上げ、1層でキューイングされた求人に対し整形・抽出を行ってマスタを作ります。データストアにはCloud SQL (MySQL) を使用しています。
3層との連携は1-2層間と同様にPub/Subを使ったキューイングで行います。

3層(Provider)

こちらも2層と同じくCloud Runジョブを使っています。2層でキューイングされた求人に対し全文検索エンジンSolrへの取り込みを行います。Solrはスケーラビリティ等を考慮してKubernetes Engine (GKE) で構築しました。
フロントから参照される求人データはここで完成され、4層からのリクエストを受けて随時データを配信します。

4層(Presenter)

フロント側もCloud Runで構築しました。こちらはジョブではなくサービスになります。
4層はユーザーからのリクエストに応じて、3層からデータを取得し描画します。現時点では2層の求人マスタを直接参照してしまっているところもありますが、理想的には3層の全文検索エンジンとキャッシュから全ての参照を行います。

完成図

そうして完成したJobcubeの全体像がこちらです!

コードレベルでは、1層(Crawler)とそれ以外はリポジトリが分かれています。2〜4層は同一リポジトリですが、モジュラモノリスというアーキテクチャを採用しモジュールで分割しています。

まとめ

今回私たちはJobcubeアーキテクチャ4層構成で考えることにしました。これによってアプリケーションを独立したコンポーネントに分割することができ、依存関係を明確かつ最小限にとどめることに成功しました。また、クラウドを使ったサーバーレスなやり方にもマッチした構成にすることができました。


求人ボックスでは共にサービスをつくる仲間を募集しています

求人ボックスのサービス開発にご興味のある方は、是非こちらをご覧ください!

カカクコム採用サイト