elasticsearch-manager 0.1.1 → 0.1.2.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|