0x00--背景和目的
在单台PC服务器上部署Redis集群,通过不同的TCP端口启动多实例,模拟多台独立PC组成集群。
0x01--环境描述:
1 Centos版本:CentOS Linux release 7.4.1708 (Core)
2 Redis版本:Redis 4.0.10 (00000000/0) 64 bit
3 安装方式:源码安装
0x02--编辑Redis实例配置文件
在根目录下新建/redis_cluster目录,用于存放多实例配置文件,这里使用6个TCP端口,编写6029--6034共计6个配置文件,使用折6个配置文件启动实例,并搭建Redis集群。
1 port 6029 ##端口号,用于模拟不同主机不同实例,6029,6030,6031,6032,6033,6034
2 bind 10.118.128.223 ##实例IP地址,默认为127.0.0.1,根据实际情况修改,集群节点间需要保证IP地址能相互通讯,网络层面需要放开相应端口的访问权限
3 daemonize yes ##允许Redis后台运行
4 pidfile /redis_cluster/redis_6029.pid ##pidfile 文件,每个实例一个,分别对应6029.6030.6031,6032,6033,6034
5 cluster-enabled yes ##开启集群cluster
6 cluster-config-file nodes_6029.conf ##集群配置文件
7 cluster-node-timeout 15000 ##请求超时时长,默认15秒,可依据网络情况自行修改配置
0x03--启动多个Redis实例
1 [root@centos7 6030]# redis-server /redis_cluster/6029/redis.conf
2 21267:C 29 Jun 16:45:41.271 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
3 21267:C 29 Jun 16:45:41.271 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21267, just started
4 21267:C 29 Jun 16:45:41.271 # Configuration loaded
5 [root@centos7 6030]# redis-server /redis_cluster/6030/redis.conf
6 21272:C 29 Jun 16:45:47.325 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7 21272:C 29 Jun 16:45:47.325 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21272, just started
8 21272:C 29 Jun 16:45:47.325 # Configuration loaded
9 [root@centos7 6030]# redis-server /redis_cluster/6031/redis.conf
10 21277:C 29 Jun 16:45:50.637 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
11 21277:C 29 Jun 16:45:50.637 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21277, just started
12 21277:C 29 Jun 16:45:50.637 # Configuration loaded
13 [root@centos7 6030]# redis-server /redis_cluster/6032/redis.conf
14 21282:C 29 Jun 16:45:53.938 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
15 21282:C 29 Jun 16:45:53.939 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21282, just started
16 21282:C 29 Jun 16:45:53.939 # Configuration loaded
17 [root@centos7 6030]# redis-server /redis_cluster/6033/redis.conf
18 21287:C 29 Jun 16:45:57.490 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
19 21287:C 29 Jun 16:45:57.490 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21287, just started
20 21287:C 29 Jun 16:45:57.490 # Configuration loaded
21 [root@centos7 6030]# redis-server /redis_cluster/6034/redis.conf
22 21292:C 29 Jun 16:46:00.787 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
23 21292:C 29 Jun 16:46:00.788 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=21292, just started
24 21292:C 29 Jun 16:46:00.788 # Configuration loaded
查看进程,可看到已经有6个Redis实例启动,且端口号也可以明显看到
1 [root@centos7 src]# ps -ef|grep redis|grep cluster
2 root 21268 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6029 [cluster]
3 root 21273 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6030 [cluster]
4 root 21278 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6031 [cluster]
5 root 21283 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6032 [cluster]
6 root 21288 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6033 [cluster]
7 root 21293 1 0 16:45 ? 00:00:03 redis-server 10.118.128.223:6034 [cluster]
0x04--配置Ruby环境-redis-trib.rb脚本
Redis3.0以后开始支持集群功能,官方推出了一个管理redis集群的工具--一个ruby脚本:redis-trib.rb
该脚本集成在redis的源码SRC目录下,所以,需要系统安装配置ruby环境,才能使用该脚本进行Redis集群的创建、配置和管理。
以下是该脚本的内容,仅供学习参考,redis版本为4.0.10


