Slide 1

Slide 1 text

AWSのマネージドサービスで実現する ニアリアルタイムな検索基盤 2022/10/08 JAWS DAYS 2022 Masataka Kashiwagi

Slide 2

Slide 2 text

自己紹介 名前:柏木 正隆(Masataka Kashiwagi) 所属:コネヒト株式会社 - 機械学習エンジニア 出身:大阪府 お仕事 ● レコメンドエンジンの開発 ● 検索システムの開発 ● MLOpsの推進 好きなAWSサービス ● Amazon SageMaker ● AWS Step Functions Twitter 友人とPodcastやってます @asteriam_fp @double_m2ml

Slide 3

Slide 3 text

会社とサービスの紹介

Slide 4

Slide 4 text

「コネヒトの事業」について 「あなたの家族像が実現できる社会をつくる」 というVISIONに基づく中期的な目標として 子どもを望む家族像の多様性を実現するために日々取り組んでいます

Slide 5

Slide 5 text

「mamari」について “悩み” と ”共感” を軸にママに寄り添う toC向けサービス アプリ・Web・SNSと多角的にサービスを展開しています

Slide 6

Slide 6 text

アジェンダ ☑ 自己紹介 ☑ コネヒトの会社・サービス紹介 □ ニアリアルタイムな検索基盤 ● ママリで扱う「Q&Aデータ」とは? ● 検索システムのアーキテクチャ ● AWS Glueで実現するデータ同期とは? ● OpenSearchのインデックス管理 ● データ同期パイプライン ● AWS SAMを使ったワークフロー/パイプラインのコード管理 □ まとめ

Slide 7

Slide 7 text

本日話さないこと ● 検索システム内製化プロジェクトの発足した背景 ● 精度改善の取り組み(検索体験の向上) ● AWSの各種サービスの細かい設定方法 この発表で得られること ※ 本資料は後ほど公開します!! ● AWSのマネージドサービスを活用した検索基盤の構築方法 ○ 検索エンジンのOpenSearchをどう使うか ○ Step Functionsを活用したデータパイプラインの構築

Slide 8

Slide 8 text

ママリで扱う「Q&Aデータ」とは?

Slide 9

Slide 9 text

どんな性質の「Q&Aデータ」か? Q&A画面のイメージ図 検索画面のイメージ図 ママリ→ママのためのQ&Aコミュニティアプリ ● 特徴:子育ての不安・悩みに関するデータ ● 月間で約130万件以上あるQ&Aデータ ○ 1つ以上回答がある質問の割合は95%以上 ○ 最初の回答がつくまでの時間は2~3分程度 ■ 新しい質問・回答が高頻度で投稿され ていく

Slide 10

Slide 10 text

検索できるようにするためには...?

Slide 11

Slide 11 text

検索システムのアーキテクチャ

Slide 12

Slide 12 text

検索システムのアーキテクチャ ※ 橙色の点線の部分をメインにお話します 実線矢印:データの流れ 点線矢印:処理の流れ

Slide 13

Slide 13 text

検索システムのアーキテクチャ コネヒトでは全面的にAWSのマネージドサービスを採用 ● 検索基盤は以下の構成 ○ 検索エンジン:Amazon OpenSearch Service ○ データベース:Amazon Aurora ○ データ同期(ETL):AWS Glue ○ ワークフロー・パイプライン:AWS Step Functions ○ コード管理:AWS Serverless Application Model(AWS SAM)

Slide 14

Slide 14 text

検索エンジン - OpenSearchとは? OpenSearchは,Elasticsearchから派生したオープンソースの検索エンジン ● AWSでは “ver.1.3” までサポートしている ○ ML Commons pluginのサポート(機械学習モデルの学習ができる) ○ Observabilityアプリの作成(システム状況を1ヶ所で確認することができる) ○ etc… ● OSS:最新版=ver.2.3.0(OpenSearch and Dashboards 2.3.0 Release Notes) 随時機能アップデートが入っているので, 今後のメジャーバージョンアップのサポートに期待! Ref. 1. OpenSearch and Dashboards 1.3.0 Release Notes 2. Amazon OpenSearch Service now supports OpenSearch version 1.3

Slide 15

Slide 15 text

