• 株式会社クラウドワークス
  • CTO室 エンジニア
  • 九岡 佑介

シンプルな構成で検索速度は10倍に!Elasticsearch as a ServiceによるUX改善

今回のソリューション:【Found】

〜検索速度を大幅に改善する「Found」の使い方〜

日本最大級のクラウドソーシングサービス「クラウドワークス」を運営する株式会社クラウドワークス。同社ではクラウドソーシングサービスの肝である検索機能を強化するため、Elasticsearchのホスティングサービス「Found」を導入し、検索速度を10倍に向上することに成功した。

ユーザー体験を最上位に考える文化が根づく同社では、検索機能の強化という課題に対しても、ツールの選定からインフラの構築方法までの全てにおいてユーザー目線を大切にしながら取り組んでいる。同社でエンジニアを務め、Foundの導入を進めた九岡 佑介さんに詳しいお話を伺った。

目標はソフトウェア界の人間国宝!

私のキャリアの中で、クラウドワークスは4社目の会社です。新卒で社内SEのような仕事をした後にソーシャルゲームの開発をする会社に転職、その後はGREEで大規模システムの基盤開発をするという経歴を辿ってきました。GREE在籍時にちょうど30歳を迎えたのですが、それまで自分でサービスをゼロから大きく育てたことがありませんでした。

私の人生の目標は、ソフトウェアの世界で人間国宝になることなんですよ(笑)。そのためには、Rubyを作ったまつもとゆきひろさんや、Railsを作ったDHHさんのように、生涯の中で自分の代表作と言えるようなソフトウェアをゼロから創り上げる必要があると思っています。そのために、OSSに理解があり、ゼロを1にするような機会を多く持てるクラウドワークスに入社しました。

私はGitHubでいくつかOSSを公開しているのですが、多いものでもスターが120くらいです。世界的なOSSになるとこれが数万にもなり、2桁も違ってきます。スターが10万くらい付けば代表作と言ってもいいと思うので、そのレベルを目指していきたいですね。

「UX改善」でユーザーを笑顔にするためFoundを導入

私が入社した当時のクラウドワークスはユーザー数が10〜20万ほどで、サーバー負荷の問題が出るか出ないかというタイミングでした。今後サービスをスケールさせるためには、今のうちに障害になりそうな所を取り除かないといけないなという段階だったんですね。

クラウドワークスには「UX改善」という文化が根付いているのですが、それは平たく言うと「ユーザーが笑顔になれるサービスを目指しましょう」ということです。

クラウドワークスは、お仕事を受発注するサービスのため、「検索」が非常に重要な機能となるのですが、その処理が遅いことによって「何でこんなに待たされているんだ!」とか「こんなサービスは使いたくない」とユーザーに思ってほしくないですよね。

検索機能を改善することでユーザーが満足し、お仕事のマッチングも増えることでサービスは成長していくはずです。そういった背景から、検索機能を強化するためにElasticsearchのホスティングサービス、Foundの導入を決めました。

▼日本最大級のクラウドソーシングサービス「クラウドワークス」

MySQL→Foundで検索速度は10倍に!

Found導入以前はMySQLのInnoDB Full-text Searchを使用していました。導入が容易でインフラ構成をシンプルなまま全文検索が実現できるという理由から、MySQLをそのまま使用していました。しかし、会社の成長に伴いコストパフォーマンスやスケーラビリティ上の問題が出始めました。

例えばクラウドワークスでは、要件上、全文検索を伴うような重いクエリと他のクエリが同じDBを使う構成になっていました。一応の対策として、テレビ放送やニュース掲載など高い負荷が予見されるときはマスタ・スレーブ構成にて性能の改善を図っていました。

しかし、予算的に常にその構成にすることは難しかったため、想定外の負荷が突然来た場合は検索機能に引っ張られて別の機能のパフォーマンスが落ちるというリスクを常に抱えている状態でした。

MySQLからFoundに乗り換えて、費用を抑えつつ、検索速度を格段に上げることが出来ました。酷い時だと30秒くらいかかっていた検索クエリが、Foundだと1秒かからずに結果が返ってくるようになり、平均で10倍ほど速度が改善しています。

今は当時と比較してユーザー数が3倍以上になっているのですが、もし今でもMySQLで全文探索をしていたらと思うと夜も眠れないです(笑)。

