redis集群搭建及分析

     redis提供了无中心化的模式来提供对key的shading, 提供数据存储的master节点与master节点之间是对等的, master节点与master节点之间通过gossip协议进行通信,以实现集群选主,失效转移, 触发数据迁移等操作.

1. redis 集群搭建
1.1 配置项说明
  • cluster-enabled <yes/no>: 是否开启集群模式, yes开启, no不开启.
  • cluster-config-file <filename>: 集群配置文件,用于集群信息,用户不能编辑或改变该文件.
  • cluster-node-timeout <milliseconds>: 检测集群中master节点失败最大时间,当master节点超过该时间还无法联系时, 如果有备份节点则备份节点将对maser节点进行失效转移,若干没有则表示该master节点失效, 当集群中大多数master节点失效时,集群将不再提供操作.
  •  cluster-slave-validity-factor <factor>:master节点检测到超时时最大连接重试次数, 默认为0, 即一旦检测到超时则slave节点就对master进行失效转移, 当该值为正数时, 在factor*timeout的时间周期内, slave不会对master进行失效转移.
  • cluster-migration-barrier <count>: master节点保存连接的最小slave节点数.
  • cluster-require-full-coverage <yes/no>:当主节点失效时是否继续提供服务, 默认yes, 即主节点失效时将不提供服务, no, 失效时仍然提供服务.

1.2 集群搭建

  下面将搭建3主3从的集群, 主节点端口分别为7000, 7001, 70002, 从节点端口为7003, 7004, 7005.即一个master节点对应一个slave节点.
创建配置文件如下:

port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes


创建6个文件夹, 文件夹名为端口名, 并将配置文件拷贝到各文件夹,端口修改为对应端

mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005

将redis-server执行程序拷贝到文件夹,并启动
cd 7000
../redis-server ./redis.conf


运行后结果如下:
14073:M 11 Aug 14:45:40.198 * No cluster configuration found, I'm 5714dd95e99999f7130eba44747f7a15aa8f5394
5714dd95e99999f7130eba44747f7a15aa8f5394, 表示节点Id.
安装redis gem
完成以上步骤后,各节点独立运行,并没有形成集群,下面需要相互之间通信,组成集群,这里使用redis自带的工具redis-trib
gem install redis 


创建集群
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \ 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

创建成功
[OK] All 16384 slots covered 

查看集群状态
127.0.0.1:7002> cluster nodes
4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470899978447 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470899976944 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 master - 0 1470899977946 2 connected 5461-10922
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470899978947 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 slave aca053afafd21f887d3bc9d87c16597f67b7e513 0 1470899977445 5 connected


命令测试:

./redis-cli -c -p 7000
127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get hello
"world"
127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
"bar"

以上集群搭建成功

2. slots映射说明
redis 内部提供 16384个槽,每个节点分配固定槽数, 也就是说一个集群最多支持16348个节点, 如有A, B, C三个节点, 则分配如下:
  • Node A  [0,5500]
  • Node B [5501,11000]
  • Node C [11001,16383]
对于一个key, 首先对其做crc16, 并将结果对16384去模, 所得的结果则表示key所属的槽, 通过查询槽的分配策略, 得到key分配的服务器, 从而实现key在集群内部shading.

3. 重定向命令
moved重定向命令:
client端与redis集群的任一节点建立连接后, 对key进行操作时:
  • 如果收到命令的redis节点发现key对应的槽不属于自己处理,则会给client回复moved错误, 并返回槽所在的真正节点,
  • client端收到moved错误后,重定向到指定节点做操作,
  • 这里可以可以看出, 任何一个redis节点均保存了集群中的其他节点槽对应信息.另外为了提高client性能, client会缓存槽与服务器的对应信息, 所以收到moved从定向时, 会相应的更新缓存.

ask重定向命令:
ask重定向发送在集群中正在对槽对应的key进行数据迁移时,具体流程为:
  •  当client端向节点nodeA发送key1的处理命令时, 若果A节点具有key1对应的槽slot1的处理权, 且key1无法在nodeA查询到, 且slot1正处于迁移状态,则nodeA返回ask重定向命令, 将其指向迁移的目标节点nodeB
  • client收到重定向命令后, 向nodeB先发送asking命令, 再发送key1的处理命令.
  • nodeB接收到asking命令后, 将对收到后续一个命令做特殊处理,也就是即使发现slot1不属于nodeB处理,仍然会执行key1的处理命令.
  • ask从定向命令不会引起client端更新缓存,且nodeB只处理一次.


