はじめに
本稿では私の所属するビジネス・ブレークスルー社の受講者に対するお知らせの配信基盤にMeilisearch取り込んだことについて書きます。
アジェンダ
- 移行前のシステムと課題
- 改善の計画
- 移行後のシステム
- まとめ
移行前のシステムと課題
移行前のシステムです。
SQLServerで管理されたお知らせ配信情報の一覧をAPIで返したり、公開時刻になったお知らせをメールやプッシュ通知で通知する仕組みです。
上記お知らせマスタの数は3万件以上。配信対象のユーザー数は40万件以上となっていました。
単純な取得処理であれば問題ない規模なのですが、弊社のシステムではユーザーの属性毎にパーソナライズされており、APIで実行するクエリは複雑になっていました。
クエリが複雑化したせいで、配信対象の多いユーザーと少ないユーザーでSQLServerが作る実行プラン切り替わり、APIの応答が突如遅くなる現象が起きていました。
改善の計画
最初は遅くなったクエリを分析したり外部のDBAに見てもらったりしながら小さく変更を行っていましたが、あまり改善効果はありませんでした。
それとは全く関係のない話題で時雨堂さんがMeilisearchの紹介をしていて、このプロダクトは面白いねという話をしたりしていました。
https://zenn.dev/voluntas/scraps/77ae77d06deadc
そこで「お知らせの配信をMeilisearch使ったらどうなるんだろうか」と思い、プロトタイプを書き始めました。
移行後のシステム
SQLServerとMeilisearchの同期は2種類に分けて書きました。
- インデックスから全て作り直す処理(Lambdaで実行する)
- リアルタイムに同期する処理(マスタを更新する管理画面で同期する)
プロトタイプ当初はMeilisearchから取得したお知らせの情報をさらにPythonでフィルタするという非効率な実装でした。
チームメンバーからのフィードバックもあり、Meilisearchにユーザー属性情報を予めタグとして登録することで一度の問い合わせで検索できるようにしました。
結果、APIのレイテンシーは安定して0.3〜0.8秒になりました。
この仕組みだとおそらくSQLServerだけでも十分対策できたと思います。
しかし弊社のお知らせはキーワード検索も対応しており、Meilisearch採用できたおかげで今後の改善に活かすことができると考えています。
まとめ
パーソナライズされた情報を全文検索でどうやって返すか、という課題に対してMeilisearchのドキュメントに検索する属性を予め登録しておき、問い合わせるユーザーの属性を付加して検索することで解決できました。
複雑なクエリを削除することができ、安定したレスポンスが返せるようになってホッとしています。