全体アーキテクチャ
インターネットのデータ規模が爆発的に成長するにつれ、現在主流のEコマースプラットフォームでは、商品量やカテゴリーが増加する一方で、ユーザーが必要な商品を見つけるのが難しくなっています。
Vipshopは、中国の大手ブランドオンラインディスカウント小売業者である。Vipshopは、中国全土の消費者に、高品質で人気のあるブランド商品を小売価格より大幅にディスカウントして提供している。顧客のショッピング体験を最適化するために、同社はユーザーのクエリーキーワードとユーザーのポートレートに基づいてパーソナライズされた検索レコメンデーションシステムを構築することを決定した。
電子商取引検索推薦システムの中核機能は、多数の商品から適切な商品を検索し、ユーザーの検索意図と好みに応じて表示することである。その際、商品とユーザーの検索意図・嗜好の類似度を計算し、類似度の高いTopK商品をユーザーに推薦する必要がある。
商品情報、ユーザーの検索意図、ユーザーの嗜好などのデータはすべて非構造化データである。このようなデータの類似度を検索エンジンElasticsearch(ES)のCosineSimilarity(7.x)を用いて計算しようとしたが、この方法には以下の欠点がある。
計算応答時間が長い - 数百万のアイテムからTopKの結果を取得する平均待ち時間は約300ミリ秒である。
ESインデックスのメンテナンスコストが高い - 商品特徴ベクトルとその他の関連データの両方に同じインデックスセットが使用されるため、インデックス構築がほとんど容易にならないが、大量のデータが生成される。
我々は、ESのCosineSimilarity計算を高速化するために、独自のローカルセンシティブハッシュプラグインの開発を試みた。その結果、性能とスループットは大幅に改善されましたが、100ミリ秒以上の待ち時間が発生し、実際のオンライン商品検索の要件を満たすことは困難でした。
徹底的な調査の結果、一般的に使用されているスタンドアロンのFaissと比較して、分散デプロイのサポート、多言語SDK、読み取り/書き込み分離などの利点があるオープンソースのベクトルデータベースであるMilvusを使用することにしました。
様々なディープラーニングモデルを用いて、膨大な非構造化データを特徴ベクトルに変換し、Milvusにインポートします。Milvusの優れた性能により、我々の電子商取引検索推薦システムは、ターゲットベクトルに類似するTopKベクトルを効率的に照会することができる。
全体アーキテクチャ
 図に示すように、システム全体のアーキテクチャは主に2つの部分から構成されている。
