Más contenido relacionado
Similar a BUYMAの商品検索システムの改善の取り組み (20)
Notas del editor
- それでは、BUYMAの商品検索システム改善の取り組みというテーマで発表を始めます
- 自己紹介ですけど、株式会社エニグモに所属しておりまして、だいたいスタッフはアルバイト等を含めると100名ぐらいいるんですけど、その中でエンジニアが集まるサービスエンジニアリング本部という部署が30名ほどおりまして、基盤開発グループという、アーキテクチャ設計したりパフォーマンス改善ですとか、検索基盤、データ解析基盤などのシステムの基盤となるところを開発するグループに4名ぐらいおりまして、そこに所属しています。
入社4年目になります。
最近は今日お話します検索システムの改善や、レコメンドエンジンの開発を主にやってます。
- 運営しておりますバイマについて軽く紹介しますと、主にファッションアイテムを扱うCtoCのショッピングサイトなんですけど、出品者が世界中いるというのが1つの特徴となっています。会員数は2月に400万人を超えまして、順調に成長しております。できたのは2004年なんですけど、途中でPHPに書き直す、Railsに書き換えたり、ガラケーサイトを閉じたりとか歴史あるサービスになります。
- 次にBUYMAのインフラの規模感ですけど、基本的にオンプレの自前のデータセンターで動いていて物理ベースで70台、仮想化してるんですけど論理ベースで200台強となっています。だいたいこれでピークタイムで毎秒1000リクエスト前後ぐらい捌いていると思います。
一部クラウド化していまして、AWS、Akamai、Google Cloud Platformを導入しています。脱オンプレへと進行中です。
- さて、今日お話するのは2つトピックがありまして、
1つは、商品検索システムの耐障害性の向上についてお話します。
2つ目は、キーワード検索の精度向上についてお話します。
一見どれもレガシーとは関係ないんですけど、どちらも古い仕組みをどうやって改善したかというお話になります。
- では、耐障害性の向上から始めます。
ブログ記事にもなってますので、あとで見てみてください。
- こちらは改善前の構成なんですけど、独立したSolrサーバーが複数台並列に並んでるだけで、バイマはRailsで出来てるんですけど、そのアプリケーション側で負荷分散してSolrへリクエストしていました。更新は絶えず動いているPHPでできた更新バッチがDBから更新データを取得しては全台に対して更新をかけていた状態です。
- SolrのIPはどうやって管理されてたかというと、設定ファイルをSolrのクライアントになる各アプリケーションが持ってい他状態なので、なのでSolrがダウンしても設定ファイルをデプロイし直さないと切り離しとか切り戻しができないという状態でした。ここらへんがレガシーですね。
- この構成の問題点は単一障害点だらけだということです。Solrが1台でもダウンすると検索も更新もエラーになってましたし、復旧するのにデプロイしないといけないという大変さもありました。
また、更新バッチも冗長化してなかったので、絶えず動いているバッチなので、そのサーバーが止まると商品を出品したのに検索結果に出てこないという状態になってしまうのも問題でした。
復旧にも大変で、切り戻すときにSolr同士のデータを揃えるのが大変でした。
経緯としては、このままマスキャンペーンを打ってユーザー数が増えたらひとたまりもないということで、リプレースに踏み切りました。
- そこで、Solrのクラスタ管理を自動化してくれるSolrCloudを導入しました。
IPを設定ファイルで管理していましたが、Zookeeperが管理してくれるようになるので、アクティブなSolrのIPを取得できたり、Solrがダウンして更新されたらクライアント側に逆に通知してくれたりするので、ダウン状態のSolrへはリクエストが行かなくなり、エラーも発生しなくなりました。
更新の仕組みは、バッチサーバーでやってたのをResqueっていうRedisをバックエンドにしたRuby製のバックグラウンドジョブでやるようにしました。これは冗長化が容易だったのでこの点でも単一故障点が解消されました。
SolrCloudは常にLeaderのサーバーが更新されれば他のサーバーへレプリケーションされるという機能があるので、更新するのは常にLeaderのサーバーだけでいいですし、そのLeaderもダウンするとフェールオーバーしてくれて、ReplicaがLeaderに昇格してくれます。
- SolrにはMaster-Slave構成っていうのもあるんですけど、これだとMasterを冗長化しないとそこが単一故障点になりますし、Solrへの負荷分散をLBでやればいいのではというのはLBを冗長化しないと単一故障点になるということで、ある程度負荷が高いところを冗長化するのって管理とかも含めてコストなんで、SolrCloudにしました。
- この改善によって単一障害点を排除できましたし、更新部分もバッチだったのをResqueワーカーにして冗長化できました。
復旧もノードを組み入れるだけでデータが同期されるということで簡単になりました。
- 頑張ったところは、SolrCloud対応のRubyクライアントを作ったところです。rsolr-cloudとして公開しています。rsolrっていう有名なsolrのrubyクライアントを拡張したものです。ruby製のツールでfluentdとか、logstashなどのログ収集のツールにも組み入れられていたりして、yahooの検索のエンジニアの人がyahoo社内のログ収集という意外なところでも活用されているようです。
- 続きましてキーワード検索の精度向上についてお話します。
- 以前、バイマで「ポーチ」を検索しても、全然関係ないものしか上位に来ないという状態でした。他にも同じようなヒットするのに上の方に来ないっていうキーワードがたくさんありました。
- これは何故かと言うと、出品者さんが自分の商品のインプレッション率を高めようとしてSEO対策のようなことをされていて、商品コメントの下の方に商品自体には関係なくても検索されそうなキーワードを下の方に散りばめるテクニックが横行していたことが原因の1つでした。
- そこで、キーワードへの関連度をソートに取り入れました。
以前は、商品人気度を算出する秘伝のロジックがあるんですけど、それで単純にソートしていただけでした。
キーワードとの関連度も取り入れるというのは、具体的には、solrのクエリーパーサーをedismaxにして、スコアでソートします。
フィールドごとにスコアの重み付けを指定可能なので、たとえばカテゴリ名のフィールドにヒットしたら上位に持ってくうるという調整も可能です。
従来の人気度もboost functionというパラーメーターで利用して程よく人気順で並ぶようにしています。
- それから、N-gramしか使ってませんでしたが、形態素解析を導入しました。毛皮とかの「ファー」で検索しても全然関係ない「サーファー」とか「ファースト」などは上位に来なくなりました。誰でも単語登録できるようにユーザー辞書の管理ツールを作成しています。
シノニム辞書も導入して同義語の差異を吸収しています。
- 気を使ったのは、秘伝のタレを壊してしまう怖さでした。
ある程度、商品人気度の算出ロジックを壊してしまうので、KPIへの影響が心配でした。問題ないキーワードが逆に悪化しないかとか、改善したとしてどのぐらい検索結果のCTRがよくなったかという評価も必要でした。
そこで、検索条件ごとでCTRの計測が必要になりました。
- CTR計測の仕組みはこのよみなっていて、ブラウザでのクリックやネイティブアプリでのタップのイベントをWeb APIで収集してBigQueryで集計し、re:dashやあとは自前の計測ツールで見れるようにしました。
- この計測の仕組みで秘伝のタレを壊す怖さから開放され、安心して改善に挑むことができました。
感覚ではなく数値でロジックの正当性を裏付けられるようになったのが大きかったです。
微妙なsolrのクエリパラメーターチューニングの効果測定も可能でしたし。
ABテストによるCTR比較も可能になったので、少しづつ様子を見ながら全体にリリースしていくということも可能になりました。
- 今後は、検索の並び順だけではなく、UIUXをこの仕組でも改善できたらいいなと考えています。
それから、BigQueryのデータをより幅広く機械学習、データ解析などで活用していきたいと考えています。
- 発表は異常なんですけど、これらを一緒にやりたいエンジニアを募集中です。
以上、ご清聴ありがとうございました。