サービス開発に集中するために「お任せ」できるFoundを選択

全文検索システムの構築ではAWSのCloudSearchも有名で、弊社でも導入を検討していました。CloudSearchはオートスケーリングなど運用を完全に任せられたり、日本語対応が充実していたりと総じて素晴らしいサービスだと思います。

ただ、独自のAPIを持っているため他のサービスとの互換性がないことを懸念していました。例えば検索機能の自動テスト時にはテスト用のインスタンスを起動して繋ぎこむ処理が必要になり、複雑な構成になってしまいます。

一方FoundはElasticsearchのAPIをそのまま使えるため、検索機能のテスト時には通常のElasticsearchを使う事が出来ます。AWSのようなオートスケーリングこそないものの、クラスタを無停止でスケールアップでき、最大のクラスタもメモリ256GBと機能的には十分でした。

弊社はスタートアップなので、事業のコアな部分の開発に集中すべきだと思っています。

技術的には魅力的なソフトウェアやサービスであったとしても、それを導入することによってサービス開発にコミットしたくてもできないエンジニアが増えてしまうようではクラウドワークス的にはアウトです。今は、運用を任せられて結果的に多くのエンジニアがサービス開発に集中できるようなサービスの方がありがたいと思っています。

Multi-AZで要件がシビアになっても対応可能!

Elasticsearchのホスティングサービスという観点で見ると、英語圏のサービスですがQbox、IndexDepot、Bonsaiなど複数の選択肢がありました。その中でもFoundだけが唯一スプリットブレーン対策を行っており、かつMulti-AZ(サーバを物理的に離れた複数のデータセンターに分散して配置する)にも対応していたということが決め手です。Multi-AZで構成すると、仮にひとつのデータセンターが落ちたとしてもサービス自体は継続することが出来ます。

しかし、実はMulti-AZはまだ使用していません。今は障害発生時にはMySQLによる検索に自動的にフォールバックするGraceful Degradationによって、速度は低下しても可用性は担保する設計にしています。

可用性と予算のトレードオフを考えた結果この構成にしていますが、今後サービスが成長すると「障害時にも速度の低下は許されない」状態になります。その時に、構築の手間がかからずお金とワンクリックで可用性を高めることが出来るというのは検索が命のクラウドワークスにとっては非常にありがたいことです。

インフラは「シンプル」な構成にすることが重要

Elasticsearchにデータを流し込む仕組みにも「シンプルにする」という考えを取り込んでいます。一般的には、一度にまとめてデータをバッチ処理で流す方法と、変更があるたびにリアルタイムでデータを反映していくという2通りの方法がありますが、弊社では後者の方法を選択しています。

バッチ処理を普通に実行するとその時間だけ特定のサーバーの負荷が上がってしまいますし、バッチ専用サーバーを必要なときだけ立てるとその分インフラの構成が複雑になってしまいます。現状では、リアルタイムで更新するほうが全体としてシンプルな作りになります。

リアルタイム更新の仕組みにはdelayed_jobというOSSを使用していて、クラウドワークス上の仕事の内容が追加/変更された時にタスクを登録し、タスクの実行時にFoundのAPIを叩くような仕組みになっています。

よりシンプルに構成するならキューイングのサービスは使わずにそのままFoundのAPIを叩くことも出来ますが、それだとFoundに負荷が集中したときにクラウドワークスのWebサイトまで遅くなってしまうので、このような構成にしています。

全ては「UX改善」のために

Foundの導入も、シンプルな構成にすることも全てクラウドワークスの「UX改善」につながっています。開発側の都合でMySQLを使っているためにユーザーを待たせてしまうとか、Elasticsearchに不具合があったからサイトにも影響が出ますとか、それだとユーザーは笑顔になれません。

それを防ぐためにも必要なところにはしっかりと開発工数をかけて、かつ出来る限り効率的な組み方をするということを心がけています。

今後はFoundをもっとサービス全体に広めていきたいですね。検索が関わるところは全てElasticsearchを使うように変えていきながら、Elasticsearchをエンジニア全員が使えるようにノウハウ化していく事も自分のミッションだと思っています。

あと、最終目標は人間国宝なので(笑)。Elasticsearchの導入に当たって自分のOSSを2つ作ったのですが、もっとOSSへの取り組みも増やしていきたいですね。

;