Elasticsearchに使うストレージを増やしたかったのですが、不安な点があったのでまとめました。
環境について
複数台で Elasticsearchのクラスターが組まれている環境で、1インデックスに複数のシャードが設定されている状態を想定しています。
また、レプリケーションは設定していませんが「データが消えると地味に痛い」環境で考えています。
その他の構成では結果が変わる可能性があります💦
新しいストレージを追加して data.path
に追加する方法
ストレージを追加する各マシンでElasticsearchを終了して、 ./config/elasticsearch.yml
の data.path
に追加する方法です。
data.path
を新しく追加しても、既存のインデックスやシャードは即座に新しい場所に再配置されません。 そのため、今のインデックスが巨大になってストレージを圧迫しているという状況には適しません。
- Elasticsearch multi data path disk full - Stack Overflow https://stackoverflow.com/questions/56523276/elasticsearch-multi-data-path-disk-full
何もしない場合、ストレージの使用率がwatermark( cluster.routing.allocation.disk.watermark.high
)を超えてはじめて別のノード(ストレージ)に移動されます。
ノードに向けての移動になるため「このストレージにそのシャードを移動したい」と狙って移動させることはできません。
Disk-based shard allocation
https://www.elastic.co/guide/en/elasticsearch/reference/current/disk-allocator.html
[2019-12-04T16:16:49,472][WARN ][o.e.c.r.a.DiskThresholdMonitor] [elasticsearch-node1] high disk watermark [90%] exceeded on [-LcqY8CedtSkufWq0ba28w][elasticsearch-node1][/mnt/elasticsearch/data/nodes/0] free: 8.4gb[8.4%], shards will be relocated away from this node
[2019-12-04T16:16:49,472][INFO ][o.e.c.r.a.DiskThresholdMonitor] [elasticsearch-node1] rerouting shards: [high disk watermark exceeded on one or more nodes]
また、elasticsearch increase storage
elasticsearch add data.path
などで調べても data.path
を追加してストレージが追加された例が乏しかったです。
- Elasticsearchを終了して
data.path
を追加すればいいと「思うよ」 https://discuss.elastic.co/t/adding-another-disk-to-an-es-node/10425 - Elasticsearchの
data.path
を追加したけど問題が起きなかったよ https://github.com/elastic/elasticsearch/issues/13210#issuecomment-136353406
古いバージョンでありますが data.path
を追加したことによる不具合の例が上がっています。
ノードの状態が RED のままになって使えなくなった https://stackoverflow.com/questions/33345002/elasticsearch-issue-when-adding-new-path-data
シャードが消失した(不具合だと考えている) https://github.com/elastic/elasticsearch/issues/13210
data.path
を追加するとどうなるか
localhostでシャード数が12のインデックスを作って試したところ 、 data.path
を追加しても状態が RED になることやデータの消失などはなく通常通り使えました。
(複数台用意しての検証はできていません)
次の環境を使い、以下の手順で確認できます。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G7024
$ curl "http://localhost:9200/"
{
"version" : {
"number" : "5.6.8",
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
1.path.data
となるディレクトリを3つ用意する
mkdir data1 data2 data3
2.elasticsearch.yml
の data.path
にディレクトリを2つ指定する
path.data: /path/to/data1,/path/to/data2
3.Elasticsearchを起動して、 適当にインデックスやドキュメントを追加してから 終了する。そして path.data
に data3
のディレクトリを追加する
path.data: /path/to/data1,/path/to/data2,/path/to/data3
再びElasticsearchを起動すると、上記のような「状態がREDのままになること」や「データが消失する」ということは起きず通常通り使用できました。
[2019-06-19T11:36:45,726][INFO ][o.e.n.Node ] [qp9CbAQ] starting ...
[2019-06-19T11:36:45,939][INFO ][o.e.t.TransportService ] [qp9CbAQ] publish_address {127.0.0.1:9300}, bound_addresses {[::1]:9300}, {127.0.0.1:9300}
[2019-06-19T11:36:49,003][INFO ][o.e.c.s.ClusterService ] [qp9CbAQ] new_master {qp9CbAQ}{qp9CbAQFQL6m45priWfGSw}{yXd2PI0RSJe7PBJfCCgQIg}{127.0.0.1}{127.0.0.1:9300}, reason: zen-disco-elected-as-master ([0] nodes joined)
[2019-06-19T11:36:49,027][INFO ][o.e.h.n.Netty4HttpServerTransport] [qp9CbAQ] publish_address {127.0.0.1:9200}, bound_addresses {[::1]:9200}, {127.0.0.1:9200}
[2019-06-19T11:36:49,027][INFO ][o.e.n.Node ] [qp9CbAQ] started
[2019-06-19T11:36:49,350][INFO ][o.e.g.GatewayService ] [qp9CbAQ] recovered [1] indices into cluster_state
[2019-06-19T11:36:51,371][INFO ][o.e.c.r.a.AllocationService] [qp9CbAQ] Cluster health status changed from [RED] to GREEN.
$ curl "http://localhost:9200/_cat/shards"
es_sample_data 9 p STARTED 16124 161.1mb 127.0.0.1 qp9CbAQ
es_sample_data 8 p STARTED 16084 156.5mb 127.0.0.1 qp9CbAQ
es_sample_data 7 p STARTED 16155 163.6mb 127.0.0.1 qp9CbAQ
es_sample_data 6 p STARTED 15998 163.6mb 127.0.0.1 qp9CbAQ
es_sample_data 11 p STARTED 16348 162.7mb 127.0.0.1 qp9CbAQ
es_sample_data 10 p STARTED 16050 159.3mb 127.0.0.1 qp9CbAQ
es_sample_data 1 p STARTED 15869 158.4mb 127.0.0.1 qp9CbAQ
es_sample_data 4 p STARTED 16144 163.4mb 127.0.0.1 qp9CbAQ
es_sample_data 3 p STARTED 16210 162mb 127.0.0.1 qp9CbAQ
es_sample_data 2 p STARTED 16277 161mb 127.0.0.1 qp9CbAQ
es_sample_data 5 p STARTED 16340 159.8mb 127.0.0.1 qp9CbAQ
es_sample_data 0 p STARTED 16241 164.7mb 127.0.0.1 qp9CbAQ
新しく設定した data3
には Elasticsearch 関連のファイルが配置されています。
$ tree data3
data3
└── nodes
└── 0
├── _state
│ ├── global-2.st
│ └── node-1.st
├── indices
│ └── C57jAJENRq2AheQLA1V7SA
│ └── _state
│ └── state-14.st
└── node.lock
data.path
を追加したあとのシャードの再配置について
新しいストレージをマウントして data.path
に追加するだけでは、(Elasticsearchに認識されるものの) 既存インデックスのシャードが 新しいストレージに再配置されず容量が活用されないため 注意しましょう。
ストレージの使用率がwatermarkに達するまでシャードが保存されているストレージをずっと使いづつけます。
シャードが新しいストレージに自動で再配置されるため、マシンをクラスターに追加する方法を強くおすすめします。
ストレージだけを追加して data.path
を追加する方法で増設した場合は、(正しいreroute APIの使い方ではないかもしれませんが)他のノードからストレージを増設したノードにシャードを移動させることで新しいストレージを使用することができます。
手動でもシャードを特定のストレージに移動させる方法はありません😢
/_cat/indices?v
, /_cat/shards/{index name}?v
, /_cat/segments?v
と /path/to/data/nodes/0/indices/{indicesのuuid}/{シャード番号の数字}/index
ディレクトリの中身を確認して 再配置するシャードを決めてから 次のコマンドを用いて、別のノードに新しくシャードを再配置させます。
繰り返しになりますがこのコマンドは別のマシンにシャードを移動するものです。Elasticsearchで認識された新しいストレージが使われますが、使用率の状況によっては希望したストレージにシャードが移動されない場合もあります。
また、(別のシャードが交換されるかたちで)移動先のノードから現在のノードにシャードが来ることもあります。
インデックス名の指定にエイリアスは使えません。エイリアスを指定してもシャードが見つからない旨のエラーが出ます。
curl -XPOST 'nodes-1:9200/_cluster/reroute?pretty' -d '{
"commands" : [ {
"move" :
{
"index" : "es_sample", "shard" : {shard id},
"from_node" : "nodes-1", "to_node" : "nodes-2"
}
}
]
}'
Elasticsearchのクラスターにノードを追加する方法
こちらでは検証していませんが、Elasticsearchのクラスターにノード(マシン)を追加するとクラスター全体のストレージ容量が増えることが確認されています。
この方法では既存のElasticsearchのノードを一旦終了させる必要がなく無停止でストレージを増設できます。
(マシンが増えることを許容するのであれば)こちらの方法が実績があり無停止で増設できるメリットを受けられます。
この場合は、シャードの再配置による負荷の上昇やスプリットブレインの防止についてなど考慮する必要があります。
Elasticsearchのクラスタにノードを追加するときにやっていること
https://suzuken.hatenablog.jp/entry/2014/04/17/134013
新しいマシンでElasticsearchを設定してクラスター名( cluster.name
)を既存のクラスター名と同じにするだけで、新しいマシンがクラスターに追加されます。
データの再配置も自動的に実行されます。
- Adding nodes to your cluster | Elasticsearch Reference [7.1] | Elastic https://www.elastic.co/guide/en/elasticsearch/reference/current/add-elasticsearch-nodes.html
- Elasticsearchクラスタにノードを追加してみる - Qiita https://qiita.com/tsukapah/items/7b976cb2c59941875ec2
ノード追加時の zen.ping.unicast.hosts
の設定について
基本的に elasticsearch.yml
の zen.ping.unicast.hosts
はクラスター内のノードをすべて設定する必要はありません。マスターノードがクラスターの情報を全部配ってくれるので マスターノードになりうるノードだけを指定します。
- https://www.elastic.co/jp/blog/how-to-configure-elasticsearch-cluster-better -> 誤解:全てのノードのzen.ping.unicast.hostsにはクラスターに接続するノードを「全て」記述しないといけない
node.master
を明示的に設定しないと、デフォルトが true
のため一つのノードがダウンしたらどれが新しくマスターノードになるかわからない設定になり zen.ping.unicast.hosts
にノードを全部書く必要がありそうです。
Master-eligible node
A node that has node.master set to true (default), which makes it eligible to be elected as the master node, which controls the cluster.https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html
まとめ
Elasticsearchでストレージを追加するには次の方法が使えそうですね ☺️
- 新しいストレージをマウントしてから、Elasticsearchを終了し、
elasticsearch.yml
にdata.path
を追加して再起動する- ただし、同一ノードにストレージを追加しているのでノードが壊れてしまうとおしまいです
- また、既存のインデックス・シャードは新しい場所に再配置されません。新しいインデックス用に容量を確保する場合しか使えないでしょう
- 新しいマシンでElasticsearchをセットアップしてクラスターにノードを追加する
- 管理するマシンは増えてしまいますが、シャードの再配置が自動的に実行されるため、インデックスが巨大になってストレージを圧迫している状況に有効でしょう