LoginSignup
1
0

More than 1 year has passed since last update.

退役コーダーおじさん、Elasticserchをお勉強:1(Elasticserch環境構築編)

Posted at

まったくElasticserchを触ったことがない状態で構築から色々とやって行きます。ほぼ個人の備忘録です。

実行環境

  • 前提条件

    • Elasticに関する理解度
    • 検証方法
      • Dockerとdocker-composeで再利用可能な環境構築を目指す。
      • Elasticserchの基本の「キ」もわかってないので、先ずは動く環境を手に入れてから、あーだこうだヤリたいと思う。
      • なるべく公式HPの情報をもとに手順検証する。
        • 書籍は発行されたタイミングの情報に閉じている為、誤記入の訂正も最新のトレンドに対応出来てないケースが過去に多々あったので。
  • HW

    • MacBook Pro(2018)
      • CPU:2.9GHz 6core
      • MEM:32GB(Dockerに4GB割り当て) 1
      • HDD:物理
  • SW

    • MacOS Monterey(12.0.1)
    • Docker desktop(3.0.3)
      • Engin: 20.10.0
      • Compose: 1.27.4
    • elasticserch 7.16.3
  • その他、bashでのコマンドalias設定 2

    • d: docker
    • dc: docker-compose

環境構築

  • ユーザーのHomeディレクトリに「elasticserch」ディレクトリを作成しそこで検証開始。
  • 公式サイトのこのページ(Install Elasticsearch with Docker)でdocker-compose.yamlをコピペして、上記elasticserchディレクトリ配下に取得。
  • とりあえずコマンドdocker-compose up実行でコンテナ立ち上げてみたが失敗。。。
    • 問題点
      • es01が起動しない
        • 解決方法: portsの記述にクォート囲みがなかったので修正。
      • contenarが母艦側ディレクトリをmountする「volumes」パラメータ設定が絶対パスとなっている。
        • 解決方法: elasticserchディレクトリ配下に閉じたいので修正。
  • 以下、上述の問題点を修正してcontener起動が可能となったdocker-compose.yaml
version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.16.3
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      # data01->./data01に修正
      - ./data01:/usr/share/elasticsearch/data
    ports:
      # 公式コピペだとここが原因でなぜか起動しなかった(MAC環境独自の問題?原因不明)、クォート囲みに修正
      - "9200:9200"
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.16.3
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      # 修正箇所
      - ./data02:/usr/share/elasticsearch/data
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.16.3
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      # 修正箇所
      - ./data03:/usr/share/elasticsearch/data
    networks:
      - elastic

# ここの表記は要否不明(別途調査)
volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

で、上記修正後に再度docker-compose up -dコマンドでelasticserchをバックグラウンド起動。

❯❯❯ dc up -d
Creating network "elasticserch_elastic" with driver "bridge"
Creating es03 ... done
Creating es02 ... done
Creating es01 ... done

コンテナを立ち上げたら一応docker psコマンドでコンテナが適切に起動したか確認。

❯❯❯ d ps
CONTAINER ID   IMAGE                                                  COMMAND                  CREATED              STATUS              PORTS                              NAMES
47aa9219c2cc   docker.elastic.co/elasticsearch/elasticsearch:7.16.3   "/bin/tini -- /usr/l…"   About a minute ago   Up About a minute   9200/tcp, 9300/tcp                 es02
80202c1c86c7   docker.elastic.co/elasticsearch/elasticsearch:7.16.3   "/bin/tini -- /usr/l…"   About a minute ago   Up About a minute   0.0.0.0:9200->9200/tcp, 9300/tcp   es01
b5b324cb5a30   docker.elastic.co/elasticsearch/elasticsearch:7.16.3   "/bin/tini -- /usr/l…"   About a minute ago   Up About a minute   9200/tcp, 9300/tcp                 es03

起動後に公式チュートリアルのコマンド(_cat/nodeにリクエストを送信してノードが起動している事を確認)を実行。

~/elasticserch
❯❯❯ curl -X GET "localhost:9200/_cat/nodes?v=true&pretty"
ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
172.19.0.2           32          97   0    0.08    0.08     0.06 cdfhilmrstw -      es03
172.19.0.4           27          97   0    0.08    0.08     0.06 cdfhilmrstw *      es02
172.19.0.3           46          97   0    0.08    0.08     0.06 cdfhilmrstw -      es01

とりあえず、無事環境構築できた様子なので、Quick startページのサンプル「Add a single documentedit(単一のドキュメントを追加する)」を実行してみます。以下、ページの説明文をGoogle翻訳に掛けた物を引用

 logs-my_app-default次のインデックス作成リクエストを送信して、データストリームに単一のログエントリを追加し ます。logs-my_app-default存在しないため、リクエストは組み込みのインデックステンプレートを使用して自動的に作成しますlogs--

よくわからんがindexっていうのがRDBMSで言うところのテーブルらしい。で、document(RDBMSでのレコードと思われる)を追加対象となるindexが存在しない場合には自動で作成してくれる様子っぽいです。この辺はjsonベースなのでmongodbと同じなのかな?POSTデータを送信するcurlコマンドをコピペ実行してみる。

❯❯❯ curl -X POST "localhost:9200/logs-my_app-default/_doc?pretty" -H 'Content-Type: application/json' -d'
{
  "@timestamp": "2099-05-06T16:21:15.000Z",
  "event": {
    "original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
  }
}
'

