Redis笔记 -- 在 Centos7.4单机中部署Redis集群(二)

0x00--背景和目的

在单台PC服务器上部署Redis集群,通过不同的TCP端口启动多实例,模拟多*立PC组成集群。

0x01--环境描述:

 Centos版本:CentOS Linux release 7.4. (Core)
Redis版本:Redis 4.0. (/) bit
安装方式:源码安装

0x02--编辑Redis实例配置文件

在根目录下新建/redis_cluster目录,用于存放多实例配置文件,这里使用6个TCP端口,编写6029--6034共计6个配置文件,使用折6个配置文件启动实例,并搭建Redis集群。

 port 6029     ##端口号,用于模拟不同主机不同实例,6029,6030,6031,6032,6033,6034
bind 10.118.128.223 ##实例IP地址,默认为127.0.0.1,根据实际情况修改,集群节点间需要保证IP地址能相互通讯,网络层面需要放开相应端口的访问权限
daemonize yes ##允许Redis后台运行
pidfile /redis_cluster/redis_6029.pid ##pidfile 文件,每个实例一个,分别对应6029.6030.6031,6032,6033,6034
cluster-enabled yes ##开启集群cluster
cluster-config-file nodes_6029.conf ##集群配置文件
cluster-node-timeout 15000 ##请求超时时长,默认15秒,可依据网络情况自行修改配置