なぜAmazon OpenSearch Serviceを選択したか ● Elasticsearchクラスタの運用は考慮ポイントが多く,独自で運用したくなかった ○ チーム人数が少ないため,マネージドサービスが使えると嬉しい ● 日本語全文検索のKuromojiプラグインに対応していた ○ (Sudachiにも対応してほしい) ● VPC内に置くことができる ● 他のAWSサービスとの親和性 ○ Glue(データ同期)やStep Functions(パイプライン)との連携可能 Ref. 1. Operational best practices for Amazon OpenSearch Service

Slide 16

Slide 16 text

AWS Glueで実現するデータ同期とは?

Slide 17

Slide 17 text

AWS Glueの使いどころ 全量データと差分データ同期パイプラインでAuroraからOpenSearchへQ&Aデータを流す 処理としてAWS Glueを使っています

Slide 18

Slide 18 text

データ同期 - AWS Glueとは? ● サーバーレスなETLマネージドサービス ○ 様々なデータソースからターゲットソースに向けてデータ連携が可能 ● バックエンドでSparkが動いているので,高速なデータ処理が可能 ● Glue Studioという新しいUIがあり,直感的にジョブ設定が可能 ○ 個人的にめっちゃ使いやすいです! Glueの使用イメージ Glue StudioのUI

Slide 19

Slide 19 text

AWS Glueを選択した理由 ● 柔軟なデータ抽出が可能か ○ 今回の必須要件である「差分抽出」の実装が容易で可能か ○ 今後要件として出てくる「複数テーブル」を組み合わせたデータ抽出・同期が可能か ○ SQLやPythonで処理を実装することが可能か(実装コスト面) ● エラー発生時のリカバリーが容易か ○ 再実行が容易に可能か ○ 各種メトリクスを取ることができるか

Slide 20

Slide 20 text

AWS Glueを選択した理由 ● 柔軟なデータ抽出が可能か ○ 今回の必須要件である「差分抽出」の実装が容易で可能か ■ Custom CodeでSQLを記述することで可能 ○ 今後要件として出てくる「複数テーブル」を組み合わせたデータ抽出・同期が可能か ■ 組み込みの変換処理・フィルター処理で実装可能 ○ SQLやPythonで処理を実装することが可能か ■ ETL Scriptsで自由に実装可能 ● エラー発生時のリカバリーが容易か ○ 再実行が容易に可能か ■ コンソール,Step Functionsのアクションも用意されているため可能 ○ 各種メトリクスを取ることが可能か ■ APIを使ってジョブ実行時間を取得することも可能

Slide 21

Slide 21 text

いくつかある要件を満たすものとして, 現状最適なAWS Glueを選択!

Slide 22

Slide 22 text

データ同期の流れ Glueを使った流れは以下の通り 1. データベースからデータをクロールする 2. クロールしたらデータカタログにメタデータを管理する 3. データカタログのメタデータを元にデータソースからデータを抽出する 4. ジョブを実行してターゲットにデータを同期する ① ② ③ ④ Glue Jobの設定 Data Catalog Data Integration and ETL

Slide 23

Slide 23 text

Glue Jobの設定 ● Glue Studioを使ってジョブを作成 & 設定 ○ 全量と差分の2つのデータ同期ジョブ ○ データソースとターゲットを決めるだけ ● データソース ○ Data Catalog(Aurora) ○ 接続方法:JDBC接続 ● ターゲットソース ○ Elasticsearch Connector(OpenSearch) ○ 接続方法:JDBC接続

Slide 24

Slide 24 text

全量と差分2つのデータ同期処理 ● 全量データの同期処理 ○ 頻度:数日に1回 ○ 目的: ■ 差分データ同期処理で取り逃がしたデータを拾う ■ バックアップ ○ 特定のテーブルの全データを対象に総入れ替え(洗い替え)を行っている ● 差分データの同期処理 ○ 頻度:数分に1回 ○ 目的:ニアリアルタイムな検索を可能にするため ○ 直近で更新があったレコードを対象にDBからデータを同期する

Slide 25

Slide 25 text

差分データ同期処理を実現する方法 大きく2つ考えられる 1. SQSなどのキューイングシステムを介して処理する方法 2. 定期的に実行されるバッチ処理による方法 ● 今回はマネージドサービスを活用して,検索基盤側でデータの登録および更新の責任 を持つようにしたかった ○ SQLで差分データを抽出→OpenSearchへデータ同期 ○ AWS Glueならこの辺りの処理はお手の物 ■ 「定期的に実行されるバッチ処理による方法」を選択

