CLOVER🍀

That was when it all began.

Elasticsearchでクラスタを構成してみる(Settings-based seed hosts provider利用)

これは、なにをしたくて書いたもの?

そういえば、Elasticsearchを使ってクラスタを組んだことがないなぁと思いまして。

1度、試しておこうかなと。

環境とお題

Elasticsearch 3台を、シンプルにデフォルトのSettings-based seed hosts providerを使ってクラスタを構成してみます。

OSとJavaのバージョンは、以下の通り。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic


$ java --version
openjdk 11.0.4 2019-07-16
OpenJDK Runtime Environment (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3)
OpenJDK 64-Bit Server VM (build 11.0.4+11-post-Ubuntu-1ubuntu218.04.3, mixed mode, sharing)

Elasticsearchは、7.4.2を使用します。

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.2-amd64.deb
$ sudo dpkg -i elasticsearch-7.4.2-amd64.deb

Elasticsearch 3台のIPアドレスは、192.168.33.11〜13として、ノード名はnode-1〜3にします。

また、ノードの種類は全台デフォルト(マスターノードであり、データノードでもある)とします。

Elasticsearchクラスタ

Elasticsearchでクラスタを構成するには、他のノードを見つけるところから始まります。これがDiscoveryです。

Discovery and cluster formation | Elasticsearch Reference [7.4] | Elastic

Discoveryでは、シードノードのアドレスリストと、マスターのアドレスリストが必要になります。シードノードのアドレスリストは、
Seed hosts providerで設定します。

Seed hosts providers

なお、マスターが決まらない場合、マスター検出プロセスの間隔は、「discovery.find_peers_interval」で指定するそうです(デフォルトで1秒)。

標準では2つのSeed hosts providerが提供されています。

その他のproviderは、プラグインとして提供されています。

Discovery Plugins | Elasticsearch Plugins and Integrations [7.4] | Elastic

今回は、Settings-based seed hosts providerを使用します。

クラスタを構成する

クラスタを構成するための設定は、以下のようにしました。

$ sudo grep -v '^#' /etc/elasticsearch/elasticsearch.yml
cluster.name: my-cluster
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
discovery.seed_hosts:
   - "192.168.33.11"
   - "192.168.33.12"
   - "192.168.33.13"
cluster.initial_master_nodes:
   - "192.168.33.11"
   - "192.168.33.12"
   - "192.168.33.13"

こちらは1台目のノードで、その他のノードは「node.name」をひとつずつずらしていくものとします。

ノード名を指定する、「cluster.initial_master_nodes」や「cluster.name」、「network.host」を指定する、などの注意は、
以下を参照。

Bootstrapping a cluster | Elasticsearch Reference [7.4] | Elastic

今回は、全ノードがマスターノードでもあり、データノードでもあるので、「cluster.initial_master_nodes」と「discovery.seed_hosts」は
同じノードを並べました。

では、各ノードのElasticsearchを起動。

$ sudo systemctl start elasticsearch

これらの設定をする前に、Elasticsearchを起動してはいけませせん(理由は後述)。

確認してみます。

$ curl localhost:9200/_cat/nodes?v
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
192.168.33.11            7          96   1    0.16    0.14     0.06 dilm      -      node-1
192.168.33.13           15          96   0    0.18    0.13     0.05 dilm      -      node-3
192.168.33.12            8          97   0    0.09    0.08     0.03 dilm      *      node-2

cat nodes API | Elasticsearch Reference [7.4] | Elastic

無事、クラスタが構成されました。マスターには、「node-2」が選出されたようです。

インデックスの作成、ドキュメントの登録をしてみる

では、Elasticsearchクラスタにインデックスを作成し、ドキュメントを登録してみましょう。各ノードに配置されるところを、
確認してみたいと思います。

お題は、書籍で。

まずは、インデックスを作成します。インデックス名は、「book」で。

$ curl -XPUT "localhost:9200/book" -H 'Content-Type: application/json' -d '{ "settings" : { "index" : { "number_of_shards" : 3, "number_of_replicas" : 2 } } }'
{"acknowledged":true,"shards_acknowledged":true,"index":"book"}

Create index API | Elasticsearch Reference [7.4] | Elastic

シャード数3、レプリカ数は2としました。

確認。

$ curl localhost:9200/book/_settings?pretty
{
  "book" : {
    "settings" : {
      "index" : {
        "creation_date" : "1574000648270",
        "number_of_shards" : "3",
        "number_of_replicas" : "2",
        "uuid" : "QOEwq8tTSueTNq5sND8q3Q",
        "version" : {
          "created" : "7040299"
        },
        "provided_name" : "book"
      }
    }
  }
}

