Azure AI Searchで挑む200万件の画像検索~PoCから本番化で解決したメモリ・コスト・運用設計の課題~
こんにちは、SuperDeliveryを開発しているエンジニアの齊藤初輝です。
SuperDeliveryは、メーカーと事業者が商品を取引するBtoB(企業間取引)の卸・仕入れができるECサイトです。
今回の記事は、Azure AIを活用した画像検索機能の開発についてです。
元々PoCで検証済みの構成を本番化した際に考慮したことについて共有します。
機能概要
ユーザーが商品画像をアップロードすると、見た目が似ている商品を自動で検索・表示する機能を開発しました。
この機能により、「この商品に似た商品が欲しい」というユーザーのニーズに応えることができます。

背景・課題認識
ECサイトでは「この商品に似た商品が欲しい」という顧客ニーズが頻繁にあります。従来のテキスト検索では、商品名や品番を正確に覚えていない顧客が類似商品を見つけることが困難でした。
特に弊社のSD exportという越境ECサービスでは、言語の壁を越えて視覚的に類似商品を検索できる機能へのニーズが確認されています。
主な機能
- 類似商品検索
- 商品画像のアップロードで、200万件の商品からの検索
- 最大120件の検索結果を類似度順で表示
- 日次バッチ
- 出品中商品情報と商品画像のベクトルデータをAzure AI Searchにインデックス登録
システム概要
技術スタック
- Azure AI Search + Azure AI Vision
類似商品検索フロー
[フロントエンド]
↓ 画像アップロード
[API]
↓ 画像解析リクエスト
[Azure AI Vision]
↓ 画像のベクトル化
[Azure AI Search]
↓ ベクトルスコアが近い、類似商品を検索
[検索結果レスポンス]
類似度順に検索結果を表示
バッチ処理フロー
[日次バッチ起動]
↓
[商品DB]
↓ 新規・更新商品を抽出(前日差分)
[バッチ処理]
↓ 1万件ずつ分割処理
[商品画像取得]
↓ 画像を300px以下にリサイズ
[Azure AI Vision]
↓ 画像をベクトル化(Base64エンコード)
[Azure AI Search]
↓ ベクトルデータをインデックス登録
[商品DB]
↓ インデックス登録状態を更新
[処理完了]
エラー時は通知
開発環境から本番環境への移行
移行時の課題と対応
PoCリポジトリから本番リポジトリへの移行にあたり、本番環境特有の要件に対応するため、システムの全面的な再実装を行いました。
PoCではPythonで開発していましたが、本番環境では既存システムとの統合を考慮し、検索機能はJava、バッチ処理はPHPで実装し直しました。この移植作業では、単なる言語変換ではなく、本番要件に応じたリファクタリングを実施し、Azure APIへのリクエスト処理を各言語で共通化することで、保守性と拡張性を向上させました。
品質担保と検証環境の構築
品質確保のため、テストコードを実装するとともに、本番環境に影響を与えない検証環境を構築しました。Azure AI Visionは従量課金のため、無料の検証環境を用意することでコストを抑えることができました。
バッチ処理では、処理する商品数を柔軟に指定できる仕組みを実装し、段階的な動作検証を可能にしました。これにより、少数の商品でテストを行った後、徐々に処理規模を拡大していく安全なデプロイメントが実現できました。
継続的な画像更新の仕組み
本番化にあたり、新規・更新される商品画像を継続的に処理するため、日次差分更新バッチを新たに開発しました。
画像の更新有無を判定し、変更があった商品のみベクトル化処理を実行することで、日次で商品画像の更新を検索に反映しています。
このバッチでは、商品のインデックス登録状態をデータベースで管理することで、処理時間の短縮と安定性を確保しています。また、出品終了や在庫切れ商品を自動的に除外するロジックを実装し、データベースとAzure AI Searchのインデックス間の整合性を維持しています。
本番化で気をつけたこと
1. バッチによる大量データの効率的なベクトル化処理
Azure AI Searchに初期データである200万件の商品データをインデックス登録する際に
いくつかパフォーマンスで考慮すべき事項がありました。
分割処理実装後も発生したメモリ問題
200万件の商品データを処理する際、一度にすべてのデータを取得するとメモリ不足によりバッチ処理が失敗することは当初から予測していました。そのため、適切なチャンクサイズで分割処理を実装していました。
しかし、分割処理を実装していたにもかかわらず、実際の運用では別の要因によるメモリ不足問題が発生しました。
調査の結果、PHPのZend Memory Manager(Zend MM)が再利用目的でメモリプールを確保し続ける動作が原因と判明しました。処理が進むにつれて追加メモリが確保されるものの、処理完了後も解放されず、階段状にメモリ使用量が累積し、最終的にシステムメモリを圧迫していました。
この問題への対策として、一定の分割処理完了時にバッチプロセスを再起動し、チェックポイントから処理を再開する方式を採用しました。これにより、メモリの累積を防ぎながら200万件全体の処理を安定して完遂できるようになりました。
Azure API呼び出し時の散発的タイムアウト
大量にAzure APIへリクエストすると、我々の環境では0.0004%程度の確率で散発的なタイムアウトエラーが発生することを確認しています。タイムアウト時間の延長や実行間隔の調整を試みましたが、完全な解消には至りませんでした。
PO(プロダクトオーナー)と協議した結果、発生率が極めて低いことから、ビジネスインパクトは限定的と判断しました。画像検索は補助的な検索機能としての位置づけであり、仮にタイムアウトエラーにより売れ筋商品が画像検索の対象から漏れた場合でも、既存のテキスト検索でカバー可能なため、現状の信頼性で十分という結論に至りました。
リトライ処理については、今回のリリースでは実装を見送り、運用開始後のエラー発生状況をモニタリングしながら、必要に応じて次フェーズでの対応を検討することとしました。
2. ユーザー向け画像検索機能の実装における工夫
画像検索機能では、ユーザーがアップロードした画像から類似商品を検索できます。アップロードされた画像はAzure AI Visionでベクトル化して処理しますが、従量課金制のため、以下のようなコスト制御とパフォーマンス最適化を実装しました。
アクセス制御によるコスト管理
ログイン済みユーザーのみに機能を限定しています。当社のBtoB向けECサイトでは会員登録時に審査を実施しており、この審査済み会員のみが画像検索を利用できる仕組みとしました。これにより、不正利用による予期しないコスト増加を防いでいます。
レートリミットの実装
インスタンス単位でリクエスト数を制限することで、Azure AI Vision APIの呼び出し回数を制御しています。これにより、短時間での大量リクエストを防ぎ、コストの予測可能性を確保しました。
レスポンス最適化
ユーザー体験を考慮し、非同期処理により複数ユーザーの同時利用を可能にしました。また、Azure API応答遅延に備えてタイムアウト設定を行い、ユーザーを無限に待機させることなく、適切にエラーハンドリングする仕組みを構築しています。
ベクトル検索アルゴリズムには、Azure AI Searchが提供するHNSW(Hierarchical Navigable Small World)を採用しました。200万件の大規模データセットに対して高速検索が可能で、PoC段階での検証でも検索精度・パフォーマンスともに要件を満たしていたため、本番環境でも同構成を継続しています。
HNSWのmパラメータ(各ノードの接続数)についても検証を行いました。mを増やすと検索精度は向上しますがインデックスサイズとクエリ時間が増加し、減らすと逆の傾向となります。検証の結果、PoC時の設定値で十分なバランスが取れていることを確認したため、変更せずに採用しています。
3. 設計判断と障害対応戦略
画像検索機能を本番運用するにあたり、障害復旧戦略について検討しました。
Azure AI Searchにはバックアップ・リストア機能の制約があるため、インデックス定義をGitで管理し、再現性を確保する方針を採用しました。障害発生時は、手動実行可能な再インデックスバッチで全件復旧が可能としました。
Blue-Green構成も検討しましたが、現時点でのビジネス規模を考慮し、単一環境での運用を選択しました。この判断により、運用コストを増加させることなく、許容可能な復旧時間内での対応を実現しています。画像検索は補助的な検索機能であるため、障害時はサービス復旧まで待機いただく運用方針をPO(プロダクトオーナー)と合意しました。
次に運用監視です。主要監視項目は以下です。
- 検索レイテンシ:3秒以内を目標値とし、レプリカ不足の早期発見に活用
- ストレージ容量:Azure管理画面で定期確認し、容量逼迫を未然防止
- バッチ処理状況:日次差分更新の成功/失敗を監視
Azure Monitorは追加コストを考慮して採用せず、既存の管理画面とアプリケーション側のメトリクスで十分な監視を実現しました。
可用性とスケーラビリティの設計
PoC時の利用者数とトラフィックパターンを分析し、本番環境ではレプリカを1台追加した2レプリカ構成としました。これにより、サービスの可用性を確保しながらコストを最小限に抑えています。
スケーリング戦略については、オートスケーリングを採用せず、監視メトリクスに基づく手動調整方式を選択しました。現時点では利用パターンが予測可能であり、急激な負荷変動が発生しないため、この方式で十分対応可能です。
商品数増加への対応についても、過去の増加傾向から将来需要を予測できるため、パーティション追加は必要なタイミングで計画的に実施する方針です。
この運用方針が成立する背景には、BtoB ECサイト特有の安定した利用パターンがあります。会員制かつ審査制のシステムであるため、利用者数の把握と予測がしやすく、急激なトラフィック増が発生しにくい特性があります。この予測可能性を活かすことで、過剰な冗長性を持たせることなく、ビジネス要件に最適化された効率的な運用を実現しています。
成果と学び
ビジネスインパクト
- 顧客体験向上 直感的な画像検索による商品発見の利便性向上
- 売上機会拡大 類似商品提案による追加購入の促進
技術的学び
- 大規模データ処理 メモリ管理システムの挙動を理解し、効率的なバッチ処理設計を行うことの重要性
- 外部API連携 タイムアウトとレートリミットによるリスク管理と安定性確保の必要性
- ベクトル検索 高次元データの類似度検索における精度とパフォーマンスの最適化ノウハウ
- コスト最適化 従量課金モデルにおける予算を意識したアーキテクチャ設計と運用の工夫
- 運用設計 障害発生を前提とした監視体制とビジネス影響を考慮した復旧戦略の構築
ドキュメント化とナレッジ共有
- 画像検索機能の技術仕様と運用手順をWikiにまとめ、開発組織内で共有
- 本テックブログでの知見公開により、社内外への技術ナレッジの展開
まとめ
Azure AI Searchを活用した画像検索機能を本番環境に導入しました。
本プロジェクトを通じて、AI技術を実務に積極的に活用し、従来のテキスト検索に加えて画像による検索という新たな価値を提供できました。ベクトル検索など、主流な検索技術を実装レベルで習得し、大規模かつ実用的な検索システムの構築ノウハウを蓄積することができました。
今後も運用データを基に継続的な改善を行い、ユーザー体験の向上を目指していきます。
ラクーンホールディングスでは、AI・検索技術に興味のあるエンジニアを募集しています!
採用情報はこちら