Slide 26

Slide 26 text

差分データ同期処理 SparkSQLによるクエリ処理で対応 ● 抽出条件 ○ 現在時刻から直近X分前のデータを抽出 ● SparkSQLの実行 ○ 「modified」という時刻カラムに対して クエリを発行し,SparkSQLを実行 ● 変換処理 ○ SparkのDataFrameをAWS Glue独自の DynamicFrameに変換する処理

Slide 27

Slide 27 text

ニアリアルタイムな同期を実現するために ● GlueのJob bookmarkというオプション機能を活用 ○ ジョブの実行状態を保持する機能 ○ 処理済みデータを再度処理しないようになる ○ 重複処理や重複データを防ぐことができる ● ジョブの実行時間が劇的に早くなります! Ref. 1. Tracking processed data using job bookmarks GlueのJob bookmarkオプション機能 引用)AWS Black Belt Online Seminar - AWS Glue

Slide 28

Slide 28 text

Job bookmarkオプション機能でハマったところ ● 予想以上に処理時間がかかった(初歩的な勘違い) ○ 1回目のジョブ実行時はブックマークを作ることになるので,通常の実行になる ○ 学び:dry-run的な形で一度動かしておく必要がある ● KeysとKeysSortOrderの設定 ○ additional_optionsのKeysSortOrderをdescにすると意図した通りに上手く動かない → OpenSearchへのUpsertが効いていないことが発覚! ○ 学び:タイムスタンプのように昇順で増加する場合,ascで指定する必要がある

Slide 29

Slide 29 text

Job bookmark機能とWorker数の調整で ニアリアルタイムなデータ同期が実現可能に!🎉

Slide 30

Slide 30 text

では,データ同期に伴う検索エンジンの インデックスの仕組みはどうするか?

Slide 31

Slide 31 text

OpenSearchのインデックス管理

Slide 32

Slide 32 text

インデックスとは? ● データを検索エンジンで検索するためには,“index” の作成が必要 ○ An index is like a ‘database' in a relational database. It has a mapping which defines multiple types. ○ An index is a collection of documents that are related to each other. ● インデックス化は,検索エンジンが高速に検索できるよう にデータを整理する方法 Ref. 1. What is an Elasticsearch Index? 2. What is Elasticsearch?

Slide 33

Slide 33 text

インデックス管理 ● 2つのインデックスを用意し,その上段にエイリアスを置く方法でOpenSearch のインデックスを管理 ○ なぜ2つ用意するのか? ■ 全量データの同期中はインデックスが使えず検索できなくなるので, 全く同じものをもう一つ用意しておく必要がある ● エイリアスを置く理由 ○ アプリケーション側で接続先を毎回変更する必要がない データ洗い替え時に削除してか ら新規でインデックスを作成

Slide 34

Slide 34 text

なぜインデックスの作り替えを毎回実施しているのか ● OpenSearchのReindex APIを使わず,インデックスの削除→新規作成を実施 ○ 数日に1回の全量データ洗い替え作業 ● 洗い替え作業 ○ データの漏れや欠損が発生していた場合の補完(保険的な役割) ■ その時点での最新データを全て検索エンジンに投入する ○ 不要なドキュメントを削除してインデックスをスリムにする → Reindex APIは既存のインデックスのコピーなので,それだけだと不十分!

Slide 35

Slide 35 text

インデックスの切り替えフローの紹介 ● 前提: ○ indexAとindexBの2つ用意 ○ エイリアスはindexBを向いている(エイリアス→indexB) ○ 差分データの更新がindexBでアクティブで,indexAはスタンバイ状態 AWS Glueによるデータ同期 最新のデータ エイリアスの向き先が indexBからindexAに変更 ● 上記のインデックスの切り替えフローをindex-Aとindex-Bで交互に行う ● これをAWS Step Functionsでパイプラインに落とし込んで実装

Slide 36

Slide 36 text

定期的にインデックスを切り替えるために パイプラインへ組み込む✈

Slide 37

Slide 37 text

データ同期パイプライン

Slide 38

Slide 38 text

ワークフローとパイプラインの役割 ● ワークフローとパイプライン2つ用意 ワークフロー パイプライン

