Redis集群

背景

redis cluster 是基于redis3.0出的redis 集群架构,从网上down 了一张图可以比较清晰的说明redis cluster的工作方式:

Redis集群_第1张图片
Redis_Cluster
  • 有几点比较重要,redis cluster 内部使用二进制协议优化传输速度和带宽。
  • 节点是否fail 是根据半数以上的node 投票决定的。
  • 客户端与redis节点直连,理论上随便选个端口和IP就能连接
  • redis cluster是将所有node 映射到16383 个solt 上。
    此外基本条件必须满足3+3的模式,也就是说集群最少也必须要有3主3从的redis 才能构建,另外redis所在服务器需要安装配置ruby。搭建redis cluster前需要把redis 老的数据清空,每台必须都执行flushall。

搭建配置

测试环境在debian下搭建配置,用了最简单的3+3的架构,分别分布在3台服务器上,每个服务器2个redis 实例。

redis-server 10.1.99.163:7011
redis-server 10.1.99.163:7012
redis-server 10.1.99.164:7013
redis-server 10.1.99.164:7014
redis-server 10.1.99.165:7015
redis-server 10.1.99.165:7016

redis 版本使用的3.02 stable 。
1.安装组建:

apt-get install ruby
gem install redis #gem 是ruby的一个打包工具

然后下载编译安装redis ,过程老样子,不复述了。
修改redis 配置文件,除了端口和bind 地址需要修改外,主要需要打开redis 集群的开关配置:

cluster-enabled yes #打开redis cluster
cluster-config-file nodes_7012.conf #这个文件在redis 集群启动后会自己生成 ,里面记录的是redis的集群节点信息                                                                                                                                                                                               
647 cluster-node-timeout 15000 #超时时间

然后一样,依次启动6个redis 实例。

root      9121  5757  0 19:45 pts/1    00:00:11 redis-server 10.1.99.163:7011 [cluster]

每个redis进程后会都带一个cluster 的标识。
此时6个redis 都是单独的redis 实例,然后在运行

redis-trib.rb create --replicas 1 10.1.99.163:7011 10.1.99.163:7012 10.1.99.164:7013 10.1.99.164:7014 10.1.99.165:7015 10.1.99.165:7016

redis-trib.rb 是管理redis集群的一个脚本,检查,添加,删除节点都可以使用该脚本:

root@:redis-3.0.2# redis-trib.rb help
Usage: redis-trib   

  create          host1:port1 ... hostN:portN
                  --replicas 
  check           host:port
  fix             host:port
  reshard         host:port
                  --from 
                  --to 
                  --slots 
                  --yes
  add-node        new_host:new_port existing_host:existing_port
                  --slave
                  --master-id 
  del-node        host:port node_id
  set-timeout     host:port milliseconds
  call            host:port command arg arg .. arg
  import          host:port
                  --from 
  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.

运行该脚本后,会生成redis的集群,同样可以使用该脚本进行检查

root@:redis-3.0.2# redis-trib.rb check 10.1.99.163:7011
Connecting to node 10.1.99.163:7011: OK
Connecting to node 10.1.99.164:7014: OK
Connecting to node 10.1.99.165:7016: OK
Connecting to node 10.1.99.164:7013: OK
Connecting to node 10.1.99.163:7012: OK
Connecting to node 10.1.99.165:7015: OK
>>> Performing Cluster Check (using node 10.1.99.163:7011)
M: 2db3baa186f7530e12f48049b81ede908616896b 10.1.99.163:7011
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 1f747e75d5eb2be8a23d52544c7f70c22fb3765a 10.1.99.164:7014
   slots: (0 slots) slave
   replicates 2db3baa186f7530e12f48049b81ede908616896b
S: 17616b78741a3d5748dedfc556c23da7823fa924 10.1.99.165:7016
   slots: (0 slots) slave
   replicates fe26cc474c10ee2b94e926a53d9270cb5777cef1
M: 5a55e25026ce1c9941220320b096f3854bf4038c 10.1.99.164:7013
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 8ffcbd674da0bdf51ad1963a5612309693d8066d 10.1.99.163:7012
   slots: (0 slots) slave
   replicates 5a55e25026ce1c9941220320b096f3854bf4038c
M: fe26cc474c10ee2b94e926a53d9270cb5777cef1 10.1.99.165:7015
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

哪些是slave ,哪些是master 一目了然。此时不出意外的话redis cluster 集群已经在工作了。连接随便一个redis node 查看相关信息:

root@:redis-3.0.2# redis-cli -c -h 10.1.99.163 -p 7011
10.1.99.163:7011> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_sent:14371
cluster_stats_messages_received:14371
10.1.99.163:7011> cluster nodes
1f747e75d5eb2be8a23d52544c7f70c22fb3765a 10.1.99.164:7014 slave 2db3baa186f7530e12f48049b81ede908616896b 0 1488807713360 4 connected
17616b78741a3d5748dedfc556c23da7823fa924 10.1.99.165:7016 slave fe26cc474c10ee2b94e926a53d9270cb5777cef1 0 1488807711357 6 connected
5a55e25026ce1c9941220320b096f3854bf4038c 10.1.99.164:7013 master - 0 1488807714363 3 connected 5461-10922
8ffcbd674da0bdf51ad1963a5612309693d8066d 10.1.99.163:7012 slave 5a55e25026ce1c9941220320b096f3854bf4038c 0 1488807715367 3 connected
fe26cc474c10ee2b94e926a53d9270cb5777cef1 10.1.99.165:7015 master - 0 1488807712358 5 connected 10923-16383
2db3baa186f7530e12f48049b81ede908616896b 10.1.99.163:7011 myself,master - 0 0 1 connected 0-5460
10.1.99.163:7011> 

此时验证redis cluster 是否正常工作,登录7011端口实例,查看对应主从信息:

10.1.99.163:7011> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.1.99.164,port=7014,state=online,offset=9629,lag=1
master_repl_offset:9629
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:9628

他是主,从是7014实例。然后插入一条数据:

10.1.99.163:7011> set barney redis
OK
10.1.99.163:7011> keys *
1) "barney"
10.1.99.163:7011> get barney
"redis"
10.1.99.163:7011> 

插入后发现有对应的key 以及value,然后登录该master 对应的salve 7014 进行查看:

10.1.99.164:7014> keys *
1) "barney"
10.1.99.164:7014> get barney 
-> Redirected to slot [5059] located at 10.1.99.163:7011
"redis"
10.1.99.163:7011> 

该势中能找到对应的keys 但是get value的时候session 去跳到了7011 上,然后再登录其他node 进行检查。

10.1.99.163:7012> keys * 
(empty list or set)
10.1.99.163:7012> get barney
-> Redirected to slot [5059] located at 10.1.99.163:7011
"redis"
10.1.99.163:7011> 

可以看到,再其他node 上无法通过类似keys * 来查到所有node 上的key值,但是直接取值的话是可以取到的,但是需要跳转到对应端口的node的session 上。同理删除操作也一样。
那么这样的话,当7011实例挂了会如何,手动kill 这个进程。
然后经过大约30秒左右,发现7011的从节点变为了主:

10.1.99.164:7014> info replication
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

说明此时redis cluster 重新将他推举为新的master:

root@:redis-3.0.2# redis-cli -c -h 10.1.99.163 -p 7012
10.1.99.163:7012> keys *
(empty list or set)
10.1.99.163:7012> get barney 
(error) CLUSTERDOWN The cluster is down
10.1.99.163:7012> 9124:S 06 Mar 21:54:53.573 # Cluster state changed: ok

10.1.99.163:7012> get barney 
-> Redirected to slot [5059] located at 10.1.99.164:7014
"redis"
10.1.99.164:7014> 

然后重新启动挂掉的redis node ,redis cluster 会将盖节点重新加入集群,但此时已经变为slave 了。

附上一些常用的redis cluster cli 命令

CLUSTER INFO 打印集群的信息  
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。  
节点  
CLUSTER MEET   将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。  
CLUSTER FORGET  从集群中移除 node_id 指定的节点。  
CLUSTER REPLICATE  将当前节点设置为 node_id 指定的节点的从节点。  
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。  
槽(slot)  
CLUSTER ADDSLOTS  [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。  
CLUSTER DELSLOTS  [slot ...] 移除一个或多个槽对当前节点的指派。  
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。  
CLUSTER SETSLOT  NODE  将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。  
CLUSTER SETSLOT  MIGRATING  将本节点的槽 slot 迁移到 node_id 指定的节点中。  
CLUSTER SETSLOT  IMPORTING  从 node_id 指定的节点中导入槽 slot 到本节点。  
CLUSTER SETSLOT  STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。  
键  
CLUSTER KEYSLOT  计算键 key 应该被放置在哪个槽上。  
CLUSTER COUNTKEYSINSLOT  返回槽 slot 目前包含的键值对数量。  
CLUSTER GETKEYSINSLOT   返回 count 个 slot 槽中的键。  

你可能感兴趣的:(Redis集群)