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
D-PONTARO
April 12, 2025
Technology
2
250
OpenSearchでレガシーな検索処理の大幅改善をやってやろう
D-PONTARO
April 12, 2025
Tweet
Share
More Decks by D-PONTARO
See All by D-PONTARO
テスト書きたいけど 書けてないのは 何でなんだぜ
dznbk
0
110
php-fpmのプロセスをコントロールする
dznbk
0
5
Other Decks in Technology
See All in Technology
AIエージェントのオブザーバビリティについて
yunosukey
1
410
20250514 1Passwordを使い倒す道場 vol.1
east_takumi
0
160
Kaigi Effect 2025 #rubykaigi2025_after
sue445
0
380
Docker Compose で手軽に手元環境を実現する / Simplifying Local Environments with Docker Compose #CinemaDeLT
nabeo
0
280
インフラからSREへ
mirakui
20
7.8k
TypeScriptで実践するクリーンアーキテクチャ ― WebからもCLIからも使えるアプリ設計 / CClean Architecture with Typescript Application
panda_program
8
1.5k
4月15日の AZ 障害をテクサポの中の人目線で振り返ってみる
kazzpapa3
3
190
UIパフォーマンス最適化: AIを活用して100倍の速度向上を実現した事例
kinocoboy2
1
680
Lakehouse в Лемана Тех. От архитектуры до оптимизации
emeremyanina1234
0
470
Why every SwiftUI developer should care about the Environment - iOSKonf25
peterfriese
0
160
本番環境への影響リスクが低い Real Application Testing (SQL Performance Analyzer) の実施方法の検討と実践
jri_narita
0
230
AWS_MCP_Servers入門.pdf
naotoiso
0
200
Featured
See All Featured
How to Ace a Technical Interview
jacobian
276
23k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
24
2.8k
Raft: Consensus for Rubyists
vanstee
137
6.9k
Writing Fast Ruby
sferik
628
61k
Making Projects Easy
brettharned
116
6.2k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
430
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
5
590
Optimising Largest Contentful Paint
csswizardry
37
3.2k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
YesSQL, Process and Tooling at Scale
rocio
172
14k
Art, The Web, and Tiny UX
lynnandtonic
298
21k
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などがコード中に定義されている ◦ 変更の際にエンジニアの手が入る状態となっているので、できれば外部ファイルに逃がしたほうが 良い