4. 失效转移
redis集群有实行主备机制, slave节点保存着master节点所有数据备份, 当master节点失效时,slave节点会对master节点进行失效转移.具体流程为:
  • 集群中master节点之间定期会进行通信, 当集群中对等的masterA节点发现某个节点masterB超时无回应时, 则将该masterB节点置为faling,并广播检测到的情况.
  • 同时masterA会记录集群中其他master节点对masterB的检测结果, 如果发现集群中大部分(n/2+1)的master节点均认为该节点faling,则将masterB的装置为failed, 即失效,同时, masterA向masterB的slave节点发送命令让其选举.
  • 选举时在一个时间纪元内会存在两种情况, 要么一个slave节点获得大于等于n/2+1的投票成为新的master, 要么超时.
  • 选择成功后的slave将会成为master节点,继续工作,而超时则进入新一轮选举,直到选出新的master.
  • 这里具有投票权的master只能投票一次,从而保证只有一个master能当选.
  • 而失效的master节点又重新上线后将转为slave节点.

redis集群的测试结果如下:
在上面搭建的集群中7004为7001的slave节点,现将7001挂掉, 查看集群状态:
127.0.0.1:7002> cluster nodes
4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470903542509 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470903542509 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 master,fail - 1470903522089 1470903520389 2 disconnected
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470903541506 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 master - 0 1470903543513 7 connected 5461-10922

可以看到7001已经失效, 同时7004成了新的master节点.


现在又将7001重启, 查看集群状态:
127.0.0.1:7002> cluster nodes 4406983653bd90043b5b7f65af0afc571bb2d93c 127.0.0.1:7002 myself,master - 0 0 3 connected 10923-16383
fd5e7a729072b0e7e29ff5a4935a0151c470a47d 127.0.0.1:7005 slave 4406983653bd90043b5b7f65af0afc571bb2d93c 0 1470903594126 3 connected
5714dd95e99999f7130eba44747f7a15aa8f5394 127.0.0.1:7000 master - 0 1470903596130 1 connected 0-5460
aca053afafd21f887d3bc9d87c16597f67b7e513 127.0.0.1:7001 slave 576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 0 1470903594727 7 connected
c450ae75e23a2cfeda901c0de77ef0cae85a8a8b 127.0.0.1:7003 slave 5714dd95e99999f7130eba44747f7a15aa8f5394 0 1470903595730 1 connected
576764adacf6737b5ef6e63ff5ea2cb3a9aae43d 127.0.0.1:7004 master - 0 1470903595629 7 connected 5461-10922

7001 成为了slave节点.


5. 集群扩展
集群扩展分为两个方面,分别为新增节点(包括新增master节点, 新增slave节点), 及减少节点.
新增master节点
流程和前面搭建集群时一致, 先给节点分配一个端口并运行,如7006.然后通过 redis-trib执行以下命令

./redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

如上, 第一个地址为新增的地址, 第二个地址为集群中已经运行的master地址,执行完以上命令后master虽然加入了集群,但是它并没有分配到槽进行数据处理
这是需要进行reshaing, 命令如下:
./redis-trib.rb reshard --from <node-id> --to <node-id> --slots <number of slots> --yes <host>:<port>


新增slave节点
./redis-trib.rb add-node --slave --master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7006 127.0.0.1:7000
其中, master-id表示要成为谁的slave.


减少节点
./redis-trib del-node 127.0.0.1:7000 `<node-id>`


6. 总结
从整个流程来看,.不管还是集群的创建还是 后期集群的运维,redis都非常的顺畅,这无疑降低了使用的门槛,就以当前redis的性能来说,做redis缓存集群是个不错的选择,不过,如果要在运营环境进行使用,还是需要更加方便的部署及运维工具,这里推荐搜狐的开源工具cachecloud, 的确十分好用,git地址见:





  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值