書き込み処理:ディープラーニングモデルが生成した項目特徴ベクトル(以下、項目ベクトル)を正規化し、MySQLに書き込む。その後、MySQLはデータ同期ツール(ETL)を用いて処理された項目特徴ベクトルを読み込み、ベクトルデータベースmilvusにインポートする。
読み込み処理:検索サービスは、ユーザークエリキーワードとユーザポートレイトに基づいて、ユーザ嗜好特徴ベクトル(以下、ユーザベクトル)を取得し、Milvusの類似ベクトルを照会し、TopKアイテムベクトルを呼び出す。
Milvusはデータの増分更新と全体更新の両方に対応している。各インクリメンタルアップデートは既存のアイテムベクトルを削除し、新しいアイテムベクトルを挿入する必要がある。この方が、読み込みが多く書き込みが少ないシナリオに適している。したがって、データ全体の更新方法を選択する。さらに、複数のパーティションのバッチでデータ全体を書き込むのにかかる時間はわずか数分であり、これはほぼリアルタイムの更新に相当する。
Milvusの書き込みノードは、データコレクションの作成、インデックスの構築、ベクターの挿入など、すべての書き込み操作を実行し、書き込みドメイン名でサービスを提供する。Milvusの読み込みノードは、すべての読み込み操作を実行し、読み込み専用のドメイン名で一般にサービスを提供する。
Milvusの現在のバージョンはコレクションのエイリアスの切り替えをサポートしていませんが、Redisを導入することで、複数のデータコレクション全体のエイリアスをシームレスに切り替えることができます。
読み取りノードは、MySQL、Milvus、GlusterFS分散ファイルシステムから既存のメタデータ情報とベクトルデータまたはインデックスを読み取るだけでよいため、複数のインスタンスを配置することで読み取り機能を水平方向に拡張することができる。
実装の詳細
データ更新
データ更新サービスでは、ベクタデータの書き込みだけでなく、ベクタのデータ量検出、インデックス構築、インデックスプリロード、エイリアス制御などを行う。全体の流れは以下の通り。 プロセス
データ全体を構築する前に、CollectionA がデータサービスを公開し、利用中のデータ全体が CollectionA(
redis key1 = CollectionA
)に向けられているとする。データ全体を構築する目的は、新しいコレクション CollectionB を作成することである。商品データチェック - MySQLテーブルの商品データの品目番号をチェックし、CollectionAの既存データと比較する。アラートは数量またはパーセンテージで設定できます。設定数量(パーセント)に達しない場合、データ全体が構築されず、構築失敗とみなされアラートが発生します。設定数量(パーセント)に達すると、データ全体の構築が開始されます。
データ全体の構築を開始 - 構築中のデータ全体のエイリアスを初期化し、Redisを更新する。更新後、構築中のデータ全体のエイリアスをCollectionB (
redis key2 = CollectionB
) に向ける。新しいコレクション全体を作成します。存在する場合は、新しいものを作成する前に削除する。
データ一括書き込み - modulo演算を使用して、各商品データのパーティションIDを独自のIDで計算し、複数のパーティションにデータを新規作成コレクションに一括で書き込みます。
インデックスの構築とプリロード - 新しいコレクションのインデックス(
createIndex()
)を作成します。インデックスファイルは分散ストレージサーバGlusterFSに格納される。システムは自動的に新しいコレクションに対するクエリをシミュレートし、クエリのウォームアップのためにインデックスをプリロードします。コレクション・データ・チェック - 新しいコレクションのデータのアイテム数をチェックし、既存のコレクションとデータを比較し、数量とパーセンテージに基づいてアラームを設定します。設定された数(パーセンテージ)に達していない場合、コレクションは切り替わらず、構築プロセスは失敗とみなされ、アラートがトリガされます。
コレクションの切り替え - エイリアス制御。Redisの更新後、使用中のデータエイリアス全体がCollectionB (
redis key1 = CollectionB
)に向けられ、元のRedisキー2が削除され、構築プロセスが完了します。
データの呼び出し
Milvusのパーティションデータを数回呼び出し、ユーザークエリキーワードとユーザポートレイトから得られるユーザベクトルとアイテムベクトルの類似度を計算し、マージ後のTopKアイテムベクトルを返す。全体的なワークフローの概略は以下の通りである。 ワークフロー 以下の表は、このプロセスに関わる主なサービスの一覧である。TopKベクトルを呼び出す平均待ち時間は約30ミリ秒であることがわかる。
サービス | 役割 | 入力パラメータ | 出力パラメータ | 応答待ち時間 |
---|---|---|---|---|
ユーザー・ベクトル取得 | ユーザーベクトル取得 | ユーザー情報+クエリー | ユーザーベクトル | 10ミリ秒 |
Milvus検索 | ベクトルの類似度を計算し、TopKの結果を返す | ユーザベクトル | アイテムベクトル | 10ミリ秒 |
スケジューリングロジック | 結果の同時呼び出しとマージ | 多チャンネルで呼び出されたアイテムベクトルと類似度スコア | TopKアイテム | 10ミリ秒 |
実装プロセス
- ユーザークエリキーワードとユーザポートレイトに基づき、ディープラーニングモデルによってユーザベクトルが計算される。
- RedisのcurrentInUseKeyRefから利用中のデータ全体のコレクションエイリアスを取得し、Milvus CollectionNameを取得する。この処理はデータ同期サービスであり、データ全体の更新後にエイリアスをRedisに切り替える。
- Milvusは同じコレクション内の異なるパーティションからデータを取得するために、ユーザベクトルと同時・非同期に呼び出され、Milvusはユーザベクトルとアイテムベクトルの類似度を計算し、各パーティションのTopK個の類似アイテムベクトルを返す。
- 各パーティションから返されたTopKアイテムベクトルをマージし、IP内積(ベクトル間の距離が大きいほど、より類似している)を使用して計算される類似性の距離の逆順に結果をランク付けします。最終的なTopKアイテム・ベクトルが返されます。
今後の展望
現時点では、Milvusベースのベクトル探索は、推薦シナリオの探索に安定して利用でき、その高い性能から、モデルの次元数やアルゴリズムの選択に遊びの余地がある。
Milvusは、メインサイト検索の想起やオールシナリオ推薦など、より多くのシナリオのミドルウェアとして重要な役割を果たすだろう。
今後Milvusに期待される機能は以下の3つである。
- コレクションエイリアス切り替えロジック - 外部コンポーネントなしでコレクション間の切り替えを調整する。
- フィルタリングメカニズム - Milvus v0.11.0はスタンドアロンバージョンでES DSLフィルタリングメカニズムのみをサポートしています。新しくリリースされたMilvus 2.0はスカラーフィルタリングと読み書き分離をサポートしています。
- Hadoop Distributed File System (HDFS)のストレージサポート - Milvus v0.10.6ではPOSIXファイルインターフェースしかサポートしておらず、ストレージバックエンドとしてFUSEをサポートしたGlusterFSを導入しています。しかし、パフォーマンスとスケーリングのしやすさという点ではHDFSの方が優れています。
教訓とベストプラクティス
- 読み取り操作が主な焦点であるアプリケーションの場合、読み取りと書き込みを分離するデプロイメントにより、処理能力を大幅に向上させ、パフォーマンスを改善することができる。
- Recallサービスで使用されるMilvusクライアントはメモリ上に常駐しているため、Milvus Javaクライアントには再接続メカニズムがありません。ハートビート・テストによりJavaクライアントとサーバー間の接続の可用性を確保するため、独自の接続プールを構築しなければならない。
- Milvusでは遅いクエリが時々発生する。これは新しいコレクションのウォームアップが不十分なためです。新しいコレクションに対するクエリをシミュレートすることにより、インデックスファイルがメモリにロードされ、インデックスのウォームアップが達成されます。
- nlistはインデックス構築パラメータで、nprobeはクエリパラメータです。検索性能と精度のバランスをとるために、圧力テスト実験を通してビジネスシナリオに応じた妥当な閾値を得る必要があります。
- 静的データシナリオの場合、最初にすべてのデータをコレクションにインポートし、後でインデックスを構築する方が効率的です。
- 実装の詳細
- 今後の展望
- 教訓とベストプラクティス
On This Page
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word