Slide 39

Slide 39 text

ワークフローの役割 ● “パイプラインの制御” ○ 前述の2つのインデックスに対して,どちらのデー タ同期パイプラインを実行するかを制御する役割 ● “運用を意識した存在” ○ EventBridgeによるスケジュール実行の対象を 集約できる ○ 現状のエイリアスの向き先を意識せずにこのワーク フローを実行するだけでインデックスの作成と切り 替えができる 2つのインデックスに対 応したパイプライン

Slide 40

Slide 40 text

パイプラインの役割 ● ワークフロー内にあるデータ同期処理の実態 ● 処理内容 ○ 辞書更新 ■ ユーザー辞書 ■ シノニム辞書 ○ 全量データの同期処理 ■ インデックスの削除 ■ エイリアスの切り替え ■ 差分データ同期処理の有効化 / 無効化

Slide 41

Slide 41 text

なぜワークフローとパイプラインで分けるのか? ● “オペレーション” ○ エラー時の再実行や手動実行を行うことが想定されたので,運用を考えると, 特に実行者が意識する設定(2つあるインデックスのうちどちらを実行すればいいか など)を減らしたかった ● “設定したいスケジュールをEventBridgeで行えなかった(クリティカルな課題)” ○ 要件:2つあるインデックスを数日おきに交互に実行したい ○ 解決策:スケジュール設定をワークフローに対して1つ設定する ■ 現在どのインデックスに対してエイリアスが接続しているかのチェックと, その後のどちらのパイプラインを流せば良いかを判断できる (ワークフロー側で判断)

Slide 42

Slide 42 text

全量データ同期パイプラインの詳細 ● 2つのセクションがある ○ 辞書更新パート ○ データ同期パート

Slide 43

Slide 43 text

辞書更新パート

Slide 44

Slide 44 text

辞書更新への対応 ● なぜパイプラインに組み込んだのか? ○ より良い検索を可能にするためには,辞書の整備が必要になってくる! ■ 定期的に発生する辞書更新を自動化したい→パイプラインに組み込む ○ OpenSearchへの辞書反映はインデックスが作られたタイミングのみ 1. インデックス新規作成時 2. インデックスオープン時 Ref. 1. 辞書の更新についての注意点 データの洗い替え時にはインデックスを新規で再作成している ので,そこに組み込むのがベスト!

Slide 45

Slide 45 text

辞書更新の流れ ● パイプラインでの辞書更新の流れは以下の通り 1. S3に置いてある辞書ファイルの更新有無をLambdaでチェック ○ 有:辞書更新へ,無:辞書更新の処理をスキップ 2. カスタムパッケージ(辞書ファイル)の更新 ○ ユーザー辞書 ○ シノニム辞書 3. OpenSearchへ辞書ファイルの関連付け 4. インデックスを新規で再作成 ○ Lambdaでインデックスの削除 ○ Glueによるデータ同期時にインデックスの作成 Ref. 1. Custom packages for Amazon OpenSearch Service

Slide 46

Slide 46 text

データ同期パート

Slide 47

Slide 47 text

データ同期の流れ ● 「インデックスの切り替えフロー」で紹介した処理をStep Functionsのアクションで 置き換えている 1. インデックスの削除(LambdaからOpenSearchのdelete APIを叩く) 2. Glueによる全量データ同期処理 3. スタンバイ状態の差分データ同期パイプラインの有効化(EventBridge) 4. インデックスの切替(LambdaからOpenSearchのaliases APIを叩く) ○ エイリアスの向き先を変更する 5. アクティブ状態の差分データ同期パイプラインの無効化(EventBridge)

Slide 48

Slide 48 text

インデックスの切り替え ● Blue/Greenデプロイ ○ 動いているインデックスの更新 󰢃 ○ 新しいインデックスへのデータ投入完了後に, エイリアスの向き先を変更 󰢏 ■ 安全なデプロイが実行できている ● このインデックスの切り替え方法は,通称ペンギ ン本の「8.5.1 インデクサの更新」の章でも書か れている Ref. 1. 検索システム-実務者のための開発改善ガイドブック

Slide 49

Slide 49 text

データパイプラインの再利用を可能に, 素早く構築するためにコードを管理しよう💪

Slide 50

Slide 50 text

AWS SAMを使った ワークフロー/パイプラインのコード管理

