スクリーンショット 2016-06-06 14.51.59

こんにちは。商品本部デジタルマーケティング室の 作野 浩之 です。

先日、AWS Summit TokyoDevelopers Conference で発表した「タウンワークにおけるサーバーレスアーキテクチャデザイン」の詳細について、お話しようと思います。

実施した施策について

リクルートジョブズはタウンワーク、フロム・エーナビ、とらばーゆ、はたらいく、リクナビ派遣など複数のメディアを取り扱うのですが、今回はタウンワークにおいて、以下のような施策を実施しました。

スクリーンショット 2016-06-06 14.54.59

つまり、サイト内のユーザーの行動に応じて、ユーザーの嗜好を元にダイナミックに検索結果を変更するという施策です。

最終的に出来上がったシステム構成

スクリーンショット 2016-06-06 15.49.25

結論からいうと、このようなシステム構成でもって、リアルタイムな予測を用いた検索システムを構築しています。
詳細については以下で触れていきます。

システムを作る上で最も考慮したポイント

そもそも、前提としてリアルタイムな予測を用いた検索システムを作るにあたり、大量の要件がありました。ざっと挙げると以下のような物です。

スクリーンショット 2016-06-06 15.10.54

一方で、この施策を実施したのは、Core Technology Labという6人のデータサイエンティストからなる集団でした。よって、上に挙げたような各種の要件を満たしつつも、可能な限りインフラの管理コストを下げてデータサイエンティストが機械学習のロジックに集中できる環境を作る事が必要でした。

というわけで、今回の施策"リアルタイムにユーザーの嗜好を拾い、検索結果をダイナミックに変化させるシステム"の詳細と、そのシステムを構築する上で、どのように管理コストを下げたか という話をしました。

リアルタイムな予測を実現するための要件の整理

リアルタイムな予測を構築するにあたって、大きく2つの要件があります。
1つ目は、ユーザーがサイト内で回遊する度に流れてくるログをリアルタイムに処理するための基盤を整備する事。
2つ目は、ユーザーが回遊した時にユーザーの嗜好を瞬時に特徴量に変換して保存し、検索した時に即座にユーザーに適した求人を予測する事です。

スクリーンショット 2016-06-06 15.19.50

ログ基盤の整備

ログ基盤の整備というのは、昔からよくあるインフラ整備の一つなのですが、今回は実現したい施策の関係で若干要件が複雑になります。今回の場合、リアルタイムにログを処理する(スライド上のフロー)という事だけではなく、機械学習という取り組みの性質から、もうひとつの要件が加わります。というのも、機械学習における予測は"過去の傾向から未来を予測するモデルを作成する"物なので、ログをストリームで流して終わりというわけにはいかず、溜まったログから予測モデルを構築するために、ログを溜めておく必要があります(スライド下のフロー)。

つまり、リアルタイムにログを処理できるだけではなく、2つの異なる用途に対してログを利用する事ができるログ基盤を整備する必要がありました。

スクリーンショット 2016-06-06 15.22.49

それに対して、"Amazon Kinesis"と"Lambda"を通して上記の2つの要件に対応するログ基盤を構築しました。

スクリーンショット 2016-06-06 15.31.15
まず、発生したログデータをAPI Gateway, Lambdaを通してKinesisに溜めます。
そして、ユーザーの回遊時に特徴量を更新するという処理は、リアルタイム性が求められるため、Kinesisにログが溜まった時点で即座にLambdaをキックして、特徴量が計算されるようにしました(Kinesisに向かって右のフロー)。
一方、ログを永続的に溜めて、溜まったログから予測モデルを構築するという処理は、そこまで厳密なリアルタイム性が求められないため、ポーリングしておいて、一定タイミングでKinesisに溜まったログをS3に書き出すようにしています(Kinesisに向かって下のフロー)。

このように、Kinesisにログを集約しておき、ログの処理タイミング別にLambdaを使用して、耐障害性が高く、様々な用途に使用できるログ基盤を構築しています。
Kinesisに向かって下のフローにあるLambdaはKinesis Firehoseが日本に来たら不用ですね(笑) 早く日本に来てほしいです。

特徴量の更新、予測の高速な処理

今回のシステムは"リアルタイムにユーザーの嗜好を汲みとって、検索結果に反映する"システムなので、読み書きに時間がかかるようなデータベースでは、システムが目指す姿から大きく乖離してしまします。なので、データベースの選定には非常にこだわっています。
要件の数でいうと大きく4つくらい挙げていますね。(ElastiCacheはデータベースサービスではなく、キャッシュサービスですが、簡単のためにデータベースと同じ括りにしています。)

スクリーンショット 2016-06-06 15.40.40

「どうやって選んでいったのか」なのですが、『高速な読み書きに対応』、『特徴量の変更に柔軟である≒スキーマレス』という2つの要件から、もうこれはNoSQLだろうとなり、RDS、カラムナーDBを選定の対象から即座に除外しました。
そこから、NoSQLに絞ったのですが、今回の場合、ユーザーに対して直接的に価値を還元するようなビジネスロジックに集中したいという動機があり、フルマネージドサービスを使う事に決定しました。(分散システムを自前で運用すると、ものすごく辛いという事を様々な所から聞いていたのも手伝って)

スクリーンショット 2016-06-06 15.47.59

最終的にDynamoDB, ElastiCacheという2つのサービスを使用しています。

最終的に出来上がったシステム構成

スクリーンショット 2016-06-06 15.49.25

最終的に出来上がったシステム構成はこのような物です。

ユーザーの回遊 => 特徴量保存

左上のユーザーに向かって下のフローです。
API Gateway, Lambdaを通して、Kinesisにログが貯まります。
次に、スライドの中央下のLambdaがキックされて、ログデータが特徴量計算サーバに送られます。
それから、特徴量計算サーバが瞬時にユーザーの特徴量を計算し、結果をスライド右中央のDynamoDBに保存します。
こうして、ユーザーが回遊する度にユーザーの特徴が更新されていきます。

ユーザーの検索 => 検索結果のソート

左上のユーザーに向かって右のフローです。
タウンワークのAPIを通してuser_idなどの情報が渡ってきて、先ほどのDynamoDBから溜めておいたユーザーの情報をフェッチし、ユーザーに適している求人原稿を予測して並び替えを行って検索結果を返します。
また、全く同じ条件で検索された際には不用な計算を省くため、予測結果をキャッシュして素早く検索結果を返します。

このようなアーキテクチャでもって、リアルタイムにユーザーの特徴から最適な求人原稿を返すという仕組みを構築しました。

まとめ

"サイト内のユーザーの行動に応じて、ユーザーの嗜好を元にダイナミックに検索結果を変えるシステム"を6名のデータサイエンティストが構築しました。
今回のプロジェクトでは、ビジネスロジックに集中してユーザーの検索体験の向上に注力したかったので、可能な限り、管理コストを下げるためにフルマネージドサービスを選定してインフラを構築していきました。

次回予告

後編では、Core Technology Lab で行ったインフラの管理コストの削減方法についてご紹介します。
今回の AWS summit での注目度も非常に高かった AWS Lambda を使用したTipsも紹介します!