elasticsearch-manager 0.1.1 → 0.1.2.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/Gemfile.lock +1 -1
- data/bin/elasticsearch-manager +13 -1
- data/lib/elasticsearch/client/elasticsearch.rb +10 -0
- data/lib/elasticsearch/manager/cmd.rb +48 -3
- data/lib/elasticsearch/manager/manager.rb +10 -2
- data/lib/elasticsearch/manager/nodes.rb +15 -0
- data/lib/elasticsearch/manager/rollingrestart.rb +7 -1
- data/lib/elasticsearch/manager/version.rb +1 -1
- data/lib/elasticsearch/manager.rb +1 -0
- data/lib/elasticsearch/model/node.rb +13 -0
- data/lib/elasticsearch/model/routing_nodes.rb +2 -2
- data/lib/elasticsearch/model/state.rb +39 -16
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
OGVjMGNiNjUxZjhjZGNmNThmYWZlZDZiOWVkMzYyY2M1MzI3YWZiOQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e33a67d294a013df625637e54a74b3768103eff
|
4
|
+
data.tar.gz: bacfd5645a75323de255fcdb4e7eed862d611ef5
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
Mjk2NGYyOTM5YmNjOGZjMmNhNTkwNmQ0M2NlMzBhMjRjMzk0MGUxODUwZmVj
|
11
|
-
NDViNjU2N2ZjNDZlNGRlNzFmYTgzODNhYWUzNjY1MDE4MTg2MWI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Y2Y1YTg4Mjg0NjhjN2ZhZjZiYzZiMmU2Zjk3MjhiNmNhM2VkZWIwOWE3NmUw
|
14
|
-
ODhiNDA0ZjI2NWEyZDhkNGFmZTAzODJiYTY0YzZjZWE2NzJlNjE3MGVkZjVj
|
15
|
-
Mjg0ZmRhODI5ZmU1NjU4N2NhMzFjZmVlNDk3MjNjYzA2YzYwNTA=
|
6
|
+
metadata.gz: f481ee93f5117ad7ca76d2986061bb93fb8a8c4767246e2b80814d806a7a44b519d52103cafa6fbc5957c07ca8289832a8a44d1b27809b60a6f71c75b9366702
|
7
|
+
data.tar.gz: 7cdca00339dd4c242afbbb4c1ec78d9782c86649a0dcdee31630d70deda76be98b9ad791cbd355f84cef71f25d90c7bd364007d8ea7d8abb3f4eb2bef0e155cc
|
data/Gemfile.lock
CHANGED
data/bin/elasticsearch-manager
CHANGED
@@ -19,8 +19,12 @@ opt_parser = OptionParser.new do |opts|
|
|
19
19
|
elasticsearch-manager [options] <command>
|
20
20
|
|
21
21
|
Available commands:
|
22
|
-
rolling-restart -- Restart elasticsearch across the entire cluster, one node at a time
|
22
|
+
rolling-restart -- Restart elasticsearch across the entire cluster, one node at a time
|
23
|
+
list-nodes -- List IPs of nodes in the cluster
|
24
|
+
shard-state -- Print current shard states
|
23
25
|
status -- Check the current state of the cluster (green/yellow/red)
|
26
|
+
diable-routing -- Disable shard routing allocation
|
27
|
+
enable-routing -- Enable shard routing allocation
|
24
28
|
|
25
29
|
EOC
|
26
30
|
|
@@ -51,8 +55,16 @@ cmd = ARGV[0]
|
|
51
55
|
case cmd
|
52
56
|
when 'rolling-restart'
|
53
57
|
ec = CMD.rolling_restart(options)
|
58
|
+
when 'list-nodes'
|
59
|
+
ec = CMD.list_nodes(options)
|
60
|
+
when 'shard-state'
|
61
|
+
ec = CMD.shard_states(options)
|
54
62
|
when 'status'
|
55
63
|
ec = CMD.status(options)
|
64
|
+
when 'disable-routing'
|
65
|
+
ec = CMD.disable_routing(options)
|
66
|
+
when 'enable-routing'
|
67
|
+
ec = CMD.enable_routing(options)
|
56
68
|
else
|
57
69
|
puts "Unknown command: #{cmd}\n"
|
58
70
|
puts opt_parser
|
@@ -29,6 +29,16 @@ module Elasticsearch
|
|
29
29
|
get('/_cluster/settings')
|
30
30
|
end
|
31
31
|
|
32
|
+
def node_concurrent_recoveries(num_recoveries = 2)
|
33
|
+
data = {
|
34
|
+
'transient' => {
|
35
|
+
'cluster.routing.allocation.node_concurrent_recoveries' => num_recoveries
|
36
|
+
}
|
37
|
+
}.to_json
|
38
|
+
|
39
|
+
put('/_cluster/settings', data)
|
40
|
+
end
|
41
|
+
|
32
42
|
def routing(disable = true)
|
33
43
|
data = {
|
34
44
|
'transient' => {
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'colorize'
|
2
2
|
require 'net/ssh'
|
3
3
|
|
4
|
-
require 'elasticsearch/manager
|
5
|
-
require 'elasticsearch/manager/rollingrestart'
|
4
|
+
require 'elasticsearch/manager'
|
6
5
|
|
7
6
|
|
8
7
|
module Elasticsearch
|
@@ -17,8 +16,9 @@ module Elasticsearch
|
|
17
16
|
print_cluster_status(manager, 'The cluster is currently unstable! Not proceeding with rolling-restart')
|
18
17
|
return 2
|
19
18
|
end
|
20
|
-
|
19
|
+
print "Discovering cluster members..." if opts[:verbose]
|
21
20
|
manager.cluster_members!
|
21
|
+
print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
|
22
22
|
timeout = opts[:timeout] || 600
|
23
23
|
sleep_interval = opts[:sleep_interval] || 30
|
24
24
|
begin
|
@@ -31,6 +31,51 @@ module Elasticsearch
|
|
31
31
|
return 0
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.list_nodes(opts)
|
35
|
+
manager = _manager(opts)
|
36
|
+
print "Discovering cluster members..." if opts[:verbose]
|
37
|
+
manager.cluster_members!
|
38
|
+
print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
|
39
|
+
manager.list_node_ips
|
40
|
+
return 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.disable_routing(opts)
|
44
|
+
manager = _manager(opts)
|
45
|
+
print "Disabling shard routing allocation..."
|
46
|
+
msg = if manager.disable_routing
|
47
|
+
"disabled!".colorize(:green)
|
48
|
+
else
|
49
|
+
"error, unable to disable shard routing allocation!".colorize(:red)
|
50
|
+
end
|
51
|
+
print "\rDisabling shard routing allocation... #{msg}\n"
|
52
|
+
return 0
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.enable_routing(opts)
|
56
|
+
manager = _manager(opts)
|
57
|
+
print "Enabling shard routing allocation..."
|
58
|
+
msg = if manager.enable_routing
|
59
|
+
"enabled!".colorize(:green)
|
60
|
+
else
|
61
|
+
"error, unable to enable shard routing allocation!".colorize(:red)
|
62
|
+
end
|
63
|
+
print "\rEnabling shard routing allocation... #{msg}\n"
|
64
|
+
return 0
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.shard_states(opts)
|
68
|
+
manager = _manager(opts)
|
69
|
+
print "Discovering cluster members..." if opts[:verbose]
|
70
|
+
manager.cluster_members!
|
71
|
+
print "\rDiscovering cluster members... Done!\n" if opts[:verbose]
|
72
|
+
puts "UNASSIGNED: #{manager.state.count_unassigned_shards}"
|
73
|
+
manager.nodes.each do |node|
|
74
|
+
puts "#{node.ip}:\tSTARTED: #{node.count_started_shards}\t|\tINITIALIZING: #{node.count_initializing_shards}\t|\tRELOCATING: #{node.count_relocating_shards}"
|
75
|
+
end
|
76
|
+
return 0
|
77
|
+
end
|
78
|
+
|
34
79
|
def self.status(opts)
|
35
80
|
manager = _manager(opts)
|
36
81
|
status = manager.cluster_status
|
@@ -6,10 +6,11 @@ module Elasticsearch
|
|
6
6
|
class ESManager
|
7
7
|
include Elasticsearch::Model
|
8
8
|
|
9
|
-
attr_accessor :leader, :members, :nodes
|
9
|
+
attr_accessor :leader, :members, :nodes, :state
|
10
10
|
|
11
11
|
def initialize(cluster_host = 'localhost', port = 9200)
|
12
12
|
@client = Elasticsearch::Client::ESClient.new(cluster_host, port)
|
13
|
+
@state = nil
|
13
14
|
@leader = nil
|
14
15
|
@nodes = nil
|
15
16
|
@members = nil
|
@@ -30,8 +31,9 @@ module Elasticsearch
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def cluster_members!
|
33
|
-
state = cluster_state
|
34
|
+
@state = cluster_state
|
34
35
|
@nodes = state.nodes
|
36
|
+
@nodes.sort! { |a,b| a.id <=> b.id }
|
35
37
|
@leader = @nodes.select { |n| n.master }[0].ip
|
36
38
|
@members = @nodes.map { |n| n.ip }
|
37
39
|
end
|
@@ -55,6 +57,12 @@ module Elasticsearch
|
|
55
57
|
ret = @client.routing(false)
|
56
58
|
ret['transient']['cluster']['routing']['allocation']['enable'] == 'all'
|
57
59
|
end
|
60
|
+
|
61
|
+
def set_concurrent_recoveries(num_recoveries)
|
62
|
+
ret = @client.node_concurrent_recoveries(num_recoveries)
|
63
|
+
# Elasticache seems to return integer settings as strings when setting them...
|
64
|
+
ret['transient']['cluster']['routing']['allocation']['node_concurrent_recoveries'] == num_recoveries.to_s
|
65
|
+
end
|
58
66
|
end
|
59
67
|
end
|
60
68
|
end
|
@@ -29,8 +29,10 @@ module Elasticsearch
|
|
29
29
|
|
30
30
|
def restart_node(node_ip, timeout, sleep_interval)
|
31
31
|
puts "\nRestarting Elasticsearch on node: #{node_ip}"
|
32
|
+
# Pull the current node's state
|
33
|
+
n = @state.nodes.select { |n| n.ip == node_ip }[0]
|
34
|
+
|
32
35
|
raise "Could not disable shard routing prior to restarting node: #{node_ip}".colorize(:red) unless disable_routing
|
33
|
-
|
34
36
|
Net::SSH.start(node_ip, ENV['USER']) do |ssh|
|
35
37
|
ssh.exec 'sudo service elasticsearch restart'
|
36
38
|
end
|
@@ -43,6 +45,10 @@ module Elasticsearch
|
|
43
45
|
raise NodeAvailableTimeout, "Node did not become available after waiting #{timeout} seconds...".colorize(:red)
|
44
46
|
end
|
45
47
|
|
48
|
+
# Make sure the cluster is willing to concurrently recover as many
|
49
|
+
# shards per node as this node happens to have.
|
50
|
+
raise "Could not update node_concurrent_recoveries prior to restarting node: #{node_ip}".colorize(:red) unless set_concurrent_recoveries(n.count_started_shards + 1)
|
51
|
+
|
46
52
|
raise "Could not re-enable shard routing following restart of node: #{node_ip}".colorize(:red) unless enable_routing
|
47
53
|
|
48
54
|
begin
|
@@ -34,6 +34,19 @@ module Elasticsearch
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
+
|
38
|
+
def count_initializing_shards
|
39
|
+
shards.select { |s| s.state.upcase == 'INITIALIZING' }.length
|
40
|
+
end
|
41
|
+
|
42
|
+
def count_relocating_shards
|
43
|
+
shards.select { |s| s.state.upcase == 'RELOCATING' }.length
|
44
|
+
end
|
45
|
+
|
46
|
+
def count_started_shards
|
47
|
+
shards.select { |s| s.state.upcase == 'STARTED' }.length
|
48
|
+
end
|
49
|
+
|
37
50
|
extend Representer
|
38
51
|
end
|
39
52
|
end
|
@@ -13,11 +13,11 @@ module Elasticsearch
|
|
13
13
|
property :master_node
|
14
14
|
nested :routing_nodes do
|
15
15
|
property :unassigned, setter: (lambda do |v,args|
|
16
|
-
self.unassigned = v.map {|s| Elasticsearch::
|
16
|
+
self.unassigned = v.map {|s| Elasticsearch::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(s) }
|
17
17
|
end)
|
18
18
|
property :nodes, setter: (lambda do |v,args|
|
19
19
|
self.nodes = v.map do |id, shards|
|
20
|
-
shards.each { |shard| Elasticsearch::
|
20
|
+
shards.each { |shard| Elasticsearch::Model::Shard.new.extend(Elastiman::Model::Shard::Representer).from_hash(shard) }
|
21
21
|
end.flatten
|
22
22
|
end)
|
23
23
|
end
|
@@ -2,22 +2,45 @@ require 'ostruct'
|
|
2
2
|
require 'representable/json'
|
3
3
|
|
4
4
|
module Elasticsearch
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
5
|
+
module Model
|
6
|
+
class ClusterState < OpenStruct
|
7
|
+
module Representer
|
8
|
+
include Representable::JSON
|
9
|
+
include Representable::Hash
|
10
|
+
include Representable::Hash::AllowSymbols
|
11
|
+
|
12
|
+
property :cluster_name
|
13
|
+
property :master_node
|
14
|
+
property :nodes, setter: (lambda do |v,args|
|
15
|
+
self.nodes = v.map do |id,node|
|
16
|
+
n = Elasticsearch::Model::Node.new.extend(Elasticsearch::Model::Node::Representer).from_hash(node)
|
17
|
+
n.id, n.master, n.ip = id, id == self.master_node, n.transport_address[/\d+\.\d+\.\d+\.\d+/]
|
18
|
+
n
|
19
|
+
end
|
20
|
+
end)
|
21
|
+
property :routing_nodes, setter: (lambda do |v,args|
|
22
|
+
v.each do |status,routes|
|
23
|
+
if status == 'nodes'
|
24
|
+
routes.each do |id,shards|
|
25
|
+
n = self.nodes.select { |n| n.id == id }[0]
|
26
|
+
s = shards.map do |shard|
|
27
|
+
Elasticsearch::Model::Shard.new.extend(Elasticsearch::Model::Shard::Representer).from_hash(shard)
|
28
|
+
end
|
29
|
+
n.shards = s
|
30
|
+
end
|
31
|
+
elsif status == 'unassigned'
|
32
|
+
self.unassigned_shards = routes.map do |shard|
|
33
|
+
Elasticsearch::Model::Shard.new.extend(Elasticsearch::Model::Shard::Representer).from_hash(shard)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end)
|
38
|
+
end
|
39
|
+
|
40
|
+
def count_unassigned_shards
|
41
|
+
unassigned_shards.length
|
42
|
+
end
|
43
|
+
extend Representer
|
20
44
|
end
|
21
|
-
extend Representer
|
22
45
|
end
|
23
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-manager
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Oldfield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- lib/elasticsearch/manager/cmd.rb
|
204
204
|
- lib/elasticsearch/manager/errors.rb
|
205
205
|
- lib/elasticsearch/manager/manager.rb
|
206
|
+
- lib/elasticsearch/manager/nodes.rb
|
206
207
|
- lib/elasticsearch/manager/rollingrestart.rb
|
207
208
|
- lib/elasticsearch/manager/version.rb
|
208
209
|
- lib/elasticsearch/model.rb
|
@@ -235,14 +236,14 @@ require_paths:
|
|
235
236
|
- lib
|
236
237
|
required_ruby_version: !ruby/object:Gem::Requirement
|
237
238
|
requirements:
|
238
|
-
- -
|
239
|
+
- - '>='
|
239
240
|
- !ruby/object:Gem::Version
|
240
241
|
version: '0'
|
241
242
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
242
243
|
requirements:
|
243
|
-
- -
|
244
|
+
- - '>'
|
244
245
|
- !ruby/object:Gem::Version
|
245
|
-
version:
|
246
|
+
version: 1.3.1
|
246
247
|
requirements: []
|
247
248
|
rubyforge_project:
|
248
249
|
rubygems_version: 2.4.6
|