droonga-engine 1.0.8 → 1.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/droonga-engine-absorb-data +9 -0
- data/bin/droonga-engine-join +11 -0
- data/bin/droonga-engine-unjoin +108 -83
- data/droonga-engine.gemspec +1 -1
- data/lib/droonga/catalog/base.rb +10 -0
- data/lib/droonga/catalog_fetcher.rb +3 -1
- data/lib/droonga/command/droonga_engine.rb +1 -0
- data/lib/droonga/command/remote.rb +21 -2
- data/lib/droonga/command/serf_event_handler.rb +2 -0
- data/lib/droonga/data_absorber.rb +6 -5
- data/lib/droonga/engine/version.rb +1 -1
- data/lib/droonga/serf.rb +26 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2574dab76722981c14a23373e838f1e01d18220
|
4
|
+
data.tar.gz: 9776825164dda315f20af0f0d610d2391cce93fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55b359cab3e5ca1bd0b7008233c54bbf413d27b97ee8d179ca09be701fa4f2749935cb37eaf743bfb0099600794c80d319edce22bedde28b69f685d944c8f193
|
7
|
+
data.tar.gz: 09add0504d2886e51065af0c09a4d350db98c8fe07e9a6de6f317ca08af34971016f57c2ac3706d4317df110d125077045c8973c996f4bda382a187cd903ffa0
|
@@ -18,6 +18,7 @@
|
|
18
18
|
require "ostruct"
|
19
19
|
require "optparse"
|
20
20
|
require "open3"
|
21
|
+
require "socket"
|
21
22
|
|
22
23
|
require "droonga/engine/version"
|
23
24
|
require "droonga/catalog_generator"
|
@@ -34,6 +35,7 @@ class AbsorbDataCommand
|
|
34
35
|
|
35
36
|
puts "Start to absorb data from #{@options.source_host}"
|
36
37
|
puts " to #{@options.destination_host}"
|
38
|
+
puts " via #{@options.receiver_host} (this host)"
|
37
39
|
puts " dataset = #{@options.dataset}"
|
38
40
|
puts " port = #{@options.port}"
|
39
41
|
puts " tag = #{@options.tag}"
|
@@ -57,6 +59,7 @@ class AbsorbDataCommand
|
|
57
59
|
options.tag = Droonga::CatalogGenerator::DEFAULT_TAG
|
58
60
|
options.dataset = Droonga::CatalogGenerator::DEFAULT_DATASET
|
59
61
|
options.remote = true
|
62
|
+
options.receiver_host = Socket.gethostname
|
60
63
|
options.messages_per_second = Droonga::DataAbsorber::DEFAULT_MESSAGES_PER_SECOND
|
61
64
|
parser = OptionParser.new
|
62
65
|
parser.version = Droonga::Engine::VERSION
|
@@ -71,6 +74,11 @@ class AbsorbDataCommand
|
|
71
74
|
"Host name of this cluster to be connected.") do |host|
|
72
75
|
options.destination_host = host
|
73
76
|
end
|
77
|
+
parser.on("--receiver-host=HOST",
|
78
|
+
"Host name of this computer.",
|
79
|
+
"(#{options.receiver_host})") do |host|
|
80
|
+
options.receiver_host = host
|
81
|
+
end
|
74
82
|
parser.on("--port=PORT", Integer,
|
75
83
|
"Port number of the source cluster to be connected.",
|
76
84
|
"(#{options.port})") do |port|
|
@@ -139,6 +147,7 @@ class AbsorbDataCommand
|
|
139
147
|
:dataset => @options.dataset,
|
140
148
|
:source_host => @options.source_host,
|
141
149
|
:destination_host => @options.destination_host,
|
150
|
+
:receiver_host => @options.receiver_host,
|
142
151
|
:port => @options.port,
|
143
152
|
:tag => @options.tag,
|
144
153
|
:messages_per_second => @options.messages_per_second,
|
data/bin/droonga-engine-join
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
require "slop"
|
19
19
|
require "json"
|
20
20
|
require "pathname"
|
21
|
+
require "socket"
|
21
22
|
|
22
23
|
require "droonga/engine/version"
|
23
24
|
require "droonga/path"
|
@@ -30,6 +31,12 @@ class JoinCommand
|
|
30
31
|
def run
|
31
32
|
parse_options
|
32
33
|
trap_signals
|
34
|
+
|
35
|
+
puts "Start to join a new node #{@options[:host]}"
|
36
|
+
puts " to the cluster of #{@options["replica-source-host"]}"
|
37
|
+
puts " via #{@options["receiver-host"]} (this host)"
|
38
|
+
puts ""
|
39
|
+
|
33
40
|
set_node_role
|
34
41
|
do_join
|
35
42
|
sleep(5) #TODO: wait for restarting of the joining node. this should be done more safely.
|
@@ -54,6 +61,9 @@ class JoinCommand
|
|
54
61
|
option.on("replica-source-host=",
|
55
62
|
"Host name of the soruce node in the cluster to be connected.",
|
56
63
|
:required => true)
|
64
|
+
option.on("receiver-host=",
|
65
|
+
"Host name of this host.",
|
66
|
+
:default => Socket.gethostname)
|
57
67
|
option.on(:dataset=,
|
58
68
|
"Dataset name of for the node to be joined.",
|
59
69
|
:default => Droonga::CatalogGenerator::DEFAULT_DATASET)
|
@@ -101,6 +111,7 @@ class JoinCommand
|
|
101
111
|
:dataset => @options[:dataset],
|
102
112
|
:source_host => @options["replica-source-host"],
|
103
113
|
:destination_host => @options[:host],
|
114
|
+
:receiver_host => @options["receiver-host"],
|
104
115
|
:port => @options[:port],
|
105
116
|
:tag => @options[:tag],
|
106
117
|
:messages_per_second => @options["records-per-second"],
|
data/bin/droonga-engine-unjoin
CHANGED
@@ -15,96 +15,121 @@
|
|
15
15
|
# License along with this library; if not, write to the Free Software
|
16
16
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
17
17
|
|
18
|
-
require "
|
19
|
-
require "optparse"
|
18
|
+
require "slop"
|
20
19
|
require "json"
|
21
20
|
require "pathname"
|
22
21
|
|
23
22
|
require "droonga/engine/version"
|
24
23
|
require "droonga/path"
|
24
|
+
require "droonga/catalog_fetcher"
|
25
25
|
require "droonga/catalog_generator"
|
26
|
-
require "droonga/safe_file_writer"
|
27
|
-
require "droonga/service_installation"
|
28
26
|
require "droonga/serf"
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
28
|
+
class UnjoinCommand
|
29
|
+
def run
|
30
|
+
parse_options
|
31
|
+
|
32
|
+
puts "Start to unjoin a node #{@options[:host]}"
|
33
|
+
puts " by #{@options["receiver-host"]} (this host)"
|
34
|
+
puts ""
|
35
|
+
|
36
|
+
do_unjoin
|
37
|
+
|
38
|
+
puts("Done.")
|
39
|
+
exit(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
def parse_options
|
44
|
+
options = Slop.parse(:help => true) do |option|
|
45
|
+
option.on(:host=,
|
46
|
+
"Host name of the replica removed from cluster.",
|
47
|
+
:required => true)
|
48
|
+
option.on("receiver-host=",
|
49
|
+
"Host name of this host.",
|
50
|
+
:default => Socket.gethostname)
|
51
|
+
option.on(:dataset=,
|
52
|
+
"Dataset name of for the node to be unjoined.",
|
53
|
+
:default => Droonga::CatalogGenerator::DEFAULT_DATASET)
|
54
|
+
option.on(:port=,
|
55
|
+
"Port number of the source cluster to be connected.",
|
56
|
+
:as => Integer,
|
57
|
+
:default => Droonga::CatalogGenerator::DEFAULT_PORT)
|
58
|
+
option.on(:tag=,
|
59
|
+
"Tag name of the soruce cluster to be connected.",
|
60
|
+
:default => Droonga::CatalogGenerator::DEFAULT_TAG)
|
61
|
+
end
|
62
|
+
@options = options
|
63
|
+
rescue Slop::MissingOptionError => error
|
64
|
+
$stderr.puts(error)
|
65
|
+
exit(false)
|
66
|
+
end
|
67
|
+
|
68
|
+
def replica_remove_host
|
69
|
+
@options[:host]
|
70
|
+
end
|
71
|
+
|
72
|
+
def tag
|
73
|
+
@options[:tag]
|
74
|
+
end
|
75
|
+
|
76
|
+
def port
|
77
|
+
@options[:port]
|
78
|
+
end
|
79
|
+
|
80
|
+
def dataset_name
|
81
|
+
@options[:dataset]
|
82
|
+
end
|
83
|
+
|
84
|
+
def replica_remove_node
|
85
|
+
"#{replica_remove_host}:#{port}/#{tag}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def fetch_catalog
|
89
|
+
fetcher = Droonga::CatalogFetcher.new(:host => replica_remove_host,
|
90
|
+
:port => port,
|
91
|
+
:tag => tag,
|
92
|
+
:receiver_host => @options["receiver-host"])
|
93
|
+
fetcher.fetch(:dataset => dataset_name)
|
94
|
+
end
|
95
|
+
|
96
|
+
def remaining_node
|
97
|
+
@remaining_node ||= detect_remaining_node
|
98
|
+
end
|
99
|
+
|
100
|
+
def detect_remaining_node
|
101
|
+
catalog = fetch_catalog
|
102
|
+
generator = Droonga::CatalogGenerator.new
|
103
|
+
generator.load(catalog)
|
104
|
+
|
105
|
+
dataset = generator.dataset_for_host(replica_remove_host)
|
106
|
+
unless dataset
|
107
|
+
raise "Specified host #{replica_remove_host} is not a member of "+
|
108
|
+
"the cluster. You must specify correct host via --replica-remove-host " +
|
109
|
+
"option."
|
110
|
+
end
|
111
|
+
|
112
|
+
other_hosts = dataset.replicas.hosts
|
113
|
+
|
114
|
+
remaining_host = other_hosts.first || replica_remove_host
|
115
|
+
"#{remaining_host}:#{port}/#{tag}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def run_remote_command(target, command, options)
|
119
|
+
serf = Droonga::Serf.new(nil, target)
|
120
|
+
result = serf.send_query(command, options)
|
121
|
+
puts(result[:result])
|
122
|
+
puts(result[:error]) unless result[:error].empty?
|
123
|
+
result[:response]
|
124
|
+
end
|
125
|
+
|
126
|
+
def do_unjoin
|
127
|
+
puts "Unjoining replica from the cluster..."
|
128
|
+
|
129
|
+
run_remote_command(remaining_node, "unjoin",
|
130
|
+
"dataset" => dataset_name,
|
131
|
+
"hosts" => [replica_remove_host])
|
132
|
+
end
|
83
133
|
end
|
84
134
|
|
85
|
-
|
86
|
-
options.tag = dataset.replicas.tag
|
87
|
-
options.port = dataset.replicas.port
|
88
|
-
options.other_hosts = dataset.replicas.hosts
|
89
|
-
|
90
|
-
remaining_host = options.other_hosts.first || options.replica_remove_host
|
91
|
-
options.remaining_node = "#{remaining_host}:#{options.port}/#{options.tag}"
|
92
|
-
|
93
|
-
|
94
|
-
def run_remote_command(target, command, options)
|
95
|
-
serf = Droonga::Serf.new(nil, target)
|
96
|
-
result = serf.send_query(command, options)
|
97
|
-
puts result[:result]
|
98
|
-
puts result[:error] unless result[:error].empty?
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
puts "Unjoining replica from the cluster..."
|
103
|
-
|
104
|
-
run_remote_command(options.remaining_node, "remove_replicas",
|
105
|
-
"dataset" => options.dataset,
|
106
|
-
"hosts" => [options.replica_remove_host])
|
107
|
-
|
108
|
-
puts "Done."
|
109
|
-
|
110
|
-
exit(true)
|
135
|
+
UnjoinCommand.new.run
|
data/droonga-engine.gemspec
CHANGED
@@ -38,7 +38,7 @@ Gem::Specification.new do |gem|
|
|
38
38
|
gem.add_dependency "archive-zip"
|
39
39
|
gem.add_dependency "cool.io"
|
40
40
|
gem.add_dependency "drndump"
|
41
|
-
gem.add_dependency "droonga-client", ">= 0.
|
41
|
+
gem.add_dependency "droonga-client", ">= 0.1.9"
|
42
42
|
gem.add_dependency "droonga-message-pack-packer", ">= 1.0.2"
|
43
43
|
gem.add_dependency "groonga-command-parser"
|
44
44
|
gem.add_dependency "faraday"
|
data/lib/droonga/catalog/base.rb
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
require "digest/sha1"
|
17
17
|
require "zlib"
|
18
18
|
require "time"
|
19
|
+
require "digest"
|
19
20
|
require "droonga/error_messages"
|
20
21
|
require "droonga/catalog/errors"
|
21
22
|
|
@@ -37,7 +38,16 @@ module Droonga
|
|
37
38
|
datasets[name]
|
38
39
|
end
|
39
40
|
|
41
|
+
def cluster_id
|
42
|
+
@cluster_id ||= calculate_cluster_id
|
43
|
+
end
|
44
|
+
|
40
45
|
private
|
46
|
+
def calculate_cluster_id
|
47
|
+
raw_id = all_nodes.sort.join(",")
|
48
|
+
Digest::SHA1.hexdigest(raw_id)
|
49
|
+
end
|
50
|
+
|
41
51
|
def migrate_database_location(current_db_path, device, name)
|
42
52
|
return if current_db_path.exist?
|
43
53
|
|
@@ -13,6 +13,8 @@
|
|
13
13
|
# License along with this library; if not, write to the Free Software
|
14
14
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
15
15
|
|
16
|
+
require "socket"
|
17
|
+
|
16
18
|
require "droonga/client"
|
17
19
|
|
18
20
|
require "droonga/address"
|
@@ -43,7 +45,7 @@ module Droonga
|
|
43
45
|
:tag => Address::DEFAULT_TAG,
|
44
46
|
:protocol => :droonga,
|
45
47
|
:timeout => 1,
|
46
|
-
:receiver_host =>
|
48
|
+
:receiver_host => Socket.gethostname,
|
47
49
|
:receiver_port => 0,
|
48
50
|
}
|
49
51
|
end
|
@@ -327,7 +327,6 @@ module Droonga
|
|
327
327
|
end
|
328
328
|
|
329
329
|
@serf.join(*hosts)
|
330
|
-
#XXX Now we should restart serf agent to remove unjoined nodes from the list of members...
|
331
330
|
end
|
332
331
|
end
|
333
332
|
|
@@ -359,8 +358,28 @@ module Droonga
|
|
359
358
|
modifier.datasets[dataset].replicas.hosts -= hosts
|
360
359
|
@service_installation.ensure_correct_file_permission(file)
|
361
360
|
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
class Unjoin < ModifyReplicasBase
|
365
|
+
def process
|
366
|
+
return if dataset.nil? or hosts.nil?
|
367
|
+
|
368
|
+
log("unjoining replicas: #{hosts.join(",")}")
|
362
369
|
|
363
|
-
|
370
|
+
CatalogModifier.modify do |modifier, file|
|
371
|
+
if unjoining_node?
|
372
|
+
modifier.datasets[dataset].replicas.hosts = hosts
|
373
|
+
else
|
374
|
+
modifier.datasets[dataset].replicas.hosts -= hosts
|
375
|
+
end
|
376
|
+
@service_installation.ensure_correct_file_permission(file)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
private
|
381
|
+
def unjoining_node?
|
382
|
+
hosts.include?(host)
|
364
383
|
end
|
365
384
|
end
|
366
385
|
|
@@ -52,6 +52,7 @@ module Droonga
|
|
52
52
|
|
53
53
|
@source_host = @params[:source_host]
|
54
54
|
@destination_host = @params[:destination_host]
|
55
|
+
@receiver_host = @params[:receiver_host] || @destination_host
|
55
56
|
|
56
57
|
@receiver_port = @params[:receiver_port]
|
57
58
|
end
|
@@ -115,7 +116,7 @@ module Droonga
|
|
115
116
|
:port => @port,
|
116
117
|
:tag => @tag,
|
117
118
|
:progocol => :droonga,
|
118
|
-
:receiver_host => @
|
119
|
+
:receiver_host => @receiver_host,
|
119
120
|
:receiver_port => 0,
|
120
121
|
}
|
121
122
|
@source_client ||= Droonga::Client.new(options)
|
@@ -127,7 +128,7 @@ module Droonga
|
|
127
128
|
:port => @port,
|
128
129
|
:tag => @tag,
|
129
130
|
:progocol => :droonga,
|
130
|
-
:receiver_host => @
|
131
|
+
:receiver_host => @receiver_host,
|
131
132
|
:receiver_port => 0,
|
132
133
|
}
|
133
134
|
@destination_client ||= Droonga::Client.new(options)
|
@@ -152,7 +153,7 @@ module Droonga
|
|
152
153
|
options += ["--port", @port]
|
153
154
|
options += ["--tag", @tag]
|
154
155
|
options += ["--dataset", @dataset]
|
155
|
-
options += ["--receiver-host", @
|
156
|
+
options += ["--receiver-host", @receiver_host]
|
156
157
|
options += ["--receiver-port", @receiver_port] if @receiver_port
|
157
158
|
options.collect(&:to_s)
|
158
159
|
end
|
@@ -162,7 +163,7 @@ module Droonga
|
|
162
163
|
options += ["--host", @destination_host]
|
163
164
|
options += ["--port", @port]
|
164
165
|
options += ["--tag", @tag]
|
165
|
-
options += ["--receiver-host", @
|
166
|
+
options += ["--receiver-host", @receiver_host]
|
166
167
|
options += ["--receiver-port", @receiver_port] if @receiver_port
|
167
168
|
options.collect(&:to_s)
|
168
169
|
end
|
@@ -252,7 +253,7 @@ module Droonga
|
|
252
253
|
fetcher = CatalogFetcher.new(:host => @source_host,
|
253
254
|
:port => @port,
|
254
255
|
:tag => @tag,
|
255
|
-
:receiver_host => @
|
256
|
+
:receiver_host => @receiver_host)
|
256
257
|
fetcher.fetch(:dataset => @dataset)
|
257
258
|
end
|
258
259
|
|
data/lib/droonga/serf.rb
CHANGED
@@ -71,6 +71,7 @@ module Droonga
|
|
71
71
|
"-event-handler", "droonga-engine-serf-event-handler",
|
72
72
|
"-log-level", log_level,
|
73
73
|
"-tag", "role=engine",
|
74
|
+
"-tag", "cluster_id=#{cluster_id}",
|
74
75
|
*retry_joins)
|
75
76
|
logger.trace("start: done")
|
76
77
|
end
|
@@ -87,6 +88,13 @@ module Droonga
|
|
87
88
|
logger.trace("stop: done")
|
88
89
|
end
|
89
90
|
|
91
|
+
def restart
|
92
|
+
logger.trace("restart: start")
|
93
|
+
stop
|
94
|
+
start
|
95
|
+
logger.trace("restart: done")
|
96
|
+
end
|
97
|
+
|
90
98
|
def join(*hosts)
|
91
99
|
ensure_serf
|
92
100
|
nodes = hosts.collect do |host|
|
@@ -123,8 +131,10 @@ module Droonga
|
|
123
131
|
result = run_once("members", "-format", "json")
|
124
132
|
result[:result] = JSON.parse(result[:result])
|
125
133
|
members = result[:result]
|
134
|
+
current_cluster_id = cluster_id
|
126
135
|
members["members"].each do |member|
|
127
|
-
if member["status"] == "alive"
|
136
|
+
if member["status"] == "alive" and
|
137
|
+
member["tags"]["cluster_id"] == current_cluster_id
|
128
138
|
nodes[member["name"]] = {
|
129
139
|
"serfAddress" => member["addr"],
|
130
140
|
"tags" => member["tags"],
|
@@ -134,6 +144,21 @@ module Droonga
|
|
134
144
|
nodes
|
135
145
|
end
|
136
146
|
|
147
|
+
def set_tag(name, value)
|
148
|
+
ensure_serf
|
149
|
+
run_once("tags", "-set", "#{name}=#{value}")
|
150
|
+
end
|
151
|
+
|
152
|
+
def update_cluster_id
|
153
|
+
set_tag("cluster_id", cluster_id)
|
154
|
+
end
|
155
|
+
|
156
|
+
def cluster_id
|
157
|
+
loader = CatalogLoader.new(Path.catalog.to_s)
|
158
|
+
catalog = loader.load
|
159
|
+
catalog.cluster_id
|
160
|
+
end
|
161
|
+
|
137
162
|
private
|
138
163
|
def ensure_serf
|
139
164
|
@serf = find_system_serf
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: droonga-engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Droonga Project
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: archive-zip
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.
|
61
|
+
version: 0.1.9
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.
|
68
|
+
version: 0.1.9
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: droonga-message-pack-packer
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|