1 [root@centos7 src]# cat redis-trib.rb
2 #!/usr/bin/env ruby
3
4 # TODO (temporary here, we'll move this into the Github issues once
5 # redis-trib initial implementation is completed).
6 #
7 # - Make sure that if the rehashing fails in the middle redis-trib will try
8 # to recover.
9 # - When redis-trib performs a cluster check, if it detects a slot move in
10 # progress it should prompt the user to continue the move from where it
11 # stopped.
12 # - Gracefully handle Ctrl+C in move_slot to prompt the user if really stop
13 # while rehashing, and performing the best cleanup possible if the user
14 # forces the quit.
15 # - When doing "fix" set a global Fix to true, and prompt the user to
16 # fix the problem if automatically fixable every time there is something
17 # to fix. For instance:
18 # 1) If there is a node that pretend to receive a slot, or to migrate a
19 # slot, but has no entries in that slot, fix it.
20 # 2) If there is a node having keys in slots that are not owned by it
21 # fix this condition moving the entries in the same node.
22 # 3) Perform more possibly slow tests about the state of the cluster.
23 # 4) When aborted slot migration is detected, fix it.
24
25 require 'rubygems'
26 require 'redis'
27
28 ClusterHashSlots = 16384
29 MigrateDefaultTimeout = 60000
30 MigrateDefaultPipeline = 10
31 RebalanceDefaultThreshold = 2
32
33 $verbose = false
34
35 def xputs(s)
36 case s[0..2]
37 when ">>>"
38 color="29;1"
39 when "[ER"
40 color="31;1"
41 when "[WA"
42 color="31;1"
43 when "[OK"
44 color="32"
45 when "[FA","***"
46 color="33"
47 else
48 color=nil
49 end
50
51 color = nil if ENV['TERM'] != "xterm"
52 print "\033[#{color}m" if color
53 print s
54 print "\033[0m" if color
55 print "\n"
56 end
57
58 class ClusterNode
59 def initialize(addr)
60 s = addr.split("@")[0].split(":")
61 if s.length < 2
62 puts "Invalid IP or Port (given as #{addr}) - use IP:Port format"
63 exit 1
64 end
65 port = s.pop # removes port from split array
66 ip = s.join(":") # if s.length > 1 here, it's IPv6, so restore address
67 @r = nil
68 @info = {}
69 @info[:host] = ip
70 @info[:port] = port
71 @info[:slots] = {}
72 @info[:migrating] = {}
73 @info[:importing] = {}
74 @info[:replicate] = false
75 @dirty = false # True if we need to flush slots info into node.
76 @friends = []
77 end
78
79 def friends
80 @friends
81 end
82
83 def slots
84 @info[:slots]
85 end
86
87 def has_flag?(flag)
88 @info[:flags].index(flag)
89 end
90
91 def to_s
92 "#{@info[:host]}:#{@info[:port]}"
93 end
94
95 def connect(o={})
96 return if @r
97 print "Connecting to node #{self}: " if $verbose
98 STDOUT.flush
99 begin
100 @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60)
101 @r.ping
102 rescue
103 xputs "[ERR] Sorry, can't connect to node #{self}"
104 exit 1 if o[:abort]
105 @r = nil
106 end
107 xputs "OK" if $verbose
108 end
109
110 def assert_cluster
111 info = @r.info
112 if !info["cluster_enabled"] || info["cluster_enabled"].to_i == 0
113 xputs "[ERR] Node #{self} is not configured as a cluster node."
114 exit 1
115 end
116 end
117
118 def assert_empty
119 if !(@r.cluster("info").split("\r\n").index("cluster_known_nodes:1")) ||
120 (@r.info['db0'])
121 0."
122 exit 1
123 end
124 end
125
126 def load_info(o={})
127 self.connect
128 nodes = @r.cluster("nodes").split("\n")
129 nodes.each{|n|
130 # name addr flags role ping_sent ping_recv link_status slots
131 split = n.split
132 name,addr,flags,master_id,ping_sent,ping_recv,config_epoch,link_status = split[0..6]
133 slots = split[8..-1]
134 info = {
135 :name => name,
136 :addr => addr,
137 :flags => flags.split(","),
138 :replicate => master_id,
139 :ping_sent => ping_sent.to_i,
140 :ping_recv => ping_recv.to_i,
141 :link_status => link_status
142 }
143 info[:replicate] = false if master_id == "-"
144
145 if info[:flags].index("myself")
146 @info = @info.merge(info)
147 @info[:slots] = {}
148 slots.each{|s|
149 if s[0..0] == '['
150 if s.index("->-") # Migrating
151 slot,dst = s[1..-1].split("->-")
152 @info[:migrating][slot.to_i] = dst
153 elsif s.index("-<-") # Importing
154 slot,src = s[1..-1].split("-<-")
155 @info[:importing][slot.to_i] = src
156 end
157 elsif s.index("-")
158 start,stop = s.split("-")
159 self.add_slots((start.to_i)..(stop.to_i))
160 else
161 self.add_slots((s.to_i)..(s.to_i))
162 end
163 } if slots
164 @dirty = false
165 @r.cluster("info").split("\n").each{|e|
166 k,v=e.split(":")
167 k = k.to_sym
168 v.chop!
169 if k != :cluster_state
170 @info[k] = v.to_i
171 else
172 @info[k] = v
173 end
174 }
175 elsif o[:getfriends]
176 @friends << info
177 end
178 }
179 end
180
181 def add_slots(slots)
182 slots.each{|s|
183 @info[:slots][s] = :new
184 }
185 @dirty = true
186 end
187
188 def set_as_replica(node_id)
189 @info[:replicate] = node_id
190 @dirty = true
191 end
192
193 def flush_node_config
194 return if !@dirty
195 if @info[:replicate]
196 begin
197 @r.cluster("replicate",@info[:replicate])
198 rescue
199 # If the cluster did not already joined it is possible that
200 # the slave does not know the master node yet. So on errors
201 # we return ASAP leaving the dirty flag set, to flush the
202 # config later.
203 return
204 end
205 else
206 new = []
207 @info[:slots].each{|s,val|
208 if val == :new
209 new << s
210 @info[:slots][s] = true
211 end
212 }
213 @r.cluster("addslots",*new)
214 end
215 @dirty = false
216 end
217
218 def info_string
219 # We want to display the hash slots assigned to this node
220 # as ranges, like in: "1-5,8-9,20-25,30"
221 #
222 # Note: this could be easily written without side effects,
223 # we use 'slots' just to split the computation into steps.
224
225 # First step: we want an increasing array of integers
226 # for instance: [1,2,3,4,5,8,9,20,21,22,23,24,25,30]
227 slots = @info[:slots].keys.sort
228
229 # As we want to aggregate adjacent slots we convert all the
230 # slot integers into ranges (with just one element)
231 # So we have something like [1..1,2..2, ... and so forth.
232 slots.map!{|x| x..x}
233
234 # Finally we group ranges with adjacent elements.
235 slots = slots.reduce([]) {|a,b|
236 if !a.empty? && b.first == (a[-1].last)+1
237 a[0..-2] + [(a[-1].first)..(b.last)]
238 else
239 a + [b]
240 end
241 }
242
243 # Now our task is easy, we just convert ranges with just one
244 # element into a number, and a real range into a start-end format.
245 # Finally we join the array using the comma as separator.
246 slots = slots.map{|x|
247 x.count == 1 ? x.first.to_s : "#{x.first}-#{x.last}"
248 }.join(",")
249
250 role = self.has_flag?("master") ? "M" : "S"
251
252 if self.info[:replicate] and @dirty
253 is = "S: #{self.info[:name]} #{self.to_s}"
254 else
255 is = "#{role}: #{self.info[:name]} #{self.to_s}\n"+
256 " slots:#{slots} (#{self.slots.length} slots) "+
257 "#{(self.info[:flags]-["myself"]).join(",")}"
258 end
259 if self.info[:replicate]
260 is += "\n replicates #{info[:replicate]}"
261 elsif self.has_flag?("master") && self.info[:replicas]
262 is += "\n #{info[:replicas].length} additional replica(s)"
263 end
264 is
265 end
266
267 # Return a single string representing nodes and associated slots.
268 # TODO: remove slaves from config when slaves will be handled
269 # by Redis Cluster.
270 def get_config_signature
271 config = []
272 @r.cluster("nodes").each_line{|l|
273 s = l.split
274 slots = s[8..-1].select {|x| x[0..0] != "["}
275 next if slots.length == 0
276 config << s[0]+":"+(slots.sort.join(","))
277 }
278 config.sort.join("|")
279 end
280
281 def info
282 @info
283 end
284
285 def is_dirty?
286 @dirty
287 end
288
289 def r
290 @r
291 end
292 end
293
294 class RedisTrib
295 def initialize
296 @nodes = []
297 @fix = false
298 @errors = []
299 @timeout = MigrateDefaultTimeout
300 end
301
302 def check_arity(req_args, num_args)
303 if ((req_args > 0 and num_args != req_args) ||
304 (req_args < 0 and num_args < req_args.abs))
305 xputs "[ERR] Wrong number of arguments for specified sub command"
306 exit 1
307 end
308 end
309
310 def add_node(node)
311 @nodes << node
312 end
313
314 def reset_nodes
315 @nodes = []
316 end
317
318 def cluster_error(msg)
319 @errors << msg
320 xputs msg
321 end
322
323 # Return the node with the specified ID or Nil.
324 def get_node_by_name(name)
325 @nodes.each{|n|
326 return n if n.info[:name] == name.downcase
327 }
328 return nil
329 end
330
331 # Like get_node_by_name but the specified name can be just the first
332 # part of the node ID as long as the prefix in unique across the
333 # cluster.
334 def get_node_by_abbreviated_name(name)
335 l = name.length
336 candidates = []
337 @nodes.each{|n|
338 if n.info[:name][0...l] == name.downcase
339 candidates << n
340 end
341 }
342 return nil if candidates.length != 1
343 candidates[0]
344 end
345
346 # This function returns the master that has the least number of replicas
347 # in the cluster. If there are multiple masters with the same smaller
348 # number of replicas, one at random is returned.
349 def get_master_with_least_replicas
350 masters = @nodes.select{|n| n.has_flag? "master"}
351 sorted = masters.sort{|a,b|
352 a.info[:replicas].length <=> b.info[:replicas].length
353 }
354 sorted[0]
355 end
356
357 def check_cluster(opt={})
358 xputs ">>> Performing Cluster Check (using node #{@nodes[0]})"
359 show_nodes if !opt[:quiet]
360 check_config_consistency
361 check_open_slots
362 check_slots_coverage
363 end
364
365 def show_cluster_info
366 masters = 0
367 keys = 0
368 @nodes.each{|n|
369 if n.has_flag?("master")
370 puts "#{n} (#{n.info[:name][0...8]}...) -> #{n.r.dbsize} keys | #{n.slots.length} slots | "+
371 "#{n.info[:replicas].length} slaves."
372 masters += 1
373 keys += n.r.dbsize
374 end
375 }
376 xputs "[OK] #{keys} keys in #{masters} masters."
377 keys_per_slot = sprintf("%.2f",keys/16384.0)
378 puts "#{keys_per_slot} keys per slot on average."
379 end
380
381 # Merge slots of every known node. If the resulting slots are equal
382 # to ClusterHashSlots, then all slots are served.
383 def covered_slots
384 slots = {}
385 @nodes.each{|n|
386 slots = slots.merge(n.slots)
387 }
388 slots
389 end
390
391 def check_slots_coverage
392 xputs ">>> Check slots coverage..."
393 slots = covered_slots
394 if slots.length == ClusterHashSlots
395 xputs "[OK] All #{ClusterHashSlots} slots covered."
396 else
397 cluster_error \
398 "[ERR] Not all #{ClusterHashSlots} slots are covered by nodes."
399 fix_slots_coverage if @fix
400 end
401 end
402
403 def check_open_slots
404 xputs ">>> Check for open slots..."
405 open_slots = []
406 @nodes.each{|n|
407 if n.info[:migrating].size > 0
408 cluster_error \
409 "[WARNING] Node #{n} has slots in migrating state (#{n.info[:migrating].keys.join(",")})."
410 open_slots += n.info[:migrating].keys
411 end
412 if n.info[:importing].size > 0
413 cluster_error \
414 "[WARNING] Node #{n} has slots in importing state (#{n.info[:importing].keys.join(",")})."
415 open_slots += n.info[:importing].keys
416 end
417 }
418 open_slots.uniq!
419 if open_slots.length > 0
420 xputs "[WARNING] The following slots are open: #{open_slots.join(",")}"
421 end
422 if @fix
423 open_slots.each{|slot| fix_open_slot slot}
424 end
425 end
426
427 def nodes_with_keys_in_slot(slot)
428 nodes = []
429 @nodes.each{|n|
430 next if n.has_flag?("slave")
431 nodes << n if n.r.cluster("getkeysinslot",slot,1).length > 0
432 }
433 nodes
434 end
435
436 def fix_slots_coverage
437 not_covered = (0...ClusterHashSlots).to_a - covered_slots.keys
438 xputs ">>> Fixing slots coverage..."
439 xputs "List of not covered slots: " + not_covered.join(",")
440
441 # For every slot, take action depending on the actual condition:
442 # 1) No node has keys for this slot.
443 # 2) A single node has keys for this slot.
444 # 3) Multiple nodes have keys for this slot.
445 slots = {}
446 not_covered.each{|slot|
447 nodes = nodes_with_keys_in_slot(slot)
448 slots[slot] = nodes
449 xputs "Slot #{slot} has keys in #{nodes.length} nodes: #{nodes.join(", ")}"
450 }
451
452 none = slots.select {|k,v| v.length == 0}
453 single = slots.select {|k,v| v.length == 1}
454 multi = slots.select {|k,v| v.length > 1}
455
456 # Handle case "1": keys in no node.
457 if none.length > 0
458 xputs "The folowing uncovered slots have no keys across the cluster:"
459 xputs none.keys.join(",")
460 yes_or_die "Fix these slots by covering with a random node?"
461 none.each{|slot,nodes|
462 node = @nodes.sample
463 xputs ">>> Covering slot #{slot} with #{node}"
464 node.r.cluster("addslots",slot)
465 }
466 end
467
468 # Handle case "2": keys only in one node.
469 if single.length > 0
470 xputs "The folowing uncovered slots have keys in just one node:"
471 puts single.keys.join(",")
472 yes_or_die "Fix these slots by covering with those nodes?"
473 single.each{|slot,nodes|
474 xputs ">>> Covering slot #{slot} with #{nodes[0]}"
475 nodes[0].r.cluster("addslots",slot)
476 }
477 end
478
479 # Handle case "3": keys in multiple nodes.
480 if multi.length > 0
481 xputs "The folowing uncovered slots have keys in multiple nodes:"
482 xputs multi.keys.join(",")
483 yes_or_die "Fix these slots by moving keys into a single node?"
484 multi.each{|slot,nodes|
485 target = get_node_with_most_keys_in_slot(nodes,slot)
486 xputs ">>> Covering slot #{slot} moving keys to #{target}"
487
488 target.r.cluster('addslots',slot)
489 target.r.cluster('setslot',slot,'stable')
490 nodes.each{|src|
491 next if src == target
492 # Set the source node in 'importing' state (even if we will
493 # actually migrate keys away) in order to avoid receiving
494 # redirections for MIGRATE.
495 src.r.cluster('setslot',slot,'importing',target.info[:name])
496 move_slot(src,target,slot,:dots=>true,:fix=>true,:cold=>true)
497 src.r.cluster('setslot',slot,'stable')
498 }
499 }
500 end
501 end
502
503 # Return the owner of the specified slot
504 def get_slot_owners(slot)
505 owners = []
506 @nodes.each{|n|
507 next if n.has_flag?("slave")
508 n.slots.each{|s,_|
509 owners << n if s == slot
510 }
511 }
512 owners
513 end
514
515 # Return the node, among 'nodes' with the greatest number of keys
516 # in the specified slot.
517 def get_node_with_most_keys_in_slot(nodes,slot)
518 best = nil
519 best_numkeys = 0
520 @nodes.each{|n|
521 next if n.has_flag?("slave")
522 numkeys = n.r.cluster("countkeysinslot",slot)
523 if numkeys > best_numkeys || best == nil
524 best = n
525 best_numkeys = numkeys
526 end
527 }
528 return best
529 end
530
531 # Slot 'slot' was found to be in importing or migrating state in one or
532 # more nodes. This function fixes this condition by migrating keys where
533 # it seems more sensible.
534 def fix_open_slot(slot)
535 puts ">>> Fixing open slot #{slot}"
536
537 # Try to obtain the current slot owner, according to the current
538 # nodes configuration.
539 owners = get_slot_owners(slot)
540 owner = owners[0] if owners.length == 1
541
542 migrating = []
543 importing = []
544 @nodes.each{|n|
545 next if n.has_flag? "slave"
546 if n.info[:migrating][slot]
547 migrating << n
548 elsif n.info[:importing][slot]
549 importing << n
550 elsif n.r.cluster("countkeysinslot",slot) > 0 && n != owner
551 xputs "*** Found keys about slot #{slot} in node #{n}!"
552 importing << n
553 end
554 }
555 puts "Set as migrating in: #{migrating.join(",")}"
556 puts "Set as importing in: #{importing.join(",")}"
557
558 # If there is no slot owner, set as owner the slot with the biggest
559 # number of keys, among the set of migrating / importing nodes.
560 if !owner
561 xputs ">>> Nobody claims ownership, selecting an owner..."
562 owner = get_node_with_most_keys_in_slot(@nodes,slot)
563
564 # If we still don't have an owner, we can't fix it.
565 if !owner
566 xputs "[ERR] Can't select a slot owner. Impossible to fix."
567 exit 1
568 end
569
570 # Use ADDSLOTS to assign the slot.
571 puts "*** Configuring #{owner} as the slot owner"
572 owner.r.cluster("setslot",slot,"stable")
573 owner.r.cluster("addslots",slot)
574 # Make sure this information will propagate. Not strictly needed
575 # since there is no past owner, so all the other nodes will accept
576 # whatever epoch this node will claim the slot with.
577 owner.r.cluster("bumpepoch")
578
579 # Remove the owner from the list of migrating/importing
580 # nodes.
581 migrating.delete(owner)
582 importing.delete(owner)
583 end
584
585 # If there are multiple owners of the slot, we need to fix it
586 # so that a single node is the owner and all the other nodes
587 # are in importing state. Later the fix can be handled by one
588 # of the base cases above.
589 #
590 # Note that this case also covers multiple nodes having the slot
591 # in migrating state, since migrating is a valid state only for
592 # slot owners.
593 if owners.length > 1
594 owner = get_node_with_most_keys_in_slot(owners,slot)
595 owners.each{|n|
596 next if n == owner
597 n.r.cluster('delslots',slot)
598 n.r.cluster('setslot',slot,'importing',owner.info[:name])
599 importing.delete(n) # Avoid duplciates
600 importing << n
601 }
602 owner.r.cluster('bumpepoch')
603 end
trib.rb脚本使用帮助:
1 [root@centos7 src]# ./redis-trib.rb help
2 Usage: redis-trib <command> <options> <arguments ...>
3
4 create host1:port1 ... hostN:portN ##创建集群
5 --replicas <arg> ##replicas参数指定当前创建的redis集群有几个Slave节点
6 check host:port ##检查集群,验证节点可用性
7 info host:port ##查看集群信息,节点信息
8 fix host:port ##修复集群
9 --timeout <arg>
10 reshard host:port ##在线迁移集群,from A to B
11 --from <arg>
12 --to <arg>
13 --slots <arg>
14 --yes
15 --timeout <arg>
16 --pipeline <arg>
17 rebalance host:port ##平衡集群节点slot数量
18 --weight <arg>
19 --auto-weights
20 --use-empty-masters
21 --timeout <arg>
22 --simulate
23 --pipeline <arg>
24 --threshold <arg>
25 add-node new_host:new_port existing_host:existing_port ##在线添加新的集群节点
26 --slave
27 --master-id <arg>
28 del-node host:port node_id ##在线删除集群节点
29 set-timeout host:port milliseconds ##redis集群节点心跳超时参数设置,默认15秒
30 call host:port command arg arg .. arg ##使命令在所有节点一起执行,慎用该参数
31 import host:port ##将外部Redis节点数据导入集群
32 --from <arg>
33 --copy
34 --replace
35 help (show this help) ##显示脚本使用帮助
36
37 For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
38 [root@centos7 src]#
0x05--配置Ruby环境-安装Ruby
注意:redis-trib.rb的运行需要的ruby包,Ruby版本至少需要2.2,否则在安装时会出现如下报错,可以自行下载2.2.2版本以上的Ruby进行安装,也可以参照码上青天的博文进行在线升级
1 [root@centos7 6030]# gem install redis
2 Fetching: redis-4.0.1.gem (100%)
3 ERROR: Error installing redis:
4 redis requires Ruby version >= 2.2.2.


