AWS
Elasticsearch
kibana
検索エンジン
AmazonElasticsearchService

[AWS]Amazon Elasticsearch Serviceでよく使うコマンド集(Amazon ES/Elasticsearch)

Amazon Elasticsearch Serviceとは?

Elasticsearchとは、分散処理マルチテナント対応検索エンジンです。(全文検索)
データを蓄積するだけではなく、そのデータに属性や情報を持たせ、
高度で柔軟性の高い検索や分析が行えます。
 #Elasticsearchが溜め込んでいる情報を、KibanaなどのBIツールで表示させます。

もともとは自サーバやAWS EC2など、サーバを立てる必要がありましたが、
そこを上手いこと、まるっと良しなにAWSが行ってくれるわけです。

基本的にはAWSコンソールをポチポチしていけば、簡単に構築することが出来ます。
 #しかもKibanaも併せて立ててくれるんですね

でもでも、こんなことも思うわけです

Amazon Elasticsearch Serviceは使いやすい
だがしかし!かゆいところに手が届かない(プラグイン入らないし
一体なんのmanagedなのか。。。

言いたいことを言えばボロボロ出てきますが。

まぁ、それでも使っちゃうんですけどね。

ElasticsearchAPIをcurlで叩いてみよう

私自身、Amazon ESで作業を行う際は、AWSコンソールからはモニタリングを使うくらいで、
あとは全てcurlでデータの取得/登録/更新/削除を行っていました。
実践レベルで使用する頻度が高いAPIがあったので、まとめたいと思います。

以下、凡例となります。
ドメイン名やindex名などは環境ごと読み替えてください。

{ドメイン}: https://から始まるドメイン名、AWSコンソール上のドメイン.エンドポイント
例:`https://search-xxx.amazonaws.com`
{index}: ドメイン.インデックス名(.kibanaなどもインデックスにあたる)
例:twitter  .kibana  など

:bangbang:注意点:bangbang:

Ver5.xまでは、ヘッダーのContent-Typeapplication/jsonとして自動認識していたが、
Ver6.xからは書かなければなりません(CRUDのうち、CUD)
もしヘッダーをつけなければこのようなエラーが帰ってきます

{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}

私自身、Amazon ESのドメインのバージョンをVer5.xVer6.xも両方使うため、
下記のコマンド集は一律-H "Content-Type: application/json"を外しています。

クラスタ/その他

クラスタのヘルスチェック

$ curl -XPUT '{ドメイン}/_cluster/health?pretty'

Shardの状態を確認

$ curl -XGET '{ドメイン}/_cat/shards?pretty'

field-dataを確認

field-dataとは・・・
各fieldのデータをメモリ上に載せ、検索を高速化している。
この時、field-dataはcacheを伴い、cacheが溜まり過ぎるとOutOfMemoryErrorが発生することがある。
利用するメモリのサイズ調整ができるが、体感だHEAP_Sizeの70〜75%で運用していた。

$ curl -XGET '{ドメイン}/_stats/fielddata?pretty'

field-dataの解放

$ curl -XPOST '{ドメイン}/_cache/clear' -d '
{
  "fielddata": "true"
}'

手動スナップショット取得/復元(リストア)

手動スナップショット取得

$ curl -XPUT '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}'

手動スナップショット一覧取得

$ curl -XGET '{ドメイン}/{S3のスナップショット保存ディレクトリ}/_all?pretty'

復元(全てを復元)

$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore'

特定のindexのみ復元

$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore' -d '
{
  "indices": "{index}"
}'
$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore' -d '
{
  "indices": [ "{index}", "{index}", "{index}" ]
}'

検索(search)

range検索

$ curl -XGET '{ドメイン}/{index}/_search' -d '
{
  "query": {
    "range": {
      "timestamp": {
        "lte": "2017-06-30"
      }
    }
  }
}'

term検索

$ curl -XGET '{ドメイン}/{index}/_search' -d '
{
  "query": {
    "term": {
      "_type": "xxxx"
    }
  }
}'

index関連

index作成

下記例だと、index作成時にプライマリシャードとレプリカシャードの数を指定

$ curl -XPUT '{ドメイン}/{index}' -d '
{
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    }
  }
}'

特定のindexを削除

$ curl -XDELETE '{ドメイン}/{index}'

indexのsettingsを変更する

下記の例だと、対象indexのread-onlyを外す

$ curl -XPUT '{ドメイン}/{index}/_settings' -d '
{
  "index.blocks.write": true
}'

indexごとの設定取得

$ curl -XGET '{ドメイン}/{index}/_settings'

index内のドキュメントカウントを取得

$ curl -XGET '{ドメイン}/{index}/_count'

既存のindexから別のindexに値をコピー

もともとあるindexから別indexに生まれ変わらせる作業が発生することがある
そのとき非常に役に立つ
 #ドキュメントの取得が遅いなど、1つのindexが肥大化してshardが足りていないケースなど
  その場合、indexを分けてあげることで、shard数を増やしたりする
 #query部分も_searchと同様に書けるため便利

下記の例だと、
元ソースのindexの2017-06-01 00:00:00から2017-06-01 23:59:59のドキュメントを
ドキュメントをコピーしたいindexにコピーする
何度も書いてますが、あくまでコピーです

$ curl -XPOST '{ドメイン}/_reindex' -d '
{
  "source": {
    "index": {元ソースのindex},
    "query": {
      "range": {
        "timestamp": {
           "gte": "2017-06-01" 
           "lte": "2017-06-30"
        }
      }
    }
  },
  "dest": {
    "index": {ドキュメントを`コピー`したいindex}
  }
}'

感想

使い方次第で顔面蒼白です
気を付けてください