ruster 0.0.2 → 0.0.3
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 +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