0x03--启动多个Redis实例

 [root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::41.271 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::41.271 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::41.271 # Configuration loaded
[root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::47.325 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::47.325 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::47.325 # Configuration loaded
[root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::50.637 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::50.637 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::50.637 # Configuration loaded
[root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::53.938 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::53.939 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::53.939 # Configuration loaded
[root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::57.490 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::57.490 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::57.490 # Configuration loaded
[root@centos7 ]# redis-server /redis_cluster//redis.conf
:C Jun ::00.787 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
:C Jun ::00.788 # Redis version=4.0., bits=, commit=, modified=, pid=, just started
:C Jun ::00.788 # Configuration loaded

查看进程,可看到已经有6个Redis实例启动,且端口号也可以明显看到

 [root@centos7 src]# ps -ef|grep redis|grep cluster
root : ? :: redis-server 10.118.128.223: [cluster]
root : ? :: redis-server 10.118.128.223: [cluster]
root : ? :: redis-server 10.118.128.223: [cluster]
root : ? :: redis-server 10.118.128.223: [cluster]
root : ? :: redis-server 10.118.128.223: [cluster]
root : ? :: redis-server 10.118.128.223: [cluster]

0x04--配置Ruby环境-redis-trib.rb脚本

Redis3.0以后开始支持集群功能,官方推出了一个管理redis集群的工具--一个ruby脚本:redis-trib.rb

该脚本集成在redis的源码SRC目录下,所以,需要系统安装配置ruby环境,才能使用该脚本进行Redis集群的创建、配置和管理。

Redis笔记 -- 在 Centos7.4单机中部署Redis集群(二)

以下是该脚本的内容,仅供学习参考,redis版本为4.0.10

 [root@centos7 src]# cat redis-trib.rb
#!/usr/bin/env ruby # TODO (temporary here, we'll move this into the Github issues once
# redis-trib initial implementation is completed).
#
# - Make sure that if the rehashing fails in the middle redis-trib will try
# to recover.
# - When redis-trib performs a cluster check, if it detects a slot move in
# progress it should prompt the user to continue the move from where it
# stopped.
# - Gracefully handle Ctrl+C in move_slot to prompt the user if really stop
# while rehashing, and performing the best cleanup possible if the user
# forces the quit.
# - When doing "fix" set a global Fix to true, and prompt the user to
# fix the problem if automatically fixable every time there is something
# to fix. For instance:
# ) If there is a node that pretend to receive a slot, or to migrate a
# slot, but has no entries in that slot, fix it.
# ) If there is a node having keys in slots that are not owned by it
# fix this condition moving the entries in the same node.
# ) Perform more possibly slow tests about the state of the cluster.
# ) When aborted slot migration is detected, fix it. require 'rubygems'
require 'redis' ClusterHashSlots =
MigrateDefaultTimeout =
MigrateDefaultPipeline =
RebalanceDefaultThreshold = $verbose = false def xputs(s)
case s[..]
when ">>>"
color="29;1"
when "[ER"
color="31;1"
when "[WA"
color="31;1"
when "[OK"
color=""
when "[FA","***"
color=""
else
color=nil
end color = nil if ENV['TERM'] != "xterm"
print "\033[#{color}m" if color
print s
print "\033[0m" if color
print "\n"
end class ClusterNode
def initialize(addr)
s = addr.split("@")[].split(":")
if s.length <
puts "Invalid IP or Port (given as #{addr}) - use IP:Port format"
exit
end
port = s.pop # removes port from split array
ip = s.join(":") # if s.length > here, it's IPv6, so restore address
@r = nil
@info = {}
@info[:host] = ip
@info[:port] = port
@info[:slots] = {}
@info[:migrating] = {}
@info[:importing] = {}
@info[:replicate] = false
@dirty = false # True if we need to flush slots info into node.
@friends = []
end def friends
@friends
end def slots
@info[:slots]
end def has_flag?(flag)
@info[:flags].index(flag)
end def to_s
"#{@info[:host]}:#{@info[:port]}"
end def connect(o={})
return if @r
print "Connecting to node #{self}: " if $verbose
STDOUT.flush
begin
@r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => )
@r.ping
rescue
xputs "[ERR] Sorry, can't connect to node #{self}"
exit if o[:abort]
@r = nil
end
xputs "OK" if $verbose
end def assert_cluster
info = @r.info
if !info["cluster_enabled"] || info["cluster_enabled"].to_i ==
xputs "[ERR] Node #{self} is not configured as a cluster node."
exit
end
end def assert_empty
if !(@r.cluster("info").split("\r\n").index("cluster_known_nodes:1")) ||
(@r.info['db0'])
."
exit
end
end def load_info(o={})
self.connect
nodes = @r.cluster("nodes").split("\n")
nodes.each{|n|
# name addr flags role ping_sent ping_recv link_status slots
split = n.split
name,addr,flags,master_id,ping_sent,ping_recv,config_epoch,link_status = split[..]
slots = split[..-]
info = {
:name => name,
:addr => addr,
:flags => flags.split(","),
:replicate => master_id,
:ping_sent => ping_sent.to_i,
:ping_recv => ping_recv.to_i,
:link_status => link_status
}
info[:replicate] = false if master_id == "-" if info[:flags].index("myself")
@info = @info.merge(info)
@info[:slots] = {}
slots.each{|s|
if s[..] == '['
if s.index("->-") # Migrating
slot,dst = s[..-].split("->-")
@info[:migrating][slot.to_i] = dst
elsif s.index("-<-") # Importing
slot,src = s[..-].split("-<-")
@info[:importing][slot.to_i] = src
end
elsif s.index("-")
start,stop = s.split("-")
self.add_slots((start.to_i)..(stop.to_i))
else
self.add_slots((s.to_i)..(s.to_i))
end
} if slots
@dirty = false
@r.cluster("info").split("\n").each{|e|
k,v=e.split(":")
k = k.to_sym
v.chop!
if k != :cluster_state
@info[k] = v.to_i
else
@info[k] = v
end
}
elsif o[:getfriends]
@friends << info
end
}
end def add_slots(slots)
slots.each{|s|
@info[:slots][s] = :new
}
@dirty = true
end def set_as_replica(node_id)
@info[:replicate] = node_id
@dirty = true
end def flush_node_config
return if !@dirty
if @info[:replicate]
begin
@r.cluster("replicate",@info[:replicate])
rescue
# If the cluster did not already joined it is possible that
# the slave does not know the master node yet. So on errors
# we return ASAP leaving the dirty flag set, to flush the
# config later.
return
end
else
new = []
@info[:slots].each{|s,val|
if val == :new
new << s
@info[:slots][s] = true
end
}
@r.cluster("addslots",*new)
end
@dirty = false
end def info_string
# We want to display the hash slots assigned to this node
# as ranges, like in: "1-5,8-9,20-25,30"
#
# Note: this could be easily written without side effects,
# we use 'slots' just to split the computation into steps. # First step: we want an increasing array of integers
# for instance: [,,,,,,,,,,,,,]
slots = @info[:slots].keys.sort # As we want to aggregate adjacent slots we convert all the
# slot integers into ranges (with just one element)
# So we have something like [..,.., ... and so forth.
slots.map!{|x| x..x} # Finally we group ranges with adjacent elements.
slots = slots.reduce([]) {|a,b|
if !a.empty? && b.first == (a[-].last)+
a[..-] + [(a[-].first)..(b.last)]
else
a + [b]
end
} # Now our task is easy, we just convert ranges with just one
# element into a number, and a real range into a start-end format.
# Finally we join the array using the comma as separator.
slots = slots.map{|x|
x.count == ? x.first.to_s : "#{x.first}-#{x.last}"
}.join(",") role = self.has_flag?("master") ? "M" : "S" if self.info[:replicate] and @dirty
is = "S: #{self.info[:name]} #{self.to_s}"
else
is = "#{role}: #{self.info[:name]} #{self.to_s}\n"+
" slots:#{slots} (#{self.slots.length} slots) "+
"#{(self.info[:flags]-["myself"]).join(",")}"
end
if self.info[:replicate]
is += "\n replicates #{info[:replicate]}"
elsif self.has_flag?("master") && self.info[:replicas]
is += "\n #{info[:replicas].length} additional replica(s)"
end
is
end # Return a single string representing nodes and associated slots.
# TODO: remove slaves from config when slaves will be handled
# by Redis Cluster.
def get_config_signature
config = []
@r.cluster("nodes").each_line{|l|
s = l.split
slots = s[..-].select {|x| x[..] != "["}
next if slots.length ==
config << s[]+":"+(slots.sort.join(","))
}
config.sort.join("|")
end def info
@info
end def is_dirty?
@dirty
end def r
@r
end
end class RedisTrib
def initialize
@nodes = []
@fix = false
@errors = []
@timeout = MigrateDefaultTimeout
end def check_arity(req_args, num_args)
if ((req_args > and num_args != req_args) ||
(req_args < and num_args < req_args.abs))
xputs "[ERR] Wrong number of arguments for specified sub command"
exit
end
end def add_node(node)
@nodes << node
end def reset_nodes
@nodes = []
end def cluster_error(msg)
@errors << msg
xputs msg
end # Return the node with the specified ID or Nil.
def get_node_by_name(name)
@nodes.each{|n|
return n if n.info[:name] == name.downcase
}
return nil
end # Like get_node_by_name but the specified name can be just the first
# part of the node ID as long as the prefix in unique across the
# cluster.
def get_node_by_abbreviated_name(name)
l = name.length
candidates = []
@nodes.each{|n|
if n.info[:name][...l] == name.downcase
candidates << n
end
}
return nil if candidates.length !=
candidates[]
end # This function returns the master that has the least number of replicas
# in the cluster. If there are multiple masters with the same smaller
# number of replicas, one at random is returned.
def get_master_with_least_replicas
masters = @nodes.select{|n| n.has_flag? "master"}
sorted = masters.sort{|a,b|
a.info[:replicas].length <=> b.info[:replicas].length
}
sorted[]
end def check_cluster(opt={})
xputs ">>> Performing Cluster Check (using node #{@nodes[0]})"
show_nodes if !opt[:quiet]
check_config_consistency
check_open_slots
check_slots_coverage
end def show_cluster_info
masters =
keys =
@nodes.each{|n|
if n.has_flag?("master")
puts "#{n} (#{n.info[:name][0...8]}...) -> #{n.r.dbsize} keys | #{n.slots.length} slots | "+
"#{n.info[:replicas].length} slaves."
masters +=
keys += n.r.dbsize
end
}
xputs "[OK] #{keys} keys in #{masters} masters."
keys_per_slot = sprintf("%.2f",keys/16384.0)
puts "#{keys_per_slot} keys per slot on average."
end # Merge slots of every known node. If the resulting slots are equal
# to ClusterHashSlots, then all slots are served.
def covered_slots
slots = {}
@nodes.each{|n|
slots = slots.merge(n.slots)
}
slots
end def check_slots_coverage
xputs ">>> Check slots coverage..."
slots = covered_slots
if slots.length == ClusterHashSlots
xputs "[OK] All #{ClusterHashSlots} slots covered."
else
cluster_error \
"[ERR] Not all #{ClusterHashSlots} slots are covered by nodes."
fix_slots_coverage if @fix
end
end def check_open_slots
xputs ">>> Check for open slots..."
open_slots = []
@nodes.each{|n|
if n.info[:migrating].size >
cluster_error \
"[WARNING] Node #{n} has slots in migrating state (#{n.info[:migrating].keys.join(",")})."
open_slots += n.info[:migrating].keys
end
if n.info[:importing].size >
cluster_error \
"[WARNING] Node #{n} has slots in importing state (#{n.info[:importing].keys.join(",")})."
open_slots += n.info[:importing].keys
end
}
open_slots.uniq!
if open_slots.length >
xputs "[WARNING] The following slots are open: #{open_slots.join(",")}"
end
if @fix
open_slots.each{|slot| fix_open_slot slot}
end
end def nodes_with_keys_in_slot(slot)
nodes = []
@nodes.each{|n|
next if n.has_flag?("slave")
nodes << n if n.r.cluster("getkeysinslot",slot,).length >
}
nodes
end def fix_slots_coverage
not_covered = (...ClusterHashSlots).to_a - covered_slots.keys
xputs ">>> Fixing slots coverage..."
xputs "List of not covered slots: " + not_covered.join(",") # For every slot, take action depending on the actual condition:
# ) No node has keys for this slot.
# ) A single node has keys for this slot.
# ) Multiple nodes have keys for this slot.
slots = {}
not_covered.each{|slot|
nodes = nodes_with_keys_in_slot(slot)
slots[slot] = nodes
xputs "Slot #{slot} has keys in #{nodes.length} nodes: #{nodes.join(", ")}"
} none = slots.select {|k,v| v.length == }
single = slots.select {|k,v| v.length == }
multi = slots.select {|k,v| v.length > } # Handle case "": keys in no node.
if none.length >
xputs "The folowing uncovered slots have no keys across the cluster:"
xputs none.keys.join(",")
yes_or_die "Fix these slots by covering with a random node?"
none.each{|slot,nodes|
node = @nodes.sample
xputs ">>> Covering slot #{slot} with #{node}"
node.r.cluster("addslots",slot)
}
end # Handle case "": keys only in one node.
if single.length >
xputs "The folowing uncovered slots have keys in just one node:"
puts single.keys.join(",")
yes_or_die "Fix these slots by covering with those nodes?"
single.each{|slot,nodes|
xputs ">>> Covering slot #{slot} with #{nodes[0]}"
nodes[].r.cluster("addslots",slot)
}
end # Handle case "": keys in multiple nodes.
if multi.length >
xputs "The folowing uncovered slots have keys in multiple nodes:"
xputs multi.keys.join(",")
yes_or_die "Fix these slots by moving keys into a single node?"
multi.each{|slot,nodes|
target = get_node_with_most_keys_in_slot(nodes,slot)
xputs ">>> Covering slot #{slot} moving keys to #{target}" target.r.cluster('addslots',slot)
target.r.cluster('setslot',slot,'stable')
nodes.each{|src|
next if src == target
# Set the source node in 'importing' state (even if we will
# actually migrate keys away) in order to avoid receiving
# redirections for MIGRATE.
src.r.cluster('setslot',slot,'importing',target.info[:name])
move_slot(src,target,slot,:dots=>true,:fix=>true,:cold=>true)
src.r.cluster('setslot',slot,'stable')
}
}
end
end # Return the owner of the specified slot
def get_slot_owners(slot)
owners = []
@nodes.each{|n|
next if n.has_flag?("slave")
n.slots.each{|s,_|
owners << n if s == slot
}
}
owners
end # Return the node, among 'nodes' with the greatest number of keys
# in the specified slot.
def get_node_with_most_keys_in_slot(nodes,slot)
best = nil
best_numkeys =
@nodes.each{|n|
next if n.has_flag?("slave")
numkeys = n.r.cluster("countkeysinslot",slot)
if numkeys > best_numkeys || best == nil
best = n
best_numkeys = numkeys
end
}
return best
end # Slot 'slot' was found to be in importing or migrating state in one or
# more nodes. This function fixes this condition by migrating keys where
# it seems more sensible.
def fix_open_slot(slot)
puts ">>> Fixing open slot #{slot}" # Try to obtain the current slot owner, according to the current
# nodes configuration.
owners = get_slot_owners(slot)
owner = owners[] if owners.length == migrating = []
importing = []
@nodes.each{|n|
next if n.has_flag? "slave"
if n.info[:migrating][slot]
migrating << n
elsif n.info[:importing][slot]
importing << n
elsif n.r.cluster("countkeysinslot",slot) > && n != owner
xputs "*** Found keys about slot #{slot} in node #{n}!"
importing << n
end
}
puts "Set as migrating in: #{migrating.join(",")}"
puts "Set as importing in: #{importing.join(",")}" # If there is no slot owner, set as owner the slot with the biggest
# number of keys, among the set of migrating / importing nodes.
if !owner
xputs ">>> Nobody claims ownership, selecting an owner..."
owner = get_node_with_most_keys_in_slot(@nodes,slot) # If we still don't have an owner, we can't fix it.
if !owner
xputs "[ERR] Can't select a slot owner. Impossible to fix."
exit
end # Use ADDSLOTS to assign the slot.
puts "*** Configuring #{owner} as the slot owner"
owner.r.cluster("setslot",slot,"stable")
owner.r.cluster("addslots",slot)
# Make sure this information will propagate. Not strictly needed
# since there is no past owner, so all the other nodes will accept
# whatever epoch this node will claim the slot with.
owner.r.cluster("bumpepoch") # Remove the owner from the list of migrating/importing
# nodes.
migrating.delete(owner)
importing.delete(owner)
end # If there are multiple owners of the slot, we need to fix it
# so that a single node is the owner and all the other nodes
# are in importing state. Later the fix can be handled by one
# of the base cases above.
#
# Note that this case also covers multiple nodes having the slot
# in migrating state, since migrating is a valid state only for
# slot owners.
if owners.length >
owner = get_node_with_most_keys_in_slot(owners,slot)
owners.each{|n|
next if n == owner
n.r.cluster('delslots',slot)
n.r.cluster('setslot',slot,'importing',owner.info[:name])
importing.delete(n) # Avoid duplciates
importing << n
}
owner.r.cluster('bumpepoch')
end

redis-trib.rb

trib.rb脚本使用帮助:

 [root@centos7 src]# ./redis-trib.rb help
Usage: redis-trib <command> <options> <arguments ...> create host1:port1 ... hostN:portN ##创建集群
--replicas <arg> ##replicas参数指定当前创建的redis集群有几个Slave节点
check host:port ##检查集群,验证节点可用性
info host:port ##查看集群信息,节点信息
fix host:port ##修复集群
--timeout <arg>
reshard host:port ##在线迁移集群,from A to B
--from <arg>
--to <arg>
--slots <arg>
--yes
--timeout <arg>
--pipeline <arg>
rebalance host:port ##平衡集群节点slot数量
--weight <arg>
--auto-weights
--use-empty-masters
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
add-node new_host:new_port existing_host:existing_port ##在线添加新的集群节点
--slave
--master-id <arg>
del-node host:port node_id ##在线删除集群节点
set-timeout host:port milliseconds ##redis集群节点心跳超时参数设置,默认15秒
call host:port command arg arg .. arg ##使命令在所有节点一起执行,慎用该参数
import host:port ##将外部Redis节点数据导入集群
--from <arg>
--copy
--replace
help (show this help) ##显示脚本使用帮助 For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
[root@centos7 src]#

0x05--配置Ruby环境-安装Ruby

注意:redis-trib.rb的运行需要的ruby包,Ruby版本至少需要2.2,否则在安装时会出现如下报错,可以自行下载2.2.2版本以上的Ruby进行安装,也可以参照码上青天的博文进行在线升级

 [root@centos7 ]# gem install redis
Fetching: redis-4.0..gem (%)
ERROR: Error installing redis:
redis requires Ruby version >= 2.2..
[root@centos7 ]# yum install -y ruby ruby-devel rubygems rpm-build
Loaded plugins: fastestmirror, langpacks
base | 3.6 kB ::
extras | 3.4 kB ::
percona-release-noarch | 2.9 kB ::
percona-release-x86_64 | 2.9 kB ::
(/): extras//x86_64/primary_db | kB ::
(/): percona-release-noarch//primary_db | kB ::
(/): percona-release-x86_64//x86_64/primary_db | kB ::
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package rpm-build.x86_64 :4.11.-.el7 will be installed
--> Processing Dependency: rpm = 4.11.-.el7 for package: rpm-build-4.11.-.el7.x86_64
--> Processing Dependency: patch >= 2.5 for package: rpm-build-4.11.-.el7.x86_64
--> Processing Dependency: system-rpm-config for package: rpm-build-4.11.-.el7.x86_64
--> Processing Dependency: perl(Thread::Queue) for package: rpm-build-4.11.-.el7.x86_64
---> Package ruby.x86_64 :2.0.0.648-.el7_4 will be installed
--> Processing Dependency: ruby-libs(x86-) = 2.0.0.648-.el7_4 for package: ruby-2.0.0.648-.el7_4.x86_64
--> Processing Dependency: rubygem(bigdecimal) >= 1.2. for package: ruby-2.0.0.648-.el7_4.x86_64
--> Processing Dependency: libruby.so.2.0()(64bit) for package: ruby-2.0.0.648-.el7_4.x86_64
---> Package ruby-devel.x86_64 :2.0.0.648-.el7_4 will be installed
---> Package rubygems.noarch :2.0.14.1-.el7_4 will be installed
--> Processing Dependency: rubygem(rdoc) >= 4.0. for package: rubygems-2.0.14.1-.el7_4.noarch
--> Processing Dependency: rubygem(psych) >= 2.0. for package: rubygems-2.0.14.1-.el7_4.noarch
--> Processing Dependency: rubygem(io-console) >= 0.4. for package: rubygems-2.0.14.1-.el7_4.noarch
--> Running transaction check
---> Package patch.x86_64 :2.7.-.el7_5 will be installed
---> Package perl-Thread-Queue.noarch :3.02-.el7 will be installed
---> Package redhat-rpm-config.noarch :9.1.-.el7.centos will be installed
--> Processing Dependency: dwz >= 0.4 for package: redhat-rpm-config-9.1.-.el7.centos.noarch
--> Processing Dependency: perl-srpm-macros for package: redhat-rpm-config-9.1.-.el7.centos.noarch
---> Package rpm.x86_64 :4.11.-.el7 will be updated
--> Processing Dependency: rpm = 4.11.-.el7 for package: rpm-libs-4.11.-.el7.x86_64
--> Processing Dependency: rpm = 4.11.-.el7 for package: rpm-python-4.11.-.el7.x86_64
---> Package rpm.x86_64 :4.11.-.el7 will be an update
---> Package ruby-libs.x86_64 :2.0.0.648-.el7_4 will be installed
---> Package rubygem-bigdecimal.x86_64 :1.2.-.el7_4 will be installed
---> Package rubygem-io-console.x86_64 :0.4.-.el7_4 will be installed
---> Package rubygem-psych.x86_64 :2.0.-.el7_4 will be installed
--> Processing Dependency: libyaml-.so.()(64bit) for package: rubygem-psych-2.0.-.el7_4.x86_64
---> Package rubygem-rdoc.noarch :4.0.-.el7_4 will be installed
--> Processing Dependency: ruby(irb) = 2.0.0.648 for package: rubygem-rdoc-4.0.-.el7_4.noarch
--> Processing Dependency: rubygem(json) >= 1.7. for package: rubygem-rdoc-4.0.-.el7_4.noarch
--> Running transaction check
---> Package dwz.x86_64 :0.11-.el7 will be installed
---> Package libyaml.x86_64 :0.1.-.el7_0 will be installed
---> Package perl-srpm-macros.noarch :-.el7 will be installed
---> Package rpm-libs.x86_64 :4.11.-.el7 will be updated
--> Processing Dependency: rpm-libs(x86-) = 4.11.-.el7 for package: rpm-build-libs-4.11.-.el7.x86_64
---> Package rpm-libs.x86_64 :4.11.-.el7 will be an update
---> Package rpm-python.x86_64 :4.11.-.el7 will be updated
---> Package rpm-python.x86_64 :4.11.-.el7 will be an update
---> Package ruby-irb.noarch :2.0.0.648-.el7_4 will be installed
---> Package rubygem-json.x86_64 :1.7.-.el7_4 will be installed
--> Running transaction check
---> Package rpm-build-libs.x86_64 :4.11.-.el7 will be updated
---> Package rpm-build-libs.x86_64 :4.11.-.el7 will be an update
--> Finished Dependency Resolution Dependencies Resolved =======================================================================================================================
Package Arch Version Repository Size
=======================================================================================================================
Installing:
rpm-build x86_64 4.11.-.el7 base k
ruby x86_64 2.0.0.648-.el7_4 base k
ruby-devel x86_64 2.0.0.648-.el7_4 base k
rubygems noarch 2.0.14.1-.el7_4 base k
Installing for dependencies:
dwz x86_64 0.11-.el7 base k
libyaml x86_64 0.1.-.el7_0 base k
patch x86_64 2.7.-.el7_5 updates k
perl-Thread-Queue noarch 3.02-.el7 base k
perl-srpm-macros noarch -.el7 base 4.6 k
redhat-rpm-config noarch 9.1.-.el7.centos base k
ruby-irb noarch 2.0.0.648-.el7_4 base k
ruby-libs x86_64 2.0.0.648-.el7_4 base 2.8 M
rubygem-bigdecimal x86_64 1.2.-.el7_4 base k
rubygem-io-console x86_64 0.4.-.el7_4 base k
rubygem-json x86_64 1.7.-.el7_4 base k
rubygem-psych x86_64 2.0.-.el7_4 base k
rubygem-rdoc noarch 4.0.-.el7_4 base k
Updating for dependencies:
rpm x86_64 4.11.-.el7 base 1.2 M
rpm-build-libs x86_64 4.11.-.el7 base k
rpm-libs x86_64 4.11.-.el7 base k
rpm-python x86_64 4.11.-.el7 base k Transaction Summary
=======================================================================================================================
Install Packages (+ Dependent packages)
Upgrade ( Dependent packages) Total download size: 6.0 M
Downloading packages:
No Presto metadata available for base
(/): dwz-0.11-.el7.x86_64.rpm | kB ::
(/): patch-2.7.-.el7_5.x86_64.rpm | kB ::
(/): libyaml-0.1.-.el7_0.x86_64.rpm | kB ::
(/): perl-Thread-Queue-3.02-.el7.noarch.rpm | kB ::
(/): perl-srpm-macros--.el7.noarch.rpm | 4.6 kB ::
(/): redhat-rpm-config-9.1.-.el7.centos.noarch.rpm | kB ::
(/): rpm-build-4.11.-.el7.x86_64.rpm | kB ::
(/): rpm-build-libs-4.11.-.el7.x86_64.rpm | kB ::
(/): rpm-libs-4.11.-.el7.x86_64.rpm | kB ::
(/): rpm-python-4.11.-.el7.x86_64.rpm | kB ::
(/): ruby-2.0.0.648-.el7_4.x86_64.rpm | kB ::
(/): rpm-4.11.-.el7.x86_64.rpm | 1.2 MB ::
(/): ruby-irb-2.0.0.648-.el7_4.noarch.rpm | kB ::
(/): ruby-libs-2.0.0.648-.el7_4.x86_64.rpm | 2.8 MB ::
(/): rubygem-bigdecimal-1.2.-.el7_4.x86_64.rpm | kB ::
(/): rubygem-io-console-0.4.-.el7_4.x86_64.rpm | kB ::
(/): rubygem-json-1.7.-.el7_4.x86_64.rpm | kB ::
(/): rubygem-psych-2.0.-.el7_4.x86_64.rpm | kB ::
(/): rubygem-rdoc-4.0.-.el7_4.noarch.rpm | kB ::
(/): rubygems-2.0.14.1-.el7_4.noarch.rpm | kB ::
(/): ruby-devel-2.0.0.648-.el7_4.x86_64.rpm | kB ::
-----------------------------------------------------------------------------------------------------------------------
Total kB/s | 6.0 MB ::
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : ruby-libs-2.0.0.648-.el7_4.x86_64 /
Updating : rpm-4.11.-.el7.x86_64 /
Updating : rpm-libs-4.11.-.el7.x86_64 /
Updating : rpm-build-libs-4.11.-.el7.x86_64 /
Installing : dwz-0.11-.el7.x86_64 /
Installing : patch-2.7.-.el7_5.x86_64 /
Installing : libyaml-0.1.-.el7_0.x86_64 /
Installing : rubygem-io-console-0.4.-.el7_4.x86_64 /
Installing : rubygem-bigdecimal-1.2.-.el7_4.x86_64 /
Installing : rubygem-json-1.7.-.el7_4.x86_64 /
Installing : rubygem-psych-2.0.-.el7_4.x86_64 /
Installing : ruby-2.0.0.648-.el7_4.x86_64 /
Installing : ruby-irb-2.0.0.648-.el7_4.noarch /
Installing : rubygems-2.0.14.1-.el7_4.noarch /
Installing : rubygem-rdoc-4.0.-.el7_4.noarch /
Installing : perl-Thread-Queue-3.02-.el7.noarch /
Installing : perl-srpm-macros--.el7.noarch /
Installing : redhat-rpm-config-9.1.-.el7.centos.noarch /
Installing : rpm-build-4.11.-.el7.x86_64 /
Installing : ruby-devel-2.0.0.648-.el7_4.x86_64 /
Updating : rpm-python-4.11.-.el7.x86_64 /
Cleanup : rpm-python-4.11.-.el7.x86_64 /
Cleanup : rpm-build-libs-4.11.-.el7.x86_64 /
Cleanup : rpm-libs-4.11.-.el7.x86_64 /
Cleanup : rpm-4.11.-.el7.x86_64 /
Verifying : ruby-libs-2.0.0.648-.el7_4.x86_64 /
Verifying : rubygem-rdoc-4.0.-.el7_4.noarch /
Verifying : rubygem-io-console-0.4.-.el7_4.x86_64 /
Verifying : rubygem-bigdecimal-1.2.-.el7_4.x86_64 /
Verifying : perl-srpm-macros--.el7.noarch /
Verifying : perl-Thread-Queue-3.02-.el7.noarch /
Verifying : redhat-rpm-config-9.1.-.el7.centos.noarch /
Verifying : ruby-devel-2.0.0.648-.el7_4.x86_64 /
Verifying : libyaml-0.1.-.el7_0.x86_64 /
Verifying : rpm-build-4.11.-.el7.x86_64 /
Verifying : rubygem-json-1.7.-.el7_4.x86_64 /
Verifying : patch-2.7.-.el7_5.x86_64 /
Verifying : rubygem-psych-2.0.-.el7_4.x86_64 /
Verifying : ruby-2.0.0.648-.el7_4.x86_64 /
Verifying : rpm-python-4.11.-.el7.x86_64 /
Verifying : rubygems-2.0.14.1-.el7_4.noarch /
Verifying : rpm-build-libs-4.11.-.el7.x86_64 /
Verifying : dwz-0.11-.el7.x86_64 /
Verifying : rpm-libs-4.11.-.el7.x86_64 /
Verifying : ruby-irb-2.0.0.648-.el7_4.noarch /
Verifying : rpm-4.11.-.el7.x86_64 /
Verifying : rpm-4.11.-.el7.x86_64 /
Verifying : rpm-python-4.11.-.el7.x86_64 /
Verifying : rpm-build-libs-4.11.-.el7.x86_64 /
Verifying : rpm-libs-4.11.-.el7.x86_64 / Installed:
rpm-build.x86_64 :4.11.-.el7 ruby.x86_64 :2.0.0.648-.el7_4 ruby-devel.x86_64 :2.0.0.648-.el7_4
rubygems.noarch :2.0.14.1-.el7_4 Dependency Installed:
dwz.x86_64 :0.11-.el7 libyaml.x86_64 :0.1.-.el7_0
patch.x86_64 :2.7.-.el7_5 perl-Thread-Queue.noarch :3.02-.el7
perl-srpm-macros.noarch :-.el7 redhat-rpm-config.noarch :9.1.-.el7.centos
ruby-irb.noarch :2.0.0.648-.el7_4 ruby-libs.x86_64 :2.0.0.648-.el7_4
rubygem-bigdecimal.x86_64 :1.2.-.el7_4 rubygem-io-console.x86_64 :0.4.-.el7_4
rubygem-json.x86_64 :1.7.-.el7_4 rubygem-psych.x86_64 :2.0.-.el7_4
rubygem-rdoc.noarch :4.0.-.el7_4 Dependency Updated:
rpm.x86_64 :4.11.-.el7 rpm-build-libs.x86_64 :4.11.-.el7 rpm-libs.x86_64 :4.11.-.el7
rpm-python.x86_64 :4.11.-.el7 Complete!

yum install -y ruby ruby-devel rubygems

0x06--安装Ruby 2.4.1

 [root@centos7 ]# rvm install 2.4.
Searching for binary rubies, this might take some time.
Found remote file https://rvm_io.global.ssl.fastly.net/binaries/centos/7/x86_64/ruby-2.4.1.tar.bz2
Checking requirements for centos.
Installing requirements for centos.
Installing required packages: autoconf, automake, bison, libffi-devel, libtool, readline-devel, sqlite-devel, zlib-devel, libyaml-devel, openssl-devel...............................
Requirements installation successful.
ruby-2.4. - #configure
ruby-2.4. - #download
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
14.1M 14.1M :: :: --:--:--
No checksum for downloaded archive, recording checksum in user configuration.
ruby-2.4. - #validate archive
ruby-2.4. - #extract
ruby-2.4. - #validate binary
ruby-2.4. - #setup
ruby-2.4. - #gemset created /usr/local/rvm/gems/ruby-2.4.@global
ruby-2.4. - #importing gemset /usr/local/rvm/gemsets/global.gems..............................
ruby-2.4. - #generating global wrappers........
ruby-2.4. - #gemset created /usr/local/rvm/gems/ruby-2.4.
ruby-2.4. - #importing gemsetfile /usr/local/rvm/gemsets/default.gems evaluated to empty gem list
ruby-2.4. - #generating default wrappers........
##查看安装结果
1 [root@centos7 ]# rvm use 2.4.
Using /usr/local/rvm/gems/ruby-2.4.
[root@centos7 ]# rvm remove 1.8.
ruby-1.8.-head - #already gone
Using /usr/local/rvm/gems/ruby-2.4.
[root@centos7 ]# ruby --version
ruby 2.4.1p111 (-- revision ) [x86_64-linux]

0x07--gem  redis接口安装

 [root@centos7 ]# gem install redis
Fetching: redis-4.0..gem (%)
Successfully installed redis-4.0.
Parsing documentation for redis-4.0.
Installing ri documentation for redis-4.0.
Done installing documentation for redis after seconds
gem installed

0x08--rubygems 安装

 [root@centos7 ]# yum install -y rubygems
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
Package rubygems-2.0.14.1-.el7_4.noarch already installed and latest version
Nothing to do

0x09--创建Redis集群

这里需要注意:需要将redis_home/src/redis-trib.rb 脚本复制到/usr/local/bin目录下,否则创建集群时,会报错:

 -bash: redis-trib.rb: command not found

完整无报错创建Redis集群过程:

 [root@centos7 src]# cp redis-trib.rb /usr/local/bin
[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
>>> Creating cluster
>>> Performing hash slots allocation on nodes...
Using masters:
10.118.128.223:
10.118.128.223:
10.118.128.223:
Adding replica 10.118.128.223: to 10.118.128.223:
Adding replica 10.118.128.223: to 10.118.128.223:
Adding replica 10.118.128.223: to 10.118.128.223:
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:
slots:- ( slots) master
M: f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:
slots:- ( slots) master
M: bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:
slots:- ( slots) master
S: b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:
replicates 99f1b18c2895889884796e06a2f4384f5b110da0
S: ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:
replicates f202f30bcd2eabaa92a085a848b7e6bcfb5496c5
S: 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:
replicates bef79294b4cb57fe72eb3871f853745437da7c79
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.......
>>> Performing Cluster Check (using node 10.118.128.223:)
M: 99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:
slots:- ( slots) master
additional replica(s)
S: b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:
slots: ( slots) slave
replicates 99f1b18c2895889884796e06a2f4384f5b110da0
M: f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:
slots:- ( slots) master
additional replica(s)
S: 73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:
slots: ( slots) slave
replicates bef79294b4cb57fe72eb3871f853745437da7c79
S: ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:
slots: ( slots) slave
replicates f202f30bcd2eabaa92a085a848b7e6bcfb5496c5
M: bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:
slots:- ( slots) master
additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All slots covered.

0x0A--Redis集群验证

redis-cli -h 10.118.128.223 -c -p 6029

说明:-h+host –p+端口号 –c 连接集群,连接Redis集群必须要加该参数

 [root@centos7 src]# redis-cli -h 10.118.128.223 -c -p
10.118.128.223:> cluster info
cluster_state:ok
cluster_slots_assigned:
cluster_slots_ok:
cluster_slots_pfail:
cluster_slots_fail:
cluster_known_nodes:
cluster_size:
cluster_current_epoch:
cluster_my_epoch:
cluster_stats_messages_ping_sent:
cluster_stats_messages_pong_sent:
cluster_stats_messages_sent:
cluster_stats_messages_ping_received:
cluster_stats_messages_pong_received:
cluster_stats_messages_meet_received:
cluster_stats_messages_received:
10.118.128.223:> cluster nodes
b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:@ slave 99f1b18c2895889884796e06a2f4384f5b110da0 connected
f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:@ master - connected -
99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:@ myself,master - connected -
73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:@ slave bef79294b4cb57fe72eb3871f853745437da7c79 connected
ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:@ slave f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 connected
bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:@ master - connected -
10.118.128.223:> cluster nodes
b008404edf2dbaef9b5ba94e85478025f99da9b3 10.118.128.223:@ slave 99f1b18c2895889884796e06a2f4384f5b110da0 connected
f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 10.118.128.223:@ master - connected -
99f1b18c2895889884796e06a2f4384f5b110da0 10.118.128.223:@ myself,master - connected -
73d4ee24ccc7685f33609ccc5862ef86b73e75d5 10.118.128.223:@ slave bef79294b4cb57fe72eb3871f853745437da7c79 connected
ec354db61687d8b8fd03a6c353c4d27ebe82a24b 10.118.128.223:@ slave f202f30bcd2eabaa92a085a848b7e6bcfb5496c5 connected
bef79294b4cb57fe72eb3871f853745437da7c79 10.118.128.223:@ master - connected -
上一篇:MySQL(九)之数据表的查询详解(SELECT语法)二


下一篇:HDU 3032 Nim or not Nim? [Multi-SG]