データを10件入れます。

$ curl -X PUT "localhost:9200/book/_doc/978-1789803327" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789803327", "title": "Elasticsearch 7 Quick Start Guide: Get up and running with the distributed search and analytics capabilities of Elasticsearch", "price": 3590 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789957754" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789957754", "title": "Advanced Elasticsearch 7.0: A practical guide to designing, indexing, and querying advanced distributed search engines", "price": 5949 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789956504" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789956504", "title": "Elasticsearch 7.0 Cookbook: Over 100 recipes for fast, scalable, and reliable search for your enterprise, 4th Edition", "price": 5993 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789954395" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789954395", "title": "Learning Elastic Stack 7.0: Distributed search, analytics, and visualization using Elasticsearch, Logstash, Beats, and Kibana, 2nd Edition (English Edition)", "price": 4158 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1788837385" -H 'Content-Type: application/json' -d '{ "isbn": "978-1788837385", "title": "Mastering Apache Solr 7.x: An expert guide to advancing, optimizing, and scaling your enterprise search", "price": 4776 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1788997829" -H 'Content-Type: application/json' -d '{ "isbn": "978-1788997829", "title": "Apache Kafka Quick Start Guide: Leverage Apache Kafka 2.0 to simplify real-time data processing for distributed applications", "price": 3605 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789349108" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789349108", "title": "Apache Spark Quick Start Guide: Quickly learn the art of writing efficient big data applications with Apache Spark", "price": 3533 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789131499" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789131499", "title": "Mastering Apache Cassandra 3.x: An expert guide to improving database scalability and availability without compromising performance, 3rd Edition", "price": 4776 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1492034148" -H 'Content-Type: application/json' -d '{ "isbn": "978-1492034148", "title": "Prometheus: Up & Running: Infrastructure and Application Performance Monitoring", "price": 3950 }'
$ curl -X PUT "localhost:9200/book/_doc/978-1789612349" -H 'Content-Type: application/json' -d '{ "isbn": "978-1789612349", "title": "Hands-On Infrastructure Monitoring with Prometheus: Implement and scale queries, dashboards, and alerting across machines and containers", "price": 4158 }'

Index some documents | Elasticsearch Reference [7.4] | Elastic

Index API | Elasticsearch Reference [7.4] | Elastic

確認。

$ curl localhost:9200/_cat/shards/book?v
index shard prirep state   docs store ip            node
book  1     r      STARTED    0  230b 192.168.33.11 node-1
book  1     p      STARTED    4 6.8kb 192.168.33.12 node-2
book  1     r      STARTED    0  230b 192.168.33.13 node-3
book  2     r      STARTED    0  230b 192.168.33.11 node-1
book  2     r      STARTED    1   5kb 192.168.33.12 node-2
book  2     p      STARTED    0  230b 192.168.33.13 node-3
book  0     p      STARTED    0  230b 192.168.33.11 node-1
book  0     r      STARTED    0  230b 192.168.33.12 node-2
book  0     r      STARTED    5 7.6kb 192.168.33.13 node-3

cat shards API | Elasticsearch Reference [7.4] | Elastic

だいぶ偏ってますが、10件のドキュメントが各ノードに分散配置されたことが確認できました。

データが10件入っていることは、別の方法でも確認しておきましょう。

$ curl localhost:9200/book/_count?pretty
{
  "count" : 10,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  }
}

Count API | Elasticsearch Reference [7.4] | Elastic

OKそうですね。

注意点

ここまでに設定したような、クラスタに関する設定をしないままElasticsearchを起動してしまうと、開発モードで起動することになり、
各ノードでそれぞれクラスタを形成します。

If you start an Elasticsearch node without configuring these settings then it will start up in development mode and auto-bootstrap itself into a new cluster.

こうなってしまうと、後でクラスタをマージすることができないため、やり直しになります。

ドキュメントに書いている通り、必要ならバックアップを取得のうえ、各ノード上のElasticsearchを停止してデータを削除(「path.data」で
指定したディレクトリの中身)、それからクラスタ向けの設定をして再起動し、クラスタが構成されたことを確認します。

「path.data」は今回の構成でいくと「/var/lib/elasticsearch」ディレクトリなので、この中身を削除します。

そして、クラスタが構成された後にデータを復元する、という手順になるようです。