[root@centos7 6030]# yum install -y ruby ruby-devel rubygems rpm-build
Loaded plugins: fastestmirror, langpacks
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
percona-release-noarch | 2.9 kB 00:00:00
percona-release-x86_64 | 2.9 kB 00:00:00
(1/3): extras/7/x86_64/primary_db | 149 kB 00:00:00
(2/3): percona-release-noarch/7/primary_db | 15 kB 00:00:01
(3/3): percona-release-x86_64/7/x86_64/primary_db | 784 kB 00:00:02
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package rpm-build.x86_64 0:4.11.3-32.el7 will be installed
--> Processing Dependency: rpm = 4.11.3-32.el7 for package: rpm-build-4.11.3-32.el7.x86_64
--> Processing Dependency: patch >= 2.5 for package: rpm-build-4.11.3-32.el7.x86_64
--> Processing Dependency: system-rpm-config for package: rpm-build-4.11.3-32.el7.x86_64
--> Processing Dependency: perl(Thread::Queue) for package: rpm-build-4.11.3-32.el7.x86_64
---> Package ruby.x86_64 0:2.0.0.648-33.el7_4 will be installed
--> Processing Dependency: ruby-libs(x86-64) = 2.0.0.648-33.el7_4 for package: ruby-2.0.0.648-33.el7_4.x86_64
--> Processing Dependency: rubygem(bigdecimal) >= 1.2.0 for package: ruby-2.0.0.648-33.el7_4.x86_64
--> Processing Dependency: libruby.so.2.0()(64bit) for package: ruby-2.0.0.648-33.el7_4.x86_64
---> Package ruby-devel.x86_64 0:2.0.0.648-33.el7_4 will be installed
---> Package rubygems.noarch 0:2.0.14.1-33.el7_4 will be installed
--> Processing Dependency: rubygem(rdoc) >= 4.0.0 for package: rubygems-2.0.14.1-33.el7_4.noarch
--> Processing Dependency: rubygem(psych) >= 2.0.0 for package: rubygems-2.0.14.1-33.el7_4.noarch
--> Processing Dependency: rubygem(io-console) >= 0.4.2 for package: rubygems-2.0.14.1-33.el7_4.noarch
--> Running transaction check
---> Package patch.x86_64 0:2.7.1-10.el7_5 will be installed
---> Package perl-Thread-Queue.noarch 0:3.02-2.el7 will be installed
---> Package redhat-rpm-config.noarch 0:9.1.0-80.el7.centos will be installed
--> Processing Dependency: dwz >= 0.4 for package: redhat-rpm-config-9.1.0-80.el7.centos.noarch
--> Processing Dependency: perl-srpm-macros for package: redhat-rpm-config-9.1.0-80.el7.centos.noarch
---> Package rpm.x86_64 0:4.11.3-25.el7 will be updated
--> Processing Dependency: rpm = 4.11.3-25.el7 for package: rpm-libs-4.11.3-25.el7.x86_64
--> Processing Dependency: rpm = 4.11.3-25.el7 for package: rpm-python-4.11.3-25.el7.x86_64
---> Package rpm.x86_64 0:4.11.3-32.el7 will be an update
---> Package ruby-libs.x86_64 0:2.0.0.648-33.el7_4 will be installed
---> Package rubygem-bigdecimal.x86_64 0:1.2.0-33.el7_4 will be installed
---> Package rubygem-io-console.x86_64 0:0.4.2-33.el7_4 will be installed
---> Package rubygem-psych.x86_64 0:2.0.0-33.el7_4 will be installed
--> Processing Dependency: libyaml-0.so.2()(64bit) for package: rubygem-psych-2.0.0-33.el7_4.x86_64
---> Package rubygem-rdoc.noarch 0:4.0.0-33.el7_4 will be installed
--> Processing Dependency: ruby(irb) = 2.0.0.648 for package: rubygem-rdoc-4.0.0-33.el7_4.noarch
--> Processing Dependency: rubygem(json) >= 1.7.7 for package: rubygem-rdoc-4.0.0-33.el7_4.noarch
--> Running transaction check
---> Package dwz.x86_64 0:0.11-3.el7 will be installed
---> Package libyaml.x86_64 0:0.1.4-11.el7_0 will be installed
---> Package perl-srpm-macros.noarch 0:1-8.el7 will be installed
---> Package rpm-libs.x86_64 0:4.11.3-25.el7 will be updated
--> Processing Dependency: rpm-libs(x86-64) = 4.11.3-25.el7 for package: rpm-build-libs-4.11.3-25.el7.x86_64
---> Package rpm-libs.x86_64 0:4.11.3-32.el7 will be an update
---> Package rpm-python.x86_64 0:4.11.3-25.el7 will be updated
---> Package rpm-python.x86_64 0:4.11.3-32.el7 will be an update
---> Package ruby-irb.noarch 0:2.0.0.648-33.el7_4 will be installed
---> Package rubygem-json.x86_64 0:1.7.7-33.el7_4 will be installed
--> Running transaction check
---> Package rpm-build-libs.x86_64 0:4.11.3-25.el7 will be updated
---> Package rpm-build-libs.x86_64 0:4.11.3-32.el7 will be an update
--> Finished Dependency Resolution
Dependencies Resolved
=======================================================================================================================
Package Arch Version Repository Size
=======================================================================================================================
Installing:
rpm-build x86_64 4.11.3-32.el7 base 147 k
ruby x86_64 2.0.0.648-33.el7_4 base 71 k
ruby-devel x86_64 2.0.0.648-33.el7_4 base 131 k
rubygems noarch 2.0.14.1-33.el7_4 base 219 k
Installing for dependencies:
dwz x86_64 0.11-3.el7 base 99 k
libyaml x86_64 0.1.4-11.el7_0 base 55 k
patch x86_64 2.7.1-10.el7_5 updates 110 k
perl-Thread-Queue noarch 3.02-2.el7 base 17 k
perl-srpm-macros noarch 1-8.el7 base 4.6 k
redhat-rpm-config noarch 9.1.0-80.el7.centos base 79 k
ruby-irb noarch 2.0.0.648-33.el7_4 base 92 k
ruby-libs x86_64 2.0.0.648-33.el7_4 base 2.8 M
rubygem-bigdecimal x86_64 1.2.0-33.el7_4 base 83 k
rubygem-io-console x86_64 0.4.2-33.el7_4 base 54 k
rubygem-json x86_64 1.7.7-33.el7_4 base 79 k
rubygem-psych x86_64 2.0.0-33.el7_4 base 82 k
rubygem-rdoc noarch 4.0.0-33.el7_4 base 322 k
Updating for dependencies:
rpm x86_64 4.11.3-32.el7 base 1.2 M
rpm-build-libs x86_64 4.11.3-32.el7 base 105 k
rpm-libs x86_64 4.11.3-32.el7 base 276 k
rpm-python x86_64 4.11.3-32.el7 base 82 k
Transaction Summary
=======================================================================================================================
Install 4 Packages (+13 Dependent packages)
Upgrade ( 4 Dependent packages)
Total download size: 6.0 M
Downloading packages:
No Presto metadata available for base
(1/21): dwz-0.11-3.el7.x86_64.rpm | 99 kB 00:00:00
(2/21): patch-2.7.1-10.el7_5.x86_64.rpm | 110 kB 00:00:00
(3/21): libyaml-0.1.4-11.el7_0.x86_64.rpm | 55 kB 00:00:00
(4/21): perl-Thread-Queue-3.02-2.el7.noarch.rpm | 17 kB 00:00:00
(5/21): perl-srpm-macros-1-8.el7.noarch.rpm | 4.6 kB 00:00:00
(6/21): redhat-rpm-config-9.1.0-80.el7.centos.noarch.rpm | 79 kB 00:00:00
(7/21): rpm-build-4.11.3-32.el7.x86_64.rpm | 147 kB 00:00:00
(8/21): rpm-build-libs-4.11.3-32.el7.x86_64.rpm | 105 kB 00:00:00
(9/21): rpm-libs-4.11.3-32.el7.x86_64.rpm | 276 kB 00:00:00
(10/21): rpm-python-4.11.3-32.el7.x86_64.rpm | 82 kB 00:00:00
(11/21): ruby-2.0.0.648-33.el7_4.x86_64.rpm | 71 kB 00:00:00
(12/21): rpm-4.11.3-32.el7.x86_64.rpm | 1.2 MB 00:00:00
(13/21): ruby-irb-2.0.0.648-33.el7_4.noarch.rpm | 92 kB 00:00:00
(14/21): ruby-libs-2.0.0.648-33.el7_4.x86_64.rpm | 2.8 MB 00:00:00
(15/21): rubygem-bigdecimal-1.2.0-33.el7_4.x86_64.rpm | 83 kB 00:00:00
(16/21): rubygem-io-console-0.4.2-33.el7_4.x86_64.rpm | 54 kB 00:00:00
(17/21): rubygem-json-1.7.7-33.el7_4.x86_64.rpm | 79 kB 00:00:00
(18/21): rubygem-psych-2.0.0-33.el7_4.x86_64.rpm | 82 kB 00:00:00
(19/21): rubygem-rdoc-4.0.0-33.el7_4.noarch.rpm | 322 kB 00:00:00
(20/21): rubygems-2.0.14.1-33.el7_4.noarch.rpm | 219 kB 00:00:00
(21/21): ruby-devel-2.0.0.648-33.el7_4.x86_64.rpm | 131 kB 00:00:09
-----------------------------------------------------------------------------------------------------------------------
Total 566 kB/s | 6.0 MB 00:00:10
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : ruby-libs-2.0.0.648-33.el7_4.x86_64 1/25
Updating : rpm-4.11.3-32.el7.x86_64 2/25
Updating : rpm-libs-4.11.3-32.el7.x86_64 3/25
Updating : rpm-build-libs-4.11.3-32.el7.x86_64 4/25
Installing : dwz-0.11-3.el7.x86_64 5/25
Installing : patch-2.7.1-10.el7_5.x86_64 6/25
Installing : libyaml-0.1.4-11.el7_0.x86_64 7/25
Installing : rubygem-io-console-0.4.2-33.el7_4.x86_64 8/25
Installing : rubygem-bigdecimal-1.2.0-33.el7_4.x86_64 9/25
Installing : rubygem-json-1.7.7-33.el7_4.x86_64 10/25
Installing : rubygem-psych-2.0.0-33.el7_4.x86_64 11/25
Installing : ruby-2.0.0.648-33.el7_4.x86_64 12/25
Installing : ruby-irb-2.0.0.648-33.el7_4.noarch 13/25
Installing : rubygems-2.0.14.1-33.el7_4.noarch 14/25
Installing : rubygem-rdoc-4.0.0-33.el7_4.noarch 15/25
Installing : perl-Thread-Queue-3.02-2.el7.noarch 16/25
Installing : perl-srpm-macros-1-8.el7.noarch 17/25
Installing : redhat-rpm-config-9.1.0-80.el7.centos.noarch 18/25
Installing : rpm-build-4.11.3-32.el7.x86_64 19/25
Installing : ruby-devel-2.0.0.648-33.el7_4.x86_64 20/25
Updating : rpm-python-4.11.3-32.el7.x86_64 21/25
Cleanup : rpm-python-4.11.3-25.el7.x86_64 22/25
Cleanup : rpm-build-libs-4.11.3-25.el7.x86_64 23/25
Cleanup : rpm-libs-4.11.3-25.el7.x86_64 24/25
Cleanup : rpm-4.11.3-25.el7.x86_64 25/25
Verifying : ruby-libs-2.0.0.648-33.el7_4.x86_64 1/25
Verifying : rubygem-rdoc-4.0.0-33.el7_4.noarch 2/25
Verifying : rubygem-io-console-0.4.2-33.el7_4.x86_64 3/25
Verifying : rubygem-bigdecimal-1.2.0-33.el7_4.x86_64 4/25
Verifying : perl-srpm-macros-1-8.el7.noarch 5/25
Verifying : perl-Thread-Queue-3.02-2.el7.noarch 6/25
Verifying : redhat-rpm-config-9.1.0-80.el7.centos.noarch 7/25
Verifying : ruby-devel-2.0.0.648-33.el7_4.x86_64 8/25
Verifying : libyaml-0.1.4-11.el7_0.x86_64 9/25
Verifying : rpm-build-4.11.3-32.el7.x86_64 10/25
Verifying : rubygem-json-1.7.7-33.el7_4.x86_64 11/25
Verifying : patch-2.7.1-10.el7_5.x86_64 12/25
Verifying : rubygem-psych-2.0.0-33.el7_4.x86_64 13/25
Verifying : ruby-2.0.0.648-33.el7_4.x86_64 14/25
Verifying : rpm-python-4.11.3-32.el7.x86_64 15/25
Verifying : rubygems-2.0.14.1-33.el7_4.noarch 16/25
Verifying : rpm-build-libs-4.11.3-32.el7.x86_64 17/25
Verifying : dwz-0.11-3.el7.x86_64 18/25
Verifying : rpm-libs-4.11.3-32.el7.x86_64 19/25
Verifying : ruby-irb-2.0.0.648-33.el7_4.noarch 20/25
Verifying : rpm-4.11.3-32.el7.x86_64 21/25
Verifying : rpm-4.11.3-25.el7.x86_64 22/25
Verifying : rpm-python-4.11.3-25.el7.x86_64 23/25
Verifying : rpm-build-libs-4.11.3-25.el7.x86_64 24/25
Verifying : rpm-libs-4.11.3-25.el7.x86_64 25/25
Installed:
rpm-build.x86_64 0:4.11.3-32.el7 ruby.x86_64 0:2.0.0.648-33.el7_4 ruby-devel.x86_64 0:2.0.0.648-33.el7_4
rubygems.noarch 0:2.0.14.1-33.el7_4
Dependency Installed:
dwz.x86_64 0:0.11-3.el7 libyaml.x86_64 0:0.1.4-11.el7_0
patch.x86_64 0:2.7.1-10.el7_5 perl-Thread-Queue.noarch 0:3.02-2.el7
perl-srpm-macros.noarch 0:1-8.el7 redhat-rpm-config.noarch 0:9.1.0-80.el7.centos
ruby-irb.noarch 0:2.0.0.648-33.el7_4 ruby-libs.x86_64 0:2.0.0.648-33.el7_4
rubygem-bigdecimal.x86_64 0:1.2.0-33.el7_4 rubygem-io-console.x86_64 0:0.4.2-33.el7_4
rubygem-json.x86_64 0:1.7.7-33.el7_4 rubygem-psych.x86_64 0:2.0.0-33.el7_4
rubygem-rdoc.noarch 0:4.0.0-33.el7_4
Dependency Updated:
rpm.x86_64 0:4.11.3-32.el7 rpm-build-libs.x86_64 0:4.11.3-32.el7 rpm-libs.x86_64 0:4.11.3-32.el7
rpm-python.x86_64 0:4.11.3-32.el7
Complete!
0x06--安装Ruby 2.4.1
1 [root@centos7 6030]# rvm install 2.4.1
2 Searching for binary rubies, this might take some time.
3 Found remote file https://rvm_io.global.ssl.fastly.net/binaries/centos/7/x86_64/ruby-2.4.1.tar.bz2
4 Checking requirements for centos.
5 Installing requirements for centos.
6 Installing required packages: autoconf, automake, bison, libffi-devel, libtool, readline-devel, sqlite-devel, zlib-devel, libyaml-devel, openssl-devel...............................
7 Requirements installation successful.
8 ruby-2.4.1 - #configure
9 ruby-2.4.1 - #download
10 % Total % Received % Xferd Average Speed Time Time Time Current
11 Dload Upload Total Spent Left Speed
12 100 14.1M 100 14.1M 0 0 94302 0 0:02:36 0:02:36 --:--:-- 75988
13 No checksum for downloaded archive, recording checksum in user configuration.
14 ruby-2.4.1 - #validate archive
15 ruby-2.4.1 - #extract
16 ruby-2.4.1 - #validate binary
17 ruby-2.4.1 - #setup
18 ruby-2.4.1 - #gemset created /usr/local/rvm/gems/ruby-2.4.1@global
19 ruby-2.4.1 - #importing gemset /usr/local/rvm/gemsets/global.gems..............................
20 ruby-2.4.1 - #generating global wrappers........
21 ruby-2.4.1 - #gemset created /usr/local/rvm/gems/ruby-2.4.1
22 ruby-2.4.1 - #importing gemsetfile /usr/local/rvm/gemsets/default.gems evaluated to empty gem list
23 ruby-2.4.1 - #generating default wrappers........
##查看安装结果
1 [root@centos7 6030]# rvm use 2.4.1
2 Using /usr/local/rvm/gems/ruby-2.4.1
3 [root@centos7 6030]# rvm remove 1.8.7
4 ruby-1.8.7-head - #already gone
5 Using /usr/local/rvm/gems/ruby-2.4.1
6 [root@centos7 6030]# ruby --version
7 ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
0x07--gem redis接口安装
1 [root@centos7 6030]# gem install redis
2 Fetching: redis-4.0.1.gem (100%)
3 Successfully installed redis-4.0.1
4 Parsing documentation for redis-4.0.1
5 Installing ri documentation for redis-4.0.1
6 Done installing documentation for redis after 4 seconds
7 1 gem installed
0x08--rubygems 安装
1 [root@centos7 6030]# yum install -y rubygems
2 Loaded plugins: fastestmirror, langpacks
3 Loading mirror speeds from cached hostfile
4 Package rubygems-2.0.14.1-33.el7_4.noarch already installed and latest version
5 Nothing to do
0x09--创建Redis集群
这里需要注意:需要将redis_home/src/redis-trib.rb 脚本复制到/usr/local/bin目录下,否则创建集群时,会报错:
1 -bash: redis-trib.rb: command not found
完整无报错创建Redis集群过程:
1 [root@centos7 src]# cp redis-trib.rb /usr/local/bin
2 [root@centos7 src]# redis-trib.rb create --replicas 1 10.118.128.223:6029 10.118.128.223:6030 10.118.128.223:6031 10.118.128.223:6032 10.118.128.223:6033 10.118.128.223:6034
3 >>> Creating cluster
4 >>> Performing hash slots allocation on 6 nodes...
5 Using 3 masters:
6 10.118.128.223:6029
7 10.118.128.223:6030
8 10.118.128.223:6031
9 Adding replica 10.118.128.223:6033 to 10.118.128.223:6029
10 Adding replica 10.118.128.223:6034 to 10.118.128.223:6030
11 Adding replica 10.118.128.223:6032 to 10.118.128.223:6031
12 >>> Trying to optimize slaves allocation for anti-affinity
13 [WARNING] Some slaves are in the same host as their master
14 M: 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:6029
15 slots:0-5460 (5461 slots) master
16 M: f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:6030
17 slots:5461-10922 (5462 slots) master
18 M: bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:6031
19 slots:10923-16383 (5461 slots) master
20 S: b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:6032
21 replicates 99f1b18c2895889884796e06a2f4384f5b110da0
22 S: ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:6033
23 replicates f202f30bcd2eabaa92a085a848b7e6bcfb5496c5
24 S: 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:6034
25 replicates bef79294b4cb57fe72eb3871f853745437da7c79
26 Can I set the above configuration? (type 'yes' to accept): yes
27 >>> Nodes configuration updated
28 >>> Assign a different config epoch to each node
29 >>> Sending CLUSTER MEET messages to join the cluster
30 Waiting for the cluster to join.......
31 >>> Performing Cluster Check (using node 10.118.128.223:6029)
32 M: 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:6029
33 slots:0-5460 (5461 slots) master
34 1 additional replica(s)
35 S: b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:6032
36 slots: (0 slots) slave
37 replicates 99f1b18c2895889884796e06a2f4384f5b110da0
38 M: f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:6030
39 slots:5461-10922 (5462 slots) master
40 1 additional replica(s)
41 S: 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:6034
42 slots: (0 slots) slave
43 replicates bef79294b4cb57fe72eb3871f853745437da7c79
44 S: ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:6033
45 slots: (0 slots) slave
46 replicates f202f30bcd2eabaa92a085a848b7e6bcfb5496c5
47 M: bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:6031
48 slots:10923-16383 (5461 slots) master
49 1 additional replica(s)
50 [OK] All nodes agree about slots configuration.
51 >>> Check for open slots...
52 >>> Check slots coverage...
53 [OK] All 16384 slots covered.
0x0A--Redis集群验证
redis-cli -h 10.118.128.223 -c -p 6029
说明:-h+host –p+端口号 –c 连接集群,连接Redis集群必须要加该参数
1 [root@centos7 src]# redis-cli -h 10.118.128.223 -c -p 6029
2 10.118.128.223:6029> cluster info
3 cluster_state:ok
4 cluster_slots_assigned:16384
5 cluster_slots_ok:16384
6 cluster_slots_pfail:0
7 cluster_slots_fail:0
8 cluster_known_nodes:6
9 cluster_size:3
10 cluster_current_epoch:6
11 cluster_my_epoch:1
12 cluster_stats_messages_ping_sent:69
13 cluster_stats_messages_pong_sent:78
14 cluster_stats_messages_sent:147
15 cluster_stats_messages_ping_received:73
16 cluster_stats_messages_pong_received:69
17 cluster_stats_messages_meet_received:5
18 cluster_stats_messages_received:147
19 10.118.128.223:6029> cluster nodes
20 b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:6032@16032 slave 99f1b18c2895889884796e06a2f4384f5b110da0 0 1530263318688 4 connected
21 f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:6030@16030 master - 0 1530263320705 2 connected 5461-10922
22 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:6029@16029 myself,master - 0 1530263320000 1 connected 0-5460
23 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:6034@16034 slave bef79294b4cb57fe72eb3871f853745437da7c79 0 1530263317678 6 connected
24 ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:6033@16033 slave f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 0 1530263318000 5 connected
25 bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:6031@16031 master - 0 1530263319697 3 connected 10923-16383
26 10.118.128.223:6029> cluster nodes
27 b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:6032@16032 slave 99f1b18c2895889884796e06a2f4384f5b110da0 0 1530263324000 4 connected
28 f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:6030@16030 master - 0 1530263324000 2 connected 5461-10922
29 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:6029@16029 myself,master - 0 1530263323000 1 connected 0-5460
30 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:6034@16034 slave bef79294b4cb57fe72eb3871f853745437da7c79 0 1530263325750 6 connected
31 ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:6033@16033 slave f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 0 1530263324736 5 connected
32 bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:6031@16031 master - 0 1530263326764 3 connected 10923-16383
来源:oschina
链接:https://my.oschina.net/u/4387108/blog/3921704