ヤマムギ

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 クラウドプラクティショナー」という本を書きました。

【PR】 「AWSではじめるLinux入門ガイド」という本を書きました。

 - AWS , ,

ad

ad

  関連記事

AWS Lambda(Python3.7)でPandocを実行する

昨日まで(AWS Batch) 昨日までは、Pandocを実行して、S3バケット …

Rocket.ChatにAPIで投稿するテスト(Postman)

トレーニング期間中で一時利用するチャットが欲しいなあと思い、Rocket.Cha …

AWS CloudFormationでAmazon DynamoDBテーブルを作ってアイテムを追加する

デモ用にDynamoDBテーブルを作って消して、ということをたまにするので、Cl …

CUSTOMINEを使ってkintoneからAWS Lambdaを実行する(Cognito認証付き)

先日の記事「kintoneのカスタマイズ開発を超速にするCUSTOMINE」で書 …

WordPress W3 Total Cache のDatabaseCacheをAmazon ElastiCacheのmemcachedに格納する

このブログのアーキテクチャは現在こちらです。 データベースは、Amazon Au …

AWS複数アカウントのリソースをLambda(Python)から一括操作したくて

AWSの複数アカウント(30ちょい)のリソースをまとめて自動処理したくて。 とり …

AWS EC2 インスタンスステータスのチェックで失敗 原因はPHP-FPMのOOM-KILLER

先週に引き続きEC2のインスタンスステータスチェックで失敗 再起動するも失敗する …

Amazon Aurora Serverlessを使い始めてみました(1日経過しての課金結果も)

祝!!! Amazon Aurora ServerlessがGAになりました! …

TwilioからのリクエストをAPI Gateway+LambdaでTwimlを返して処理する

Twilioで着信した時のリクエスト先としてTwimlをWebサーバやS3で用意 …

Cloud9でSAMローカルテスト

せっかくテストするので、Amazon CloudSearchからAmazon E …