Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
OpenSearchでレガシーな検索処理の大幅改善をやってやろう
Search
DPon
April 12, 2025
Technology
2
280
OpenSearchでレガシーな検索処理の大幅改善をやってやろう
DPon
April 12, 2025
Tweet
Share
More Decks by DPon
See All by DPon
つよつよな人の理解の早さを理解する
dznbk
0
57
テスト書きたいけど 書けてないのは 何でなんだぜ
dznbk
0
120
php-fpmのプロセスをコントロールする
dznbk
0
6
Other Decks in Technology
See All in Technology
生成AIで小説を書くためにプロンプトの制約や原則について学ぶ / prompt-engineering-for-ai-fiction
nwiizo
3
820
Welcome to the LLM Club
koic
0
160
変化する開発、進化する体系時代に適応するソフトウェアエンジニアの知識と考え方(JaSST'25 Kansai)
mizunori
1
210
初めてのAzure FunctionsをClaude Codeで作ってみた / My first Azure Functions using Claude Code
hideakiaoyagi
1
210
Clineを含めたAIエージェントを 大規模組織に導入し、投資対効果を考える / Introducing AI agents into your organization
i35_267
4
1.5k
Snowflake Summit 2025 データエンジニアリング関連新機能紹介 / Snowflake Summit 2025 What's New about Data Engineering
tiltmax3
0
300
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
26k
Fabric + Databricks 2025.6 の最新情報ピックアップ
ryomaru0825
1
130
Postman AI エージェントビルダー最新情報
nagix
0
100
製造業からパッケージ製品まで、あらゆる領域をカバー!生成AIを利用したテストシナリオ生成 / 20250627 Suguru Ishii
shift_evolve
PRO
1
130
How Community Opened Global Doors
hiroramos4
PRO
1
110
Node-REDのFunctionノードでMCPサーバーの実装を試してみた / Node-RED × MCP 勉強会 vol.1
you
PRO
0
110
Featured
See All Featured
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Building Applications with DynamoDB
mza
95
6.5k
KATA
mclloyd
29
14k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.8k
A Tale of Four Properties
chriscoyier
160
23k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
48
2.8k
Stop Working from a Prison Cell
hatefulcrawdad
270
20k
Large-scale JavaScript Application Architecture
addyosmani
512
110k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
700
Statistics for Hackers
jakevdp
799
220k
A Modern Web Designer's Workflow
chriscoyier
694
190k
Transcript
OpenSearchでレガシーな検索処理の 大幅改善をやってやろう PHPカンファレンス小田原2025
自己紹介 • 堂薗 伸樹(どうぞの のぶき) / DPon(@DPontaro) ◦ 園 薗 •
職業:エンジニア • 所属:スターフェスティバル株式会社 • 家族:妻 子👦👦 犬 • ゲーム好き • 大阪からきました • 🎉 カンファレンス初登壇 🎉
会社とサービスの話 • https://gochikuru.com/ • 法人・団体向けの宅配弁当 ケータリング・オードブルの デリバリーサービス。
前段 プロジェクトの説明
プロジェクトの特徴 • ごちクルとは別の特定業界向けのお弁当デリバリーサービス • Initial Commitは2015年 • コロナ禍で需要減。リソース都合もあり、しばらく専任のエンジニアがついていない 状態。 •
ときどき改善依頼があった際、手が空いてる人がスポットでアサインされる
パフォーマンスの課題 • 2024年春、サイトのパフォーマンスは少し触れただけでも体感できるくらいに悪い • 需要が戻りつつあるなか、マイナスの印象を与えるわけにもいかない
レガシーな環境
初手の改善
ボトルネックをみつける 商品検索のController。 リクエストされる頻度高く、かつ重い ページ。 中央値が 1.9 sec これに加え、ページ表示までに画像や cssのダウンロードなども発生する
初手の改善 スロークエリに手を入れてみる • INDEXの追加 • 該当箇所のコードを調整し、発行されるクエリを修正 結果200msec くらいは改善したが焼け石に水。
さてどうしたものか 長年専任がついていないプロジェクト、コードはツギハギで無駄も多い。 複雑に絡み合ったコードの解消のために、検索ロジック全体を組み直す必要がありそ う。 → それならもう OpenSearch に移行してもいいのでは?
OpenSearchとは • 分散型の検索エンジン。Elasticsearchのフォーク版 • クラスタ構成、複数のノードにデータ分散。 • 高速な全文検索が可能
簡単に用語解説:Document • Document:データを格納する単位。JSON形式。 ◦ 学生のデータベースでは、 Documentは1人の学生を表せる ◦ RDBにおける行に相当
簡単に用語解説:Index • Index:Documentの集まり ◦ RDBでいうテーブル ◦ 学生のデータベースでは、 Indexはすべての学生を表す
簡単に用語解説:Clusterとか • Cluster, Node ◦ Clusterは、Nodeの集まり。 ◦ Nodeはデータを保存、検索リクエストを処理 するサーバ。 •
Shard ◦ いわゆる水平分割。 ◦ Indexのdocumentを行単位でシャード分割し て分散 ◦ シャードの分割目安:シャードのサイズを 10 ~ 50 GB に制限することです。(公式いわく)
OpenSearchへの移行
OpenSearch公式のPHPクライアント まぁバージョン下げたら対応してるやつあるやろ。 https://github.com/opensearch-project/opensearch-php
おっかしいなー
真面目にどうするか 理想はPHPのバージョンアップ。そうはいっても • スポット的なアサインでもあり、メインは別プロジェクトの人員 • 元のミッションはパフォーマンス改善。 →バージョンアップはスコープ外では? • 認知負荷の高いコードの理解、スロークエリの対応など既にある程度時間もかけて いる。
→このタイミングからバージョンアップまでやる? ※言わずもがなテストはメンテされておらず
戦略的後回し // TODO PHPバージョンアップ 結局公式のPHP7.3が対応してるバージョンのクライアントを落としてから、7.1で動くよう にエラーが出る箇所をつぶして対応させました。 ※バージョンアップはパフォーマンス改善後に対応しました(7.4までですけど...
バッチの実装 毎時 RDS -> OpenSearch へデータ投入するバッチを実行。 その際”YYYYMMDD-HH”のサフィックスを持つINDEXが作成される。 例:product-index-20250412-15 INDEX作成後、アプリケーションが参照している OpenSearchのINDEXのエイリアスを変更。
実行前:product_index -> product-index-20250412-14 実行後:product_index -> product-index-20250412-15
マッピングの話 マッピングはOpenSearchに、ドキュメントとそのフィールドの保存方法とインデックスを指示します。 各フィールドのデータ型を指定することで (例えば、年を日付にするなど )、保存やクエリをより効率的に行うこと ができます。 Dynamic mapping (動的マッピング) 新しいデータやフィールドが自動的に追加される。
Explicit mapping (明示的マッピング) 推奨。正確な構造とデータ型を前もって定義できる。 パフォーマンスや正確性を高めることができる
マッピング一例 "id": map[string]string{"type": "integer"}, "product_name": map[string]interface{}{ "type": "text", "analyzer": "product_index_analyzer",
"search_analyzer": "product_search_analyzer", },
analyze 文字列を検索に使えるように「分かち書き(トークン化)」&「正規化」する処理
analyzer と search_analyzer "product_name": map[string]interface{}{ "type": "text", "analyzer": "product_index_analyzer", "search_analyzer":
"product_search_analyzer", }, analyzer:インデックス時(保存時)に使用する analyzer を指定。 search_analyzer:検索時に使用する analyzer を指定
synonym_filter search_analyzer には上記のsynonym_filterという同義語の設定がされている。 この設定により曖昧検索に対応できる "synonym_filter": map[string]interface{}{ "type": "synonym", "synonyms": []string{
"ウナギ,ウナジュウ", "子供,お子様",
やってみてどうだった
🎉結果発表🎉 before 中央値:1.9sec after 中央値:0.92sec
売上につながった? ここ1年で売上の数値はしっかり伸びている 🎉 複数要因があるものではありますが、パフォーマンス改善で下支えが出来た ※余談 社内の営業の方々から直接 DMでめちゃ助かったと何人か声かけていただいて、好感触
他改善するなら • 毎時のバッチ実行 ◦ 日々商品のデータは更新されているが、最大 1時間の遅延を許容している状態 ◦ よりリアルタイムに更新したい場合、イベント駆動な仕組みを取り入れたり • インフラのあいのり
◦ ごちクルと同じインスタンスなので障害発生した際は、どちらも検索処理が機能しなくなる(今のとこ ろ発生はしていない) ◦ 切り離せば懸念はなくなるが、コスト増にはなるのでバランス考えて • synonym_filterなどがコード中に定義されている ◦ 変更の際にエンジニアの手が入る状態となっているので、できれば外部ファイルに逃がしたほうが 良い