Slide 51

Slide 51 text

AWS SAMによるパイプラインのコード管理 ● AWS SAMとは,AWS Serverless Application Model (AWS SAM) といい,サーバレスなAWSリ ソースを管理するツール ○ サーバレスに特化したCloudFormation ○ 今回使用したリソースは全てコード管理可能 ■ Lambda, Glue, Step Functions (SFn) ...etc ディレクトリ構成

Slide 52

Slide 52 text

Step Functionsのパイプライン作成 ● dev用のパイプラインをWorkflow Studioで作成 ● 問題なければ,JSONの定義ファイルをExportし,プロダクションにも適用できる ように環境による差分がある部分はパラメータ化し,template.yamlで管理

Slide 53

Slide 53 text

ワークフローのサンプルコード管理 Global変数は”Parameters”に記載 ワークフローのSFnの設定 ”Resources”に設定を記載 Lambda, Glue, SFnの設定 変数をパラメータ化 SFnの設定が書かれたJSON ● template.yamlの設定内容

Slide 54

Slide 54 text

コード管理の良いところ ● 設定した内容を別環境に簡単に適用することが可能 ○ ABテストを実施する際など,同一の環境をもう1セット用意する必要がある場合でも コード管理しておくこと,コマンド一発で環境を用意可能 ● コードレビューが可能になり,設定ミスや漏れなどに気づきやすい ○ 設定内容を透明化できる ○ git管理できる ● 環境依存部分をパラメータ化することで,template.yamlで管理切り替えが可能 ● リソースの後片付けも容易に ○ SAM or CloudFormationで作成すると,スタックというリソースの集合体で管理が できるので,削除する場合も一括で消すことができる

Slide 55

Slide 55 text

コード化することで,コマンド一発で 再現性ある環境構築が可能に🎉

Slide 56

Slide 56 text

まとめ ● AWSの各種サービスを上手く使って検索基盤を1から構築した! ○ 短期間で本番適用まで行けたのはAWSのマネージドサービスのおかげ ● ニアリアルタイムなデータ同期はかなりチャレンジング ○ GlueのJob bookmark機能 ● 検索基盤の構築方法 ○ OpenSearchを活用した検索システム ■ インデックスの切り替え / 運用方法 ○ Step Functionsを活用したデータパイプラインの構築 ■ ワークフロー/パイプラインの二段構成 ←オススメ😊 ○ 再利用のためのコード管理も忘れずに!

Slide 57

Slide 57 text

検索基盤が整備され, 検索体験 向上フェーズへ!

Slide 58

Slide 58 text

ニアリアルタイムで同期される検索基盤 ● 詳しくはテックブログを見て頂ければ! ○ https://tech.connehito.com/entry/2022/08/24/184911 ○ https://tech.connehito.com/entry/2022/09/16/165655

Slide 59

Slide 59 text

References URL ● https://github.com/opensearch-project/opensearch-build/blob/main/release-notes/opensearch-releas e-notes-1.3.0.md ● https://aws.amazon.com/jp/about-aws/whats-new/2022/07/amazon-opensearch-service-supports-ve rsion-1-3/ ● https://docs.aws.amazon.com/opensearch-service/latest/developerguide/bp.html ● https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html ● https://www.elastic.co/blog/what-is-an-elasticsearch-index ● https://www.elastic.co/what-is/elasticsearch ● https://blog.johtani.info/blog/2020/04/27/note-updating-dictionary/ ● https://docs.aws.amazon.com/opensearch-service/latest/developerguide/custom-packages.html ● https://www.lambdanote.com/products/ir-system

Slide 60

Slide 60 text

さいごに

Slide 61

Slide 61 text

We are hiring! 機械学習エンジニア絶賛募集中です!!! Wantedlyの募集ページに飛びます ・ライフイベント/ライフスタイルの課題解決をするサービスに興味がある方 ・データ基盤に関する意思決定や,MLプロダクト開発に興味のある方   もし興味を持たれましたら,まずはカジュアルにお話させてもらえると嬉しいです!   Twitter DM or Wantedly経由など...ご連絡お待ちしています!   Twitter: https://twitter.com/asteriam_fp   Wantedly: https://www.wantedly.com/companies/connehito/projects

Slide 62

Slide 62 text

おわり ご静聴ありがとうございました!