ヤマムギ

growing hard days.

*

Amazon CloudSearchからAmazon Elasticsearch Serviceへ変えました

   


全文検索をする必要がありまして、本当はCloudSearchを使い続けたいのですが、今は小規模なので低いインスタンスを使いたくて、Amazon Elasticsearch Serviceに変えました。
データ移行はしていません。
データはソース元から入れ直しました。
変えた理由とAWS Lambda Python3.7でそれぞれに対してデータの追加、更新、検索の違いを記録しておこうと思います。

何に使っているか

Alexaへのリクエストに対して、まずキーワードをマスターデータから全文検索しています。
その全文検索のために使用しています。

Amazon CloudSearchからAmazon Elasticsearch Serviceへ変えた理由

コストです。
アクセス数もまだまだ低いので最低限のコストにすることが目的です。

Amazon CloudSearchのコスト

2019年3月の課金結果です。
バージニア北部で一番低いsearch.m1.smallで$0.059 x 744時間で$43.9です。

Amazon Elasticsearch Serviceのコスト

2019年4月の途中からElasticsearch Serviceに変更したので途中経過です。
上記のCloudSearchと同じ期間条件にしてみると、
バージニア北部t2.smallで $0.036 x 744時間で$26.78ぐらいです。
それとEBSは10GBにしているのでその料金が、$0.135 x 10GBで$1.35です。
両方あわせて、$28.13が見込まれます。

可用性を考えるとノードを複数作って専用マスターノードも作ったりするべきで、それを考えるとCloudSearchの方がコストは低くなりそうなのですが、今回は可用性はおいといてとにかくコスト重視にしています。

Amazon Elasticsearch Service

とにかく作ってみました。
ちなみにCloudSearchはこちらの「Amazon CloudSearchにAWS Lambda(Python)からデータをアップロードする」に書いています。

[新しいドメインの作成]から作成しました。
リザーブドインスタンスもあるのですね。将来的には検討したいです。
今回はオンデマンドにします。

デプロイタイプはカスタムを選択しました。

ドメイン名を設定して、とにかくコスト重視で、1つのAZで1つのインスタンス、インスタンスタイプは最も低いt2.small.elasticsearch、専用マスターインスタンスはなしです。
ストレージはEBSです。
(t2.small.elasticsearchの場合はEBSのみでインスタンスストレージは選択できません。)
サイズは設定できる最小の10GBにしました。

特に隠す必要のないデータですので、ネットワークはパブリックにしました。

ドメインポリシーは次のポリシーにしました。

特定のIAMロールからのアクセスだけを許可しています。
このIAMロールはLambdaで使用するIAMロールです。
あらかじめ作っておきます。

これでAmazon Elasticsearch Service側の設定は完了です。

AWS LambdaでAmazon Elasticsearch Serviceを使う

参考にさせていただいたサイト
ありがとうございます!!

モジュール(requests-aws4auth, Elasticsearch Client)の準備

私はMacで作業しました。
pythonというディレクトリを作成して、そこにpipでインストールでしました。

pythonディレクトリごとzipにしました。

zipファイルをアップロードしてAWS Layersを作成しました。

AWS Lambdaの設定

作成したLayersを設定しておきます。
IAMロールは、Elasticsearch Serviceドメインにアクセス許可したIAMロールを設定しています。

アクセス権限はCloudWatch Logsへのログの書き込みと、このLambdaがDynamoDB StreamsトリガーなのでStreamを読める権限を与えています。
ElasticSearch Serviceへのデータの読み書きはAWSのAPIではなく、ElasticSearchクライアントからのアクセスになるので、IAMロールの権限には含めません。

環境変数

  • ENDPOINT
    Elasticsearch Serviceのエンドポイントを指定しました。

  • REGION
    Elasticsearch Serviceのリージョン。

  • TZ
    Asia/Tokyoを指定しました。

データを登録するAWS Lambdaのコード

IAMロールを設定することにより、環境変数にAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKENを取得できます。
これをAWS4Authに設定しまして、Elasticsearchクライアントを作成しました。

複数のインデックス作成なので、actionsの配列にインデックスを作成するアクションを追加していきます。
helpers.bulkで配列化したアクションを実行して複数のインデックスを作成しました。

‘_id’に一意となるキーを指定して、’name’が更新されたときにインデックスが更新できるようにしました。

全文検索するAWS Lambdaのコード

このAWS Lambdaは今はAPI Gatewayトリガーにしていてチャットボットからのリクエストに対応しています。
リクエストは’query’パラメータで受けています。
‘query’パラメータにはキーワードが与えられるのでそれで検索をしています。

例 : {‘query’: ‘aws’}

ここで作ったAPIに対してのチャットボットからのリクエストが例えば次のようなコードです。

Elasticsearch Serviceのレスポンスの[hits][total]に結果が何件あったかがありますので、結果があったかを判定して、[‘hits’][‘hits’][‘_source’]から値を取得できました。

[参考]CloudSearchで全文検索するAWS Lambdaのコード

CloudSearchでデータのアップロードをするコードは「Amazon CloudSearchにAWS Lambda(Python)からデータをアップロードする」に書いていますのでそちらをご参照ください。

CloudSearchで全文検索するコードは次のようなコードを使っていました。

チャットボットからのリクエストは次のようなコードです。
ElasticSearchと若干レスポンスが異なっています。


最後までお読みいただきましてありがとうございました!
【PR】 「AWS認定試験対策 AWS クラウドプラクティショナー」という本を書きました。

 - AWS , ,

ad

ad

  関連記事

AWS EC2 インスタンスステータスのチェックで失敗して起動しなくなり復旧

EC2のインスタンスに接続出来なくなったので、AMIから作成してElastic …

EC2とRDSのMySQLを他のAWSアカウントへ移設する

他のAWSアカウントへシステムごと移設した場合の手順です。 構成はEC2とRDS …

TuneCoreの売上データCSVをS3に格納してAthenaのクエリをRe:dashのデータソースにして可視化する

先日参加しましたAWS Summit Tokyo 2017で、 [JapanTa …

Amazon Linux にnodejsとmongoDBをインストールする

EPEL リポジトリを利用してnodejsとnpmをインストールする [cray …

よくあるサーバーレスアーキテクチャで質問フォーム

この記事はServerless2 Advent Calendar 2018に参加 …

AWS EC2 Amazon Linux にEC-CUBE3をnginx+MySql環境へインストール(手順検証中)

目次 EC2インスタンスを作成する各パッケージのインストールEC-CUBEインス …

slackのbotにWikipediaを調べてもらう(Python on AWS Lambda + API Gateway)

slackのbotに少しでも役に立ってもらおうと、Wikipediaを調べてもら …

AWS Lambda KMSを使って環境変数を暗号化、復号化する(Python)

Lambda内で外部APIを使用する場合などをユースケースとして、環境変数をKM …

Amazon Connectの新規作成からプッシュボタン入力と発信元電話番号をLambdaで処理するまで

とりあえずやりたいことはタイトルに書いたとおり、「電話をかけて、プッシュボタンに …

AWS BatchでPandocコンテナイメージを実行する

「ECR(Amazon Elastic Container Registry)に …