尚、Quick startページではKibanaを使用して実行との記載があったが方法がわからないので別途調査。。。
参考までに上記curlコマンドをKibanaというGUIのツールで実行する場合、少し目に優しい構文でできるような記載でした。

# kibanaでのサンプル。HTTPメソッドと対象となるindex(/_docはお約束なのかな?)にINSERTする実データで良いらしい。
POST logs-my_app-default/_doc
{
  "@timestamp": "2099-05-06T16:21:15.000Z",
  "event": {
    "original": "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
  }
}

上記curlコマンドのレスポンス値。

# curlコマンドの戻り値
{
  "_index" : ".ds-logs-my_app-default-2022.02.04-000001",
  "_type" : "_doc",
  "_id" : "npmIwn4BrcdMpf7_-mmB",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

戻り値をざっと確認してみると"successful"の値が1で、"failed"の値は0。この2つのパラメーターの値はゼロイチでTrue/Falseを表現しているらしく結果として成功っぽい。なにやら"index"の値(テーブル名にあたる部分)として生成された名称はds-logs-my_app-default-2022.02.04-000001となってます。で、idが発番されたらしい。その他"version"等もあるので更新履歴なのか、はたまた楽観ロックで使うのかは別途調査が必要ですが、とりあえずはデータ挿入成功です。
お次、このdocumentを表示する方法は?こちらもQuick StartページのSearch dataをコピペ実行してみる。

❯❯❯ curl -X GET "localhost:9200/logs-my_app-default/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": { }
  },
  "sort": [
    {
      "@timestamp": "desc"
    }
  ]
}
'

どうやらURIの第一ディレクティブに検索対象のindexを指定するらしい。以降第二ディレクティブで指定している'_search'はRESTfulの第一ディレクティブで指定したindexへのアクションの指定で_searchが検索アクションらしい。アクション名以降にクエストリンクとして渡している'pretty'は必須値ではないがJSON戻り値に成形オプション有効化を指してます(省略すると整形されない状態で戻る)。で、-dオプションで渡しているgetでのパラメータ。こちらもJSON形式でキー名称"query"で渡している値(ネストされた連想配列)のキー"match_all"の値(これも連想配列)に何も指定しないことにより、全てのdocumentを引っ張ってきているっぽい(訂正:defaultで10件指定で取得しているらしいです。SQLだとLimit/offset句が適用された状態かと)。で、キー名称"sort"の値が配列で複数のソート条件を渡せるっぽいね。これらを親の顔より見て慣れ親しんだSQLのDMLで書くとこんな感じだろうか。

SELECT * from `logs-my_app-default` LIMIT 10 OFFSET 0 order by `@timestamp` desc;

で、上記curlコマンド実行結果のレスポンス値

{
  "took" : 26,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [
      {
        "_index" : ".ds-logs-my_app-default-2022.02.04-000001",
        "_type" : "_doc",
        "_id" : "npmIwn4BrcdMpf7_-mmB",
        "_score" : null,
        "_source" : {
          "@timestamp" : "2099-05-06T16:21:15.000Z",
          "event" : {
            "original" : "192.0.2.42 - - [06/May/2099:16:21:15 +0000] \"GET /images/bg.jpg HTTP/1.0\" 200 24736"
          }
        },
        "sort" : [
          4081767675000
        ]
      }
    ]
  }
}

ステータスやhits件数等もデータ内に含まれている。RESTfulなWebAPIだとデータに付随する情報はHeaderにX-tortal-countLink等で持たせろとかWebAPI設計のベストプラクティスで紹介されていた気がするが、httpベースでの用途だけではないから良いのかな?で、データは連想配列第一階層の'hits'Objectの中に同名称'hits'配列があり、この配列内にElasticserchのdocument毎にObjectとして格納される形かな?なんとなくJSONレスポンスの設計をSwaggerに貼ったら設計上良くない作りだと指摘されそうな構成ですが、まぁなんとなくレスポンス内容は掴めました。

一応複数データ挿入もサンプルがあったので実行。endpointのアクション名は'_balk'で、改行で区切られたJSON(NDJSON)というらしい。各データの終端記号は(\n)で、最後の行を含め(\n)終わる必要がありとの事。

curl -X PUT "localhost:9200/logs-my_app-default/_bulk?pretty" -H 'Content-Type: application/json' -d'
{ "create": { } }
{ "@timestamp": "2099-05-07T16:24:32.000Z", "event": { "original": "192.0.2.242 - - [07/May/2020:16:24:32 -0500] \"GET /images/hm_nbg.jpg HTTP/1.0\" 304 0" } }
{ "create": { } }
{ "@timestamp": "2099-05-08T16:25:42.000Z", "event": { "original": "192.0.2.255 - - [08/May/2099:16:25:42 +0000] \"GET /favicon.ico HTTP/1.0\" 200 3638" } }
'

(上記複数データ挿入の戻り値は省略してますが、無事に成功しております。)

とりあえず、アプリケーション起動とデータ単一挿入、複数挿入、データ抽出まで簡単に検証できたので今回はここまで。

  1. memory容量が足りないとes01/es02/es03とクラスター起動する筈のコンテナが一部起動しない事象が発生したのでデフォ値から少し増やしました。

  2. 説明文上では短縮表記でない正式なコマンドで記載しますが、コマンド実行結果は上記aliasのまま貼り付けを行うケースがある為、適宜読み替え要です。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0