ruster 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +18 -1
- data/bin/ruster +56 -19
- data/ruster.gemspec +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c35baea7d1a295313170c4ef1345c6f22f872697
|
4
|
+
data.tar.gz: 76f8ba9ddf5ae1cf2cc5df865fe733770786fc21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef371dc30165f7284d3e0d1c1b250125320f675cc27391790195147f0ddd17d53b287ac130b10e23c1ffe48052fea74ca0cfebb641d4d0d0d86c5900ddf26609
|
7
|
+
data.tar.gz: d5c88f5c3cc8389231029ceea8a69153457056cc5c452eb1113b53a5c921d9d45d5df1b6dae60de1180b18fd0e0626aa78347a3f0ac765eb178f47010e6db5bf
|
data/README.md
CHANGED
@@ -44,7 +44,7 @@ node.
|
|
44
44
|
### Execute a command in all nodes
|
45
45
|
|
46
46
|
```
|
47
|
-
$ ruster
|
47
|
+
$ ruster each ip:port [CMD ...]
|
48
48
|
```
|
49
49
|
|
50
50
|
Executes the [Redis command][redis-commands] in all nodes, displaying
|
@@ -59,6 +59,23 @@ $ ruster reshard cluster_ip:port slots target_ip:port source_ip:port [...]
|
|
59
59
|
Reshards the cluster at `cluster_ip:port`, by moving `slots` slots
|
60
60
|
from several `source_ip:port` to `target_ip:port`.
|
61
61
|
|
62
|
+
It accepts the following parameters:
|
63
|
+
|
64
|
+
* `-n` indicate destination DB (currently only `0` seem to be working)
|
65
|
+
* `-t` indicate timeout for [`MIGRATE`][migrate] keys
|
66
|
+
|
67
|
+
[migrate]: http://redis.io/commands/migrate
|
68
|
+
|
69
|
+
### Global parameters
|
70
|
+
|
71
|
+
`ruster` accepts the following global parameters:
|
72
|
+
|
73
|
+
* `-v` verbose output. It could be used multiple times, to indicate
|
74
|
+
the level of verbosity.
|
75
|
+
|
76
|
+
1. display log messages
|
77
|
+
1. display Redis commands sent to the cluster
|
78
|
+
|
62
79
|
## TODO
|
63
80
|
|
64
81
|
* documentation
|
data/bin/ruster
CHANGED
@@ -4,14 +4,42 @@ require "redic"
|
|
4
4
|
require "clap"
|
5
5
|
|
6
6
|
$verbose = 0
|
7
|
-
$timeout = 10_000_000
|
8
7
|
|
9
|
-
action, *args = Clap.run ARGV, {
|
10
|
-
"-v" => -> { $verbose += 1 },
|
11
|
-
"-t" => ->(ms) { $timeout = ms }
|
12
|
-
}
|
8
|
+
action, *args = Clap.run ARGV, "-v" => -> { $verbose += 1 }
|
13
9
|
|
14
|
-
|
10
|
+
USAGE = <<EOU
|
11
|
+
Usage: #{File.basename($0)} [-v] <action> ip:port [...]
|
12
|
+
|
13
|
+
Parameters
|
14
|
+
|
15
|
+
-v Increases verbosity level. Can be used more than once.
|
16
|
+
|
17
|
+
Actions
|
18
|
+
|
19
|
+
create ip:port [ip:port...]
|
20
|
+
Creates a cluster with all the passed nodes
|
21
|
+
|
22
|
+
add cluster_ip:port ip:port
|
23
|
+
Add node ip:port to the cluster at cluster_ip:port
|
24
|
+
|
25
|
+
remove cluster_ip:port ip:port
|
26
|
+
Remove node from the cluster at cluster_ip:port
|
27
|
+
Note that currently removing a node that has assigned
|
28
|
+
slots breaks the cluster state.
|
29
|
+
|
30
|
+
each cluster_ip:port CMD...
|
31
|
+
Execute Redis CMD in all nodes
|
32
|
+
|
33
|
+
reshard cluster_ip:port slots target_ip:port source_ip:port...
|
34
|
+
Reshards `slots` slots into target_ip:port, taking slots
|
35
|
+
proportionally from all the nodes in source_ip:port
|
36
|
+
|
37
|
+
Accepts `-n n` to indicate a destination DB
|
38
|
+
Accepts `-t ms` to indicate timeout for keys migration
|
39
|
+
|
40
|
+
EOU
|
41
|
+
|
42
|
+
abort USAGE if action.nil? or args.nil? or args.empty?
|
15
43
|
|
16
44
|
module UI
|
17
45
|
def err msg
|
@@ -214,7 +242,7 @@ class Cluster
|
|
214
242
|
end
|
215
243
|
end
|
216
244
|
|
217
|
-
def
|
245
|
+
def each(*args)
|
218
246
|
nodes!.each do |node|
|
219
247
|
UI.info "#{node}: #{args.join(' ')}"
|
220
248
|
|
@@ -224,7 +252,9 @@ class Cluster
|
|
224
252
|
end
|
225
253
|
end
|
226
254
|
|
227
|
-
def reshard(target_addr, slots, sources)
|
255
|
+
def reshard(target_addr, slots, sources, opts={})
|
256
|
+
options = { timeout: 1_000, db: 0 }.merge(opts)
|
257
|
+
|
228
258
|
target = Node.new(target_addr)
|
229
259
|
|
230
260
|
from = sources.map{ |addr| Node.new(addr) } \
|
@@ -234,6 +264,8 @@ class Cluster
|
|
234
264
|
sum + source.slots[:slots].size
|
235
265
|
end
|
236
266
|
|
267
|
+
UI.abort "No slots found to migrate" unless total_slots > 0
|
268
|
+
|
237
269
|
from.each do |source|
|
238
270
|
# Proportional number of slots, based on current assigned slots
|
239
271
|
node_slots = (slots.to_f / total_slots * source.slots[:slots].size).to_i
|
@@ -241,7 +273,9 @@ class Cluster
|
|
241
273
|
UI.info "Moving #{node_slots} slots from #{source} to #{target}"
|
242
274
|
|
243
275
|
source.slots[:slots].take(node_slots).each do |slot|
|
244
|
-
|
276
|
+
count = source.call("CLUSTER", "COUNTKEYSINSLOT", slot)
|
277
|
+
|
278
|
+
UI.log " Moving slot #{slot} (#{count} keys)"
|
245
279
|
|
246
280
|
target.call("CLUSTER", "SETSLOT", slot, "IMPORTING", source.id)
|
247
281
|
source.call("CLUSTER", "SETSLOT", slot, "MIGRATING", target.id)
|
@@ -254,9 +288,11 @@ class Cluster
|
|
254
288
|
done = keys.empty?
|
255
289
|
|
256
290
|
keys.each do |key|
|
257
|
-
res = source.call("MIGRATE", target.ip, target.port, key,
|
291
|
+
res = source.call("MIGRATE", target.ip, target.port, key, options[:db], options[:timeout])
|
258
292
|
|
259
293
|
UI.abort res.message if res.is_a?(RuntimeError)
|
294
|
+
|
295
|
+
$stdout.print '.' if $verbose > 2
|
260
296
|
end
|
261
297
|
end
|
262
298
|
|
@@ -287,22 +323,23 @@ begin
|
|
287
323
|
args.each do |addr|
|
288
324
|
cluster.remove_node(Node.new(addr))
|
289
325
|
end
|
290
|
-
when "
|
326
|
+
when "each"
|
291
327
|
cluster = Cluster.new(args.shift)
|
292
328
|
|
293
|
-
cluster.
|
329
|
+
cluster.each(*args)
|
294
330
|
when "reshard"
|
295
|
-
|
296
|
-
|
297
|
-
slots = Integer(args.shift)
|
331
|
+
options = {}
|
298
332
|
|
299
|
-
|
333
|
+
cluster_addr, slots, target_addr, *sources = Clap.run args, {
|
334
|
+
"-t" => ->(ms) { options[:timeout] = Integer(ms) },
|
335
|
+
"-n" => ->(db) { options[:db] = db }
|
336
|
+
}
|
300
337
|
|
301
|
-
|
338
|
+
cluster = Cluster.new(cluster_addr)
|
302
339
|
|
303
|
-
cluster.reshard(
|
340
|
+
cluster.reshard(target_addr, slots, sources, options)
|
304
341
|
else
|
305
|
-
UI.abort "Unrecognized action
|
342
|
+
UI.abort "Unrecognized action `#{action}'\n#{USAGE}"
|
306
343
|
end
|
307
344
|
rescue => ex
|
308
345
|
UI.abort ex.message, ex.backtrace
|
data/ruster.gemspec
CHANGED