複数のインデックスをまとめて消す方法
Delete Index http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-delete-index.html
にも書いてあるけど、*
が使える。単一のインデックスを消す場合には以下のようにする。
$ curl -XDELETE 'http://localhost:9200/twitter/'
もし、hoge1
、hoge2
、fuga1
というインデックスがあって、hoge1
とhoge2
だけ消したい場合には以下のようにする。
$ curl -XDELETE 'http://localhost:9200/hoge*/'
Elasticsearchのクラスタにノードを追加するときにやっていること
Elasticsearchのクラスタにノードを追加するのは簡単にできる。しかし、インデックスを盛々積んだクラスタにノードをカジュアルに追加すると、一気にシャードのアロケーションが走って負荷があがる。また、何の設定もせずに追加するとsplit brainを起こしやすくなる。適切に設定すれば大丈夫なので、それをまとめておく。
結論
安全にやるなら、
- ノード追加前に全shardの移動を止める。
- split brainを避けるために、最小のマスターノード数を設定しておく。
ということをしておくとよい。
クラスタ設定はリアルタイムに変更できるので活用しよう。
Cluster Update Settings http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/cluster-update-settings.html
ノード追加前の準備
シャードの移動をとめておく。また、最小のマスターノード数を普段よりちょっと多めに設定しておく。こうしておけばsplit brainを防げる。なお、discovery.zen.minimum_master_nodes
の設定はノード数 / 2 + 1
にしておく。ノードを追加するときは追加したあとのノード数に合わせて設定しておくとよい。
例えば、3ノードのクラスタに2ノード追加するとする。その場合、discovery.zen.minimum_master_nodes
は5 / 2 + 1 = 3.5
なので、3か4にしておく。
$ curl -XPUT http://es1:9200/_cluster/settings -d '{ "persistent": {"cluster.routing.allocation.enable": "none"} }' {"acknowledged":true,"persistent":{"cluster":{"routing":{"allocation":{"enable":"none"}}}},"transient":{}}% $ curl -XPUT http://es1:9200/_cluster/settings -d '{ "persistent": {"discovery.zen.minimum_master_nodes": 3} }' {"acknowledged":true,"persistent":{"discovery":{"zen":{"minimum_master_nodes":"3"}}},"transient":{}}%
実際にノードを追加する。ノードを追加した際にclusterに追加されている様子はelasticsearch-headなどでみるのがよい。
mobz/elasticsearch-head https://github.com/mobz/elasticsearch-head
split brainしていないか観察しておく。もしsplit brainしてしまったら、discoveryをもう一度走らせる必要があるので気をつけよう。
無事ノードがクラスタに追加されたことを確認したら、シャード移動を許可するようにする。
$ curl -XPUT http://es1:9200/_cluster/settings -d '{ "persistent": {"cluster.routing.allocation.enable": "all"} }' {"acknowledged":true,"persistent":{"cluster":{"routing":{"allocation":{"enable":"none"}}}},"transient":{}}%
するとシャードが各ノードに移っていくことが確認できる。なお、デフォルトだと1インデックスにつき2シャードずつしか移動が行われないようになっている。cluster.routing.allocation.cluster_concurrent_rebalance
を調整することでこれを変更することもできる。1インデックスあたりのシャード数を多めに設定している場合には、この設定を増やすことによって、シャードの移動を早くすることができる。ただし、当然シャード移動のためのトラフィックも増えるので、そこはモニタリングしつつ行うようにする。
Cluster http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-cluster.html
他にも、もしDCが分かれているなどの場合にはそれぞれのrackごとに設定をすることもできる。
write heavyなときの設定
あんまりクエリされないけど、書き込みがめっちゃ多い運用というのもあると思う。今うちで使ってる方法だと、限られた人たちがKibanaでクエリするので、多くても2桁人。
- 書き込みはスムーズにしたい
- 検索は多少遅くてもいいけど確実に結果が帰ってきてほしい
- STWは避けたい
ということで最近いろいろ調査してた。
ElasticSearch config for a write-heavy cluster https://gist.github.com/reyjrar/4364063
上記の設定は割りと参考になりそうなので、来週の検証に利用してみる。
Elasticsearch 1.x系統でのgatewayに関して
Localのみ推奨、となっている。
Gatewayモジュールというのがあって、
端的にいうとクラスタ管理のためのメタデータを保持する部分になっている。デフォルトではlocalに保存するようになってる。
弊社ではAWSでElasticsearchを運用しているのでS3 Gatewayを検討しよう、と思ったらどうもdeprecateになっているらしい。
- S3 Gateway
- http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-gateway-s3.html
ちなみにこのへんのissueで議論されている。
- Deprecate Shared Gateway · Issue #2458 · elasticsearch/elasticsearch
- https://github.com/elasticsearch/elasticsearch/issues/2458
shared gatewayについては基本的に廃止の方向のようだ。
- Shared FS Gateway
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-gateway-fs.html
- http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/modules-gateway-hadoop.html
ちなみにAWSがらみでいうと、Elasticsearchへのautoscaling適用についてはこのへんで議論されている。
- Analyze/Implement Auto Scaling for Elasticsearch · Issue #270 · cityindex/logsearch
- https://github.com/cityindex/logsearch/issues/270
自分ところの環境では当面Elasticsearchのautoscaling運用は考えてない。少なくとも現時点では。理由はシンプルで、ノード追加のタイミングでのshardのreplicationの負荷がどうしても発生するので、そのへんrerouteをしっかり設定して、、、となると結局autoscaling groupごとにrouteを考えよう、などなど考える部分が増えるので。ひとまずトラフィックが予測できるならautoscalingにしなくてもよいのでは、と思っている。
update
2014/03/27 16:10 Local Gateway以外、削除されました。Elasticsearch 1.2.0から反映されるようです。
参考: Remove deprecated Gateways · Issue #5422 · elasticsearch/elasticsearch https://github.com/elasticsearch/elasticsearch/issues/5422
Elasticsearch 1.0.1でcuratorが動かない場合
現象が報告されているようです。
Master branch doesn't work with Elasticsearch 1.0.1 · Issue #56 · elasticsearch/curator https://github.com/elasticsearch/curator/issues/56
curatorのmaster
ブランチでは対応しているようなので、現段階での対応としてはpipでmasterブランチからいれるようにしましょう。
$ pip install https://github.com/elasticsearch/curator/tarball/master
これでうちの環境では動くようになりました。
update
2014/03/27 13:15 pipへのリリースもされ、通常通りpip install elasticsearch-curator
で動作するようになりました。
preferenceを利用してsearchを特定シャードでのみ実行する
Preference http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-preference.html
これを使う。
例
例えば、primary shardでのみ実行してみる。
GET _search?preference=_primary { "facets":{ "terms": { "terms": { "field": "_type", "size": 10, "order":"count" } } } }
通常は?
primary shard, replica shardをランダムに利用するようになっている。クエリの実行結果の_shards
をみるとどのシャードで実行されたのかを確かめることができる。
Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する
- 追記 2014/02/06 19:58 わかりづらかったのでテンプレートのrepositoryを作りました。 https://github.com/suzuken/vagrant-puppet-elasticsearch-cluster-sample
- 追記 2014/02/07 10:00 johtaniさんが本記事を元に実際に環境を試してくださってました。-> すずけんさんのメモを元にVagrantでElasticsearchクラスタを起動してみた - @johtaniの日記 2nd http://blog.johtani.info/blog/2014/02/06/es-cluster-start-using-vagrant-and-puppet/
cluster構成をつくってみる。結論から言うと、
- ちゃんと
network.host
をVMに設定する - すると勝手にmulticastでnodeが発見される
以下の記事と同様にelasticsearch用のノードをもう1つ作る。
- Vagrant環境にpuppet moduleを利用してさくっとelasticsearchをインストールする - すずけんメモ
NodeのディスカバリにはZen Discoveryを利用する。単純にマルチキャストを利用すればよいだろう。と思ったらエラー。どうやらnetwork.host
をちゃんと設定しなければならないらしい。
- Zen Discovery
結論、というか設定
以下のように設定する。
Vagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "centos64" config.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box" config.vm.define :search01 do |search_config| search_config.vm.hostname = "search01.local" search_config.vm.network "private_network", ip: "192.168.10.114" end config.vm.define :search02 do |search_config| search_config.vm.hostname = "search02.local" search_config.vm.network "private_network", ip: "192.168.10.115" end
manifests/search.pp
include search
ついでにelasticsearch-headとMarvel, elastic-HQもいれてある。
roles/search/manifests/init.pp
class search { service { 'iptables': enable => false, ensure => stopped, } class { 'elasticsearch': package_url => 'https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.11.noarch.rpm', java_install => true, config => { 'cluster' => { 'name' => 'test-es-cluster01' }, 'network.host' => '_eth1:ipv4_', 'marvel.agent.exporter.es.hosts' => ['192.168.10.114:9200','192.168.10.115:9200'] } } elasticsearch::plugin{'elasticsearch/marvel/latest': module_dir => 'marvel' } elasticsearch::plugin{'mobz/elasticsearch-head': module_dir => 'head' } elasticsearch::plugin{'royrusso/elasticsearch-HQ': module_dir => 'HQ' } }
あとは
$ vagrant up search01 $ vagrant up search02 $ vagrant ssh-config search01 --host search01.local >> ~/.ssh/config $ vagrant ssh-config search02 --host search02.local >> ~/.ssh/config $ ssh search01.local "cd /vagrant && sudo puppet module install elasticsearch-elasticsearch" $ ssh search02.local "cd /vagrant && sudo puppet module install elasticsearch-elasticsearch" $ ssh search01.local "cd /vagrant && sudo puppet apply --modulepath=/etc/puppet/modules:modules:roles manifests/search.pp" $ ssh search02.local "cd /vagrant && sudo puppet apply --modulepath=/etc/puppet/modules:modules:roles manifests/search.pp"
とすればVMが2つ立ち上がってelasticsearchのクラスタが組まれる。Marvelでみるとこんな感じ。
ついでにもう1つノード足すとこんな感じになる。設定は割愛。単純に同じようにVMつくってmanifestあてれば勝手にclusterに追加される。簡単。
中身的なこと
ちなみに各サーバの/etc/elasticsearch/elasticsearch.yml
は以下のようになる。Marvelはデフォルトだとlocalhost:9200
をみるようになっているので、明示してあげるようにしている。
### MANAGED BY PUPPET ### --- cluster: name: test-es-cluster01 marvel: agent: exporter: es: hosts: - 192.168.10.114:9200 - 192.168.10.115:9200 network: host: _eth1:ipv4_
ここ、明示しなくても勝手にノード検出するんじゃないかという気がしているけど、とりあえずこれで。
http://www.elasticsearch.org/guide/en/marvel/current/#stats-export をみると以下のように載っている。
A list of hosts in hostname:port format to which statistics and events will be sent. Data will be sent to the first host, but will failover to the next host(s) if the first is not reachable. Defaults to ["localhost:9200"].
ということなので、複数載せておけば勝手にfailoverして隣のホストにexportするようにしてくれるらしい。便利。
細かいエラーの話
環境によるかもしれないけど、VMで立ち上げたnodeはデフォルトでnetwork.host
がeth0
を見るようになっている。この場合、例えばunicastでpingしてnodeを検出しようとしてもerrorがでてしまう。この場合、network.host
が10.0.2.15
になっている。
[2014-02-05 07:30:18,350][INFO ][discovery.zen ] [Rocket Raccoon] failed to send join request to master [[Kismet][QjUBU_iKTc6oLJn-trkEVw][inet[/10.0.2.15:9300]]], reason [org.elasticsearch.transport.RemoteTransportException: [Rocket Raccoon][i net[/10.0.2.15:9300]][discovery/zen/join]; org.elasticsearch.ElasticSearchIllegalStateException: Node [[Rocket Raccoon][oWubpeP8Q5atLeAIlD2rWA][inet[/10.0.2.15:9300]]] not master for join request from [[Rocket Raccoon][oWubpeP8Q5atLeAIlD2rWA][inet[/10.0. 2.15:9300]]]]
network.host
をVMのhostにしてもやっぱりだめ。
[2014-02-05 07:34:24,593][WARN ][discovery.zen ] [Americop] failed to connect to master [[Kismet][QjUBU_iKTc6oLJn-trkEVw][inet[/10.0.2.15:9300]]], retrying... org.elasticsearch.transport.ConnectTransportException: [Kismet][inet[/10.0.2.15:9300]] connect_timeout[30s] at org.elasticsearch.transport.netty.NettyTransport.connectToChannels(NettyTransport.java:718) at org.elasticsearch.transport.netty.NettyTransport.connectToNode(NettyTransport.java:647) at org.elasticsearch.transport.netty.NettyTransport.connectToNode(NettyTransport.java:615) at org.elasticsearch.transport.TransportService.connectToNode(TransportService.java:129) at org.elasticsearch.discovery.zen.ZenDiscovery.innerJoinCluster(ZenDiscovery.java:335) at org.elasticsearch.discovery.zen.ZenDiscovery.access$500(ZenDiscovery.java:76) at org.elasticsearch.discovery.zen.ZenDiscovery$1.run(ZenDiscovery.java:283) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) Caused by: java.net.ConnectException: Connection refused: /10.0.2.15:9300 at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:739) at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.connect(NioClientBoss.java:150) at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.processSelectedKeys(NioClientBoss.java:105) at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.process(NioClientBoss.java:79) at org.elasticsearch.common.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318) at org.elasticsearch.common.netty.channel.socket.nio.NioClientBoss.run(NioClientBoss.java:42) at org.elasticsearch.common.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108) at org.elasticsearch.common.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) ... 3 more
host側ネットワークを見れるようにするためにnetwork.host
を変更すればよかったのでした。 @johtani さんのreplyで気が付きました。ありがとうございました。
Vagrant環境のelasticsearch, うまくDiscoverしてくれないなぁ。private network組む以外に何か特別に設定必要なのかな。それともunicastか・・?
— Kenta Suzuki (@suzu_v) 2014, 2月 5
@johtani あーできました。network.hostでeth1向くようにしたらちゃんと外に出ました。ありがとうございます〜。
— Kenta Suzuki (@suzu_v) 2014, 2月 5
@johtani なるほど・・・。このへんは明示しないとですね。
— Kenta Suzuki (@suzu_v) 2014, 2月 5