Upgrade to Pro — share decks privately, control downloads, hide ads and more …

niconicoの検索システム(2019年版)

Ken57
December 04, 2019

 niconicoの検索システム(2019年版)

2019年のniconicoの検索システムの説明です。

Ken57

December 04, 2019
Tweet

More Decks by Ken57

Other Decks in Programming

Transcript

  1. niconicoの検索システムの概要 • データサイズ • コンテンツ数: 約3,000万doc • 性能要件 • 参照系

    • ピークタイムで1,300req/secの検索リクエスト • 99.9%のリクエストを1秒以内にレスポンス • 更新系 • ピークタイムで1,000msg/secのコンテンツ更新メッセージ • 1分以内反映
  2. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ ログ基盤 検索者

    サービス サービス 検索システム • Elasticsearch Version 6.8を利用 • 2012年にVersion 1.xで運用開始し、 順次アップグレード • Version 7.xへのアップグレードも 計画中 • 構成 • データノード: 40台 • 突発的な負荷が予想される際に は臨機応変に増減 • マスターノード: 3台
  3. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ 検索者 サービス

    サービス 検索システム • 同義語辞書構築 • ユーザ情報インデックスのデータ生成 • ユーザのフォロー関係・視聴関係の クラスタリング ログ基盤
  4. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ 検索者 サービス

    サービス 検索システム • 同義語辞書 • ユーザのクラスタ情報 ログ基盤
  5. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ 検索者 サービス

    サービス 検索システム • データ更新を行うサブシステム • 主にGo言語で構築 更新系 APIサーバ Rabbit MQ DB 書き込み ワーカー My SQL Elasticsearch ES 書き込み ワーカー コンテンツ 更新 メッセージ ログ基盤
  6. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ 検索者 サービス

    サービス 検索システム • コンテンツ検索APIを提供するサーバ • 言語はScala • フレームワークはFinagle • フィルタチェインで下記の流れを記述 • 同義語辞書からの同義語取得 • 検索者が所属するクラスタ情報の取得 • 検索者の視聴履歴情報の取得 • ESのクエリ生成 • ESへのリクエスト
  7. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150
  8. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ 更新メッセージ(再生数更新) 動画ID: sm9 再生数: 432 ランキングスコア合計: 900 ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150
  9. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 動画サーバ側で再生数・コメント数・マイリスト数 に基づいて計算されて送られてくる 更新メッセージ(再生数更新) 動画ID: sm9 再生数: 432 ランキングスコア合計: 900
  10. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ 更新メッセージ 動画ID: sm9 ランキングスコア合計: 900 ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 +100
  11. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ 更新メッセージ 動画ID: sm9 ランキングスコア合計: 900 ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 +100
  12. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 • 64bit longの配列
  13. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150
  14. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間分のランキングスコア の増加量の総和を取って ソートする
  15. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ 更新メッセージ 動画ID: sm9 ランキングスコア合計: 900 ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 +100
  16. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ 更新メッセージ 動画ID: sm9 ランキングスコア合計: 900 ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間ランキングスコア 増加量近似値: 600
  17. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間ランキングスコア 増加量近似値: 600 第1ソートでは、近似値 でソート
  18. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間ランキングスコア 増加量近似値: 600 トップN件を、 24時間分のランキングスコア 増加量情報の総和を取って ソートする
  19. ランキングソートの処理の流れ • 9/10 19:00に動画ID:sm9のランキングスコア合計が800→900になったときの例 Elasticsearch 動画 サーバ 更新系 参照系 API

    サーバ ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間ランキングスコア 増加量近似値: 600 • 25時間のスコア増加量の総和である • 再生数・コメント数・マイリスト数が更新 されないコンテンツの値が残り続ける
  20. ランキングソートの処理の流れ • ⽇次バッチで24時間再⽣されていないコンテンツのランキング近似値は消す Elasticsearch 動画 サーバ 更新系 参照系 API サーバ

    ランキングスコア合計: 800 動画ID: sm9 ランキングスコア増加量 9/10 19:00 +100 9/10 18:00 +50 … 9/9 19:00 +300 9/9 18:00 +150 24時間ランキングスコア 増加量近似値: 600 バッチ サーバ
  21. ランキングソートの検索クエリ(1) "query": { "function_score": { "query": { …タグ検索のクエリ }, "functions":

    [ { "field_value_factor": { “field”: “[ランキング近似値]", "factor": 1, "missing": 0 } } ], "boost_mode": "replace” 第1ソート • Rescoreを利用する場合は、Fieldでなく Score(デフォルトでは単語関連度)でしか ソートできない • Function scoreのfield value factorで ランキング近似値を指定
  22. ランキングソートの検索クエリ(2) "rescore": [ { "window_size": 1000, "query": { "rescore_query": {

    "function_score": { "query": { ...タグ検索のクエリ }, "functions": [ { "script_score": { "script": { “id”: ”[スコア増加量計算のスクリプト]", "params": { ...スクリプトに渡すパラメタ 第2ソート } } }, "score_mode": "multiply", "boost_mode": "replace", "boost": 1 } }, "query_weight": 0, "rescore_query_weight": 1, "score_mode": "total" } } ] } • RescoreするトップNの値 • ノードごとのトップNであることに注意 • 10シャードなので実際はトップ1万
  23. rescoreでどの程度⾼速化できたか Rescoreあり Rescore無し 1回目 0.540s 1.628s 2回目 0.508s 1.125s 3回目

    0.430s 1.066s 4回目 0.539s 1.094s 5回目 0.465s 1.142s 平均 0.496s 1.211s • キーワード「ゲーム」で検索し、約700万件動画がヒットしたときの レスポンスタイム • 約60%⾼速化 • 複雑な計算式からなるソートの⾼速化にrescore機能が有効であることが分かる
  24. 背景 (1) • ソーシャルネットワークサービスにおけるコンテンツ検索では、 ソーシャルサーチが検索精度の向上に効果的である • 動画や⾳楽、⽣放送番組などのマルチメディアコンテンツの 検索では、その内容が⾃然⾔語で⼗分に説明されているとは 限らない •

    SNSとしての機能を持つCGMサイトのコンテンツ検索においては、 検索者とコンテンツ作成者のフォロー関係や視聴関係などの情報を 利⽤することで、検索精度を向上することができる可能性がある Personalized social search based on the user's social network, (David C, 2009) The anatomy of a large-scale scocial search engine (Horowitz, D,2010)
  25. Louvain法(1) • ソーシャルネットワークに対して凝集型階層的グラフクラスタリングの⼀⼿法 であるLouvain法を適⽤して⽣成した階層構造のクラスタ情報をコンテンツDB に格納してコンテンツ検索時のスコア付けに使⽤する • Louvain法(V. D. Blondel, 2008)とは、Newmanのモジュラリティという

    指標をもとにした⾼速かつ⾼精度でコミュニティ構造を抽出できる、 代表的なグラフクラスタリングアルゴリズム • Louvain法は、処理の繰り返しごとに得られるコミュニティ構造を保持する ことで、解像度の異なる階層的なコミュニティ構造を得ることができるという 特徴を持っている
  26. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤
  27. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤 フォロー関係ログと視聴ログに対して、 Louvain法でグラフクラスタリングを行う (spark graphx を利用)
  28. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤 ユーザのクラスタ情報を Redisに格納する
  29. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤 • 動画の新規投稿イベントを受け取る • クラスタ情報DBから動画投稿者の クラスタ情報を取得する • 合わせてコンテンツDBに書き込む
  30. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤 • クラスタ情報DBから検索者のクラスタ情報を 取得する • 検索者のクラスタ情報と、動画投稿者の クラスタ情報のクラスタ間類似度をもとに ヒットしたコンテンツをスコアリングし、 ソートして提示する
  31. システム構成 Elasticsearch サービス 更新系 参照系 API サーバ バッチサーバ (1) (2)

    検索者 (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) ログ基盤
  32. スコアリング(1) • ⼤量のコンテンツがヒットした際のレスポンス時間を 短縮するために、ランキングソートと同様にElasticsearchの rescoreで2段階でスコアリング = 9 :単語関連度スコア + ,

    :再生数スコア + - :コンテンツ鮮度スコア + ; :コメント鮮度スコア + < :フォロー関係クラスタ間類似度 + = :視聴関係クラスタ間類似度 1段階⽬: コンテンツの投稿⽇時が新しい順によりソート 2段階⽬: 1段階⽬のソート結果の上位件について、ユーザのクラスタ情報を 利⽤したスコアによりソート
  33. スコアリング(2) • ⼤量のコンテンツがヒットした際のレスポンス時間を 短縮するために、ランキングソートと同様にElasticsearchの rescoreで2段階でスコアリング = 9 :単語関連度スコア + ,

    :再生数スコア + - :コンテンツ鮮度スコア + ; :コメント鮮度スコア + < :フォロー関係クラスタ間類似度 + = :視聴関係クラスタ間類似度 1段階⽬: コンテンツの投稿⽇時が新しい順によりソート 2段階⽬: 1段階⽬のソート結果の上位件について、ユーザのクラスタ情報を 利⽤したスコアによりソート
  34. クラスタ間類似度(1) • 検索者とコンテンツ投稿者のフォロー関係クラスタ情報の類似度の 計算⽅法を例として説明する • 検索者Aのフォロー関係クラスタ情報を? = ?,, , ?,-

    , … , ?,/ コンテンツ投稿者Bのフォロー関係クラスタ情報 @ = [@,, , @,- , … , @,/ ]としたとき、AとBのフォロー関係クラスタ間 類似度(? , @ )は下記の式で計算する ?, @ = 1 E &F, / ?,&, @,& , = I 1 ( = ) 0 ( ≠ )
  35. 評価実験 • CGMサイトであるニコニコ動画に提案アルゴリズムを実装し、 検索者が興味のあるコンテンツを⾒つけるためにクラスタ情報が 有⽤であることを確認する • 下記のネットワークに対しlouvain法を適⽤し、クラスタ情報を⽣成する • フォロー関係 •

    視聴関係 • 検索システムの規模(2018年4⽉2⽇) • 約1500万件の動画を検索対象として保持している • フォロー関係、視聴関係のネットワークの規模 ネットワークの種類 ノード数 エッジ数 フォロー関係 9,194,596 109,471,657 視聴関係 3,047,813 48,378,044
  36. 評価実験 • CGMサイトであるニコニコ動画に提案アルゴリズムを実装し、 検索者が興味のあるコンテンツを⾒つけるためにクラスタ情報が 有⽤であることを確認する • 下記のネットワークに対しlouvain法を適⽤し、クラスタ情報を⽣成する • フォロー関係 •

    視聴関係 • 検索システムの規模(2018年4⽉2⽇) • 約1500万件の動画を検索対象として保持している • フォロー関係、視聴関係のネットワークの規模 ネットワークの種類 ノード数 エッジ数 フォロー関係 9,194,596 109,471,657 視聴関係 3,047,813 48,378,044 ユーザの7日分の視聴履歴について、最後まで動画を視聴した履歴のみを抽出し、 動画の視聴者と動画の投稿者の関係にマッピング
  37. 評価実験 • CGMサイトであるニコニコ動画に提案アルゴリズムを実装し、 検索者が興味のあるコンテンツを⾒つけるためにクラスタ情報が 有⽤であることを確認する • 下記のネットワークに対しlouvain法を適⽤し、クラスタ情報を⽣成する • フォロー関係 •

    視聴関係 • 検索システムの規模(2018年4⽉2⽇) • 約1500万件の動画を検索対象として保持している • フォロー関係、視聴関係のネットワークの規模 ネットワークの種類 ノード数 エッジ数 フォロー関係 9,194,596 109,471,657 視聴関係 3,047,813 48,378,044
  38. 評価実験の⽅法(2) • クラスタ間類似度の重みの値を0.1から0.3まで変えていく • ユーザに本アルゴリズムを利⽤した検索機能を利⽤してもらい、 重みの値が⼤きい時と⼩さい時のクリック率を⽐較する • 検索者が興味を持っているコンテンツを探すときに、 クラスタ間類似度の指標が役に⽴っているかどうかを確かめる =

    9 :単語関連度スコア + , :再生数スコア + - :コンテンツ鮮度スコア + ; :コメント鮮度スコア + < :フォロー関係クラスタ間類似度 + = :視聴関係クラスタ間類似度 • 本検索機能を利用してもらうユーザには、本ソート順が検索者の 視聴履歴を反映したものになっていることを案内している • 重みを0.0にするパターンについては、検索者に提示される動画の 傾向が明らかに検索者の視聴傾向を反映しないものとなり、機能が 壊れているようにも見えてしまうため、試行していない
  39. • フォロー関係クラスタ間類似度の重み< 、視聴関係クラスタ間類似度の重み = を0.1から0.3まで変えたときのクリック率を⽰す • 各重みパターンの間のクリック率に差があるどうかをRyan法よる多重⽐較で 確かめる 視聴関係クラスタ間類似度 0.1

    0.2 0.3 フォロー関係 クラスタ間類似度 0.1 41.6 (36,808) 43.2** (37,978) 42.0 (38,327) 0.2 42.1 (38,856) 42.1 (38,999) 43.3** (38,433) 0.3 42.4 (38,093) 43.4** (37,876) 42.7 (37,728) 評価実験の結果(1)
  40. • フォロー関係クラスタ間類似度の重み< 、視聴関係クラスタ間類似度の重み = を0.1から0.3まで変えたときのクリック率を⽰す • 各重みパターンの間のクリック率に差があるどうかをRyan法よる多重⽐較で 確かめる 視聴関係クラスタ間類似度 0.1

    0.2 0.3 フォロー関係 クラスタ間類似度 0.1 41.6 (36,808) 43.2** (37,978) 42.0 (38,327) 0.2 42.1 (38,856) 42.1 (38,999) 43.3** (38,433) 0.3 42.4 (38,093) 43.4** (37,876) 42.7 (37,728) 評価実験の結果(1) • 各類似度による指標の重みの値を0.1より大きくした パターンのクリック率が向上している • 視聴関係クラスタ間類似度、フォロー関係クラスタ間類 似度の指標が、検索者が見たいと感じるような動画を 探すときに役立っていると考えられる
  41. おわりに • 下記について説明した • niconicoのコンテンツ検索システムの概要 • Elasticsearchを⽤いたタグベースの動画ランキングの実現 • SNSの機能を持つCGMサイトにおけるコンテンツ検索を対象とした、 パーソナライズドソーシャルサーチのアルゴリズム

    • パーソナライズドサーチに関してはまだ改善の余地がある • ランキング学習でスコアリング式の重みパラメータの調整 • node2vecなどのgraph embeddingの⼿法で算出するノードの ベクトル間の距離をスコアリングに利⽤する⽅式なども⽐較検討