redis集群

1.首先安装rubyinstaller-2.3.3-x64.exe

2.删除ruby源,设置国内的源

C:\Ruby23-x64\bin>gem source -l

*** CURRENT SOURCES ***

https://rubygems.org/

C:\Ruby23-x64\bin>gem source --remove https://rubygems.org/

https://rubygems.org/ removed from sources

C:\Ruby23-x64\bin>gem source -l

*** CURRENT SOURCES ***

C:\Ruby23-x64\bin>gem source -a http://gems.ruby-china.org/

http://gems.ruby-china.org/ added to sources

C:\Ruby23-x64\bin>gem source -l

*** CURRENT SOURCES ***

http://gems.ruby-china.org/

C:\Ruby23-x64\bin>gem install redis

Fetching: redis-3.3.2.gem (100%)

Successfully installed redis-3.3.2

Parsing documentation for redis-3.3.2

Installing ri documentation for redis-3.3.2

Done installing documentation for redis after 1 seconds

1 gem installed

redis-trib.rb Windows下的包没有这个文件可以从官方版本src目录下拷贝出来。

然后建立7000-7005目录 配置redis.windows-serverice.conf文件。

配置:

端口
dump.rdb
appendonly  yes
maxmemory
maxmemory-policy allkeys-lru
cluster-enabled yes
cluster-config-file nodes-7002.conf
cluster-node-timeout 15000

然后设置脚本开启redis:

start  D:\redis\7000\redis-server.exe D:\redis\7000\redis.windows-service.conf

关闭redis:@echo off
taskkill /f /im redis-server.exe /t
开启所有的redis然后创建集群:

D:\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

>>> Creating cluster

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

127.0.0.1:7000

127.0.0.1:7001

127.0.0.1:7002

Adding replica 127.0.0.1:7003 to 127.0.0.1:7000

Adding replica 127.0.0.1:7004 to 127.0.0.1:7001

Adding replica 127.0.0.1:7005 to 127.0.0.1:7002

M: 2c98792e5f4adaa1bd6895abf1c757d070976971 127.0.0.1:7000

   slots:0-5460 (5461 slots) master

M: 675c94a07078f3828ff451b4d1c91b181ccd0433 127.0.0.1:7001

   slots:5461-10922 (5462 slots) master

M: 3ae36010d659eb58ce0a5cd200d067c970a62565 127.0.0.1:7002

   slots:10923-16383 (5461 slots) master

S: ffe407227d03fc69614c47c2308dc354e2f6a47b 127.0.0.1:7003

   replicates 2c98792e5f4adaa1bd6895abf1c757d070976971

S: 3e122a35e2a74c7f5eff14edd6ff9ba764aca5bb 127.0.0.1:7004

   replicates 675c94a07078f3828ff451b4d1c91b181ccd0433

S: 2c95492ea9700d699e69816e5df6f461e5777109 127.0.0.1:7005

   replicates 3ae36010d659eb58ce0a5cd200d067c970a62565

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 127.0.0.1:7000)

M: 2c98792e5f4adaa1bd6895abf1c757d070976971 127.0.0.1:7000

   slots:0-5460 (5461 slots) master

   1 additional replica(s)

S: 3e122a35e2a74c7f5eff14edd6ff9ba764aca5bb 127.0.0.1:7004

   slots: (0 slots) slave

   replicates 675c94a07078f3828ff451b4d1c91b181ccd0433

S: ffe407227d03fc69614c47c2308dc354e2f6a47b 127.0.0.1:7003

   slots: (0 slots) slave

   replicates 2c98792e5f4adaa1bd6895abf1c757d070976971

M: 675c94a07078f3828ff451b4d1c91b181ccd0433 127.0.0.1:7001

   slots:5461-10922 (5462 slots) master

   1 additional replica(s)

S: 2c95492ea9700d699e69816e5df6f461e5777109 127.0.0.1:7005

   slots: (0 slots) slave

   replicates 3ae36010d659eb58ce0a5cd200d067c970a62565

M: 3ae36010d659eb58ce0a5cd200d067c970a62565 127.0.0.1:7002

   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.

连接集群:

D:\redis\7000>redis-cli.exe -c -p 7000

127.0.0.1:7000> keys *

(empty list or set)

127.0.0.1:7000> hmset user:001 name zzy age 1 address "zhejiang hangzhou"

OK

127.0.0.1:7000> hmset user:002 name haha age 2 address "bejing china"

-> Redirected to slot [13102] located at 127.0.0.1:7002

OK

创建集群

现在我们已经有了六个正在运行中的 Redis 实例, 接下来我们需要使用这些实例来创建集群。 
通过使用 Redis 集群命令行工具 redis-trib , 编写节点配置文件的工作可以非常容易地完成: redis-trib 位于 Redis 源码的 src 文件夹中, 它是一个 Ruby 程序, 这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作。这里通过create命令来创建集群。

# cd ~/redis-3.0.0/src

# ./redis-trib.rb create --replicas 1 192.168.1.21:7001 192.168.1.21:7002 192.168.1.21:7003 192.168.1.21:7011 192.168.1.21:7012 192.168.1.21:7013

说明: 
这里的IP地址必须是真实的IP,不能使用回环 127.0.0.1 地址。

–replicas 1 即每一个master有1个slave;顺序为 m m m s s s 
redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯。

输入yes,然后配置完成。

以上信息的其中一部分可以通过向集群中的任意节点(主节点或者从节点都可以)发送 CLUSTER NODES 命令来获得。该命令还可以获得节点 ID , IP 地址和端口号, 标志(flag), 最后发送 PING 的时间, 最后接收 PONG 的时间, 连接状态, 节点负责处理的槽。

# redis-cli -p 7001 cluster nodes

08. 集群检查

./redis-trib.rb check 127.0.0.1:7001

09. 连接Redis集群

通过上面的输出,我们可以看出Redis三个主节点的slot范围。一个 Redis 客户端可以向集群中的任意节点(包括从节点)发送命令请求。我们首先连接第一个节点:

# redis-cli -p 7001

 

127.0.0.1:7001> set a 1

(error) MOVED 15495 127.0.0.1:7003

127.0.0.1:7001> get a

(error) MOVED 15495 127.0.0.1:7003

127.0.0.1:7001> set b 1

OK

虽然我们用Node ID来标识集群中的节点, 但是为了让客户端的转向操作尽可能地简单, 节点在 MOVED 错误中直接返回目标节点的 IP 和端口号, 而不是目标节点的 ID 。客户端应该记录槽15495由节点127.0.0.1:7003负责处理“这一信息, 这样当再次有命令需要对槽15495执行时, 客户端就可以加快寻找正确节点的速度。这样,当集群处于稳定状态时,所有客户端最终都会保存有一个哈希槽至节点的映射记录,使得集群非常高效: 客户端可以直接向正确的节点发送命令请求, 无须转向、代理或者其他任何可能发生单点故障(single point failure)的实体(entiy)。

10. 添加新master节点

a. 启动节点

# cd ~/redis-cluster

# mkdir 8001

# cp ./redis.conf ./8001

# cd 8001

# redis-server redis.conf

b. 将节点加入到集群

# redis-trib.rb add-node 127.0.0.1:8001 127.0.0.1:7001

说明: 
第一个 ip:port 为新节点 
第二个 ip:port 是任意一个已经存在的节点 
新节点没有包含任何数据,也没有包含任何slot。 
当集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中,同时新的主节点因为没有包含任何slot,不参加选举和failover。

c. 为新节点分配 slot

# redis-trib.rb reshard 127.0.0.1:8001 

#根据提示选择要迁移的slot数量(ps:这里选择500) 

How many slots do you want to move (from 1 to 16384)? 500 

#选择要接受这些slot的node-id 

What is the receiving node ID? f51e26b5d5ff74f85341f06f28f125b7254e61bf 

#选择slot来源: 

#all表示从所有的master重新分配, 

#或者数据要提取slot的master节点id,最后用done结束 

Please enter all the source node IDs. 

  Type 'all' to use all the nodes as source nodes for the hash slots. 

  Type 'done' once you entered all the source nodes IDs. 

Source node #1:all 

#打印被移动的slot后,输入yes开始移动slot以及对应的数据. 

#Do you want to proceed with the proposed reshard plan (yes/no)? yes 

#结束 

11. 添加新的 Slave 节点

a. 启动节点

# cd ~/redis-cluster

# mkdir 8011

# cp ./redis.conf ./8011

# cd 8011

# redis-server redis.conf

b. 将节点加入到集群 
方法一:

# redis-trib.rb add-node -slave 127.0.0.1:8011 127.0.0.1:7001

说明: 
第一个 ip:port 为新节点 
第二个 ip:port 是任意一个已经存在的节点 
新的节点会作为集群中其中一个主节点的从节点,一般来说是从节点最少的主节点。

方法二:

# redis-trib.rb add-node -slave -master-id \ 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:8011 127.0.0.1:7001

说明: 
-master-id xxxx 主节点的 ID 
第一个 ip:port 为新节点 
第二个 ip:port 是任意一个已经存在的节点

注意:在线添加slave 时,需要bgsave整个master数据,并传递到slave,再由 slave加载rdb文件到内存,rdb生成和传输的过程中消耗Master大量内存和网络IO,以此不建议单实例内存过大,线上小心操作。

12. 在线 reshard 数据

对于负载/数据不均匀的情况,可以在线reshard slot来解决,方法与添加新master的reshard一样,只是需要reshard的master节点是已存在的老节点。

# redis-trib.rb reshard 127.0.0.1:7003

13. 删除一个 slave 节点

# redis-trib.rb del-node ip:port '<node-id>' 

# redis-trib.rb del-node 127.0.0.1:7001 'c7ee2fca17cb79fe3c9822ced1d4f6c5e169e378'

说明: 
ip:port 集群中已有的任意一节点(不是被删除的节点) 
被删除节点的 ID

14. 删除一个 master 节点(7003)

删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点。 (目前redis-trib.rb只能把被删除master的slot对应的数据迁移到一个节点上)。

a. 迁移 slot

#把127.0.0.1:7003当前master迁移到127.0.0.1:7002上 

redis-trib.rb reshard 172.0.0.1:7002 

#根据提示选择要迁移的slot数量(ps:这里选择500) 

How many slots do you want to move (from 1 to 16384)? 500(被删除master的所有slot数量) 

#选择要接受这些slot的node-id(172.0.0.1:7002) 

What is the receiving node ID? c4a31c852f81686f6ed8bcd6d1b13accdc947fd2 (ps:172.0.0.1:7002的node-id) 

Please enter all the source node IDs. 

  Type 'all' to use all the nodes as source nodes for the hash slots. 

  Type 'done' once you entered all the source nodes IDs. 

Source node #1:f51e26b5d5ff74f85341f06f28f125b7254e61bf(被删除master的node-id) 

Source node #2:done 

#打印被移动的slot后,输入yes开始移动slot以及对应的数据. 

#Do you want to proceed with the proposed reshard plan (yes/no)? yes 

b. 删除空的 master 节点

# redis-trib.rb del-node 172.0.0.1:7001 'f51e26b5d5ff74f85341f06f28f125b7254e61bf' 

说明: 
ip:port 集群中已有的任意一节点(不是被删除的节点) 
被删除节点的 ID

15. 改变从节点的隶属关系(从节点 7013)

# redis-cli -p 7013

127.0.0.1:7013> cluster replicate 2b9ebcbd627ff0fd7a7bbcc5332fb09e72788835

说明:

  2b9ebcbd627ff0fd7a7bbcc5332fb09e72788835  为新的主节点的 ID

16. 集群的关闭和重启

redis cluster官方文档,没发现有关集群重启和关闭的方法。主要是因为在正式的环境中集群一般都由3台物理机构成,3台物理机同时挂掉的可能性极小。只要不同时挂掉,挂掉的机器修复后在加入集群,集群都能良好的运作,万一同时挂掉,数据又没有备份的话,就有大麻烦了。

redis cluster集群中的节点基本上都对等的,没有管理节点。如果要让所有节点都关闭,只能关闭所有 redis-server 进程。

# pkill -9 redis

然后重新启动,如果直接重启会报告错误。

# redis-trib.rb create --replicas 1 xxx xxx xxx xxx

会报以下错误,

[ERR] Node 127.0.0.1:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

第一次启动集群时,~/redis-cluster/7001/ 下只有 redis.conf,而现在重启时,此目录下有了别的文件,所有报错。简单的方法是将除了 redis.conf 外的其他文件全部删除,在启动肯定是可以的,但是集群是有数据的,所以需要保留了配置文件 redis.conf 和数据文件 *.rdb。 
这样是可以启动的,但是原来的数据还是丢失了,不知道是自己的想法不对。

需要注意的问题

1.执行06步骤时,节点目录下(7001/7002/…/7013/ 应当只有 redis.conf 文件)

2.一定要严格执行 01 步骤准备好环境。 
此步骤中 gem sources 默认地址好像无法访问,建议用下面方法替换

# gem sources -r https://rubygems.org

# gem sources -a http://rubygems.org 

Redis Cluster 功能特性

Redis 集群是分布式的redis 实现,具有以下特性:

1. 高可用性与可线性扩张到1000个节点2. 数据自动路由到多个节点3. 节点间数据共享4. 可动态添加或者删除节点5. 部分节点不可达时,集群仍可用6. 数据通过异步复制,不保证数据的强一致性7. 可动态调整数据分布

Redis 集群架构图

其中       一: Redis 集群协议              1、Redis 集群,节点负责存储数据、记录集群状态,集群节点能自动发现其他节点,检测出节点的状态,并在需要的时候,推选中主节点              2、Redis 集群节点中通过TCP连接和一个二级制协议(cluster bus) 建立通信。发现新的节点、发送PING包、特定的情况下发送集群消息。集群连接能够发布与订阅消息              3、Redis 集群节点不能代理请求,客户端发起请求后,接收到重定向(MOVED\ASK)错误,会自动重定向到其他节点。理论上来说,客户端是可以自由地向集群中的所有节点发送请求,在需要的时候把请求重定向到其他节点,所以客户端是不需要保存集群状态。 不过客户端可以缓存键值和节点之间的映射关系,这样能明显提高命令执行的效率。       二: 安全写入                     Redis 集群节点之间使用异步复制,在分区过程中存在窗口,容易导致丢失写入数据,Redis集群即使努力尝试所有写入,但是以下两种情况可能丢失数据:                     1、命令操作到达主节点后,但在主节点回复的时候,此时写入可能还没有通过主节点复制到从节点那里。如果这时候主库宕机了,这条命令永久丢失。以防主节点长时间不可达而它的一个从节点已经被提升为主节点。                     2、分区导致一个主节点不可达,然而集群发送故障转移(failover),提升从节点为主节点,原来的主节点再次恢复。一个没有更新路由表(routing table)的客户端或许会在集群把这个主节点变成一个从节点(新主节点的从节点)之前对它进行写入操作。导致数据彻底丢失       三: 可用性              Redis 集群少数节点不可用后,在经过cluster-node-timeout时间后,集群根据自动故障机制,将从节点提升为主节点。这事集群恢复可用              举个例子,一个由 N 个主节点组成的集群,每个主节点都只有一个从节点。当有一个节点(因为故障)被分割出去后,集群的多数节点这边仍然是可访问的。当有两个节点(因故障)被分割出去后集群仍可用的概率是 1-(1/(N*2-1))(在第一个节点故障出错后总共剩下 N*2-1 个节点,那么失去冗余备份(即失去从节点)的那个主节点也故障出错的概率是 1/(N*2-1)))。              比如一个拥有6个节点的集群,每个节点都只有一个从节点,那么在两个节点从多数节点这边分割出去后集群不再可用的概率是 1/(6*2-1) = 0.0909,即有大约 9% 的概率。

Redis 集群数据分布

Redis 集群没有使用一致性hash,引入了哈希槽(HASH SLOT).Redis 集群中所有的主节点都负责 16384 个哈希槽中的一部分。当集群处于稳定状态时,集群中没有在执行重配置(reconfiguration)操作,每个哈希槽都只由一个节点进行处理(不过主节点可以有一个或多个从节点,可以在网络断线或节点失效时替换掉主节点) slot = CRC16(KEY) / 16384

Redis 集群键HASH标签

目标:     HASH 标签是确保两个KEY 都能在同一个HASH槽的一种方式。实现方式:    HASH 槽是用另一种不同的计算方式计算的。基本来说,如果KEY包含一个"{...}"这样的模式,只有“{” 和 “}” 之间的字符串会被用来做HASH以获取HAS槽。如果同时出现多个“{}” 计算方式如下:    * 如果KEY 包含一个 “{” 字符    * 那么在 “{”的右边就会字符 "}"    * 在字符 "{" 和 "}"直接会有一个或多个字符。但是第一个"}" 一定会出现在第一个"{"之后    * 只有在第一个 { 和它右边第一个 } 之间的内容会被用来计算哈希值例子:    1、比如这两个键 user:{1000}.following 和user:{1000}.followers 会被哈希到同一个哈希槽里,因为只有 "1000" 这个子串会被用来计算哈希值。    2、对于 user{}{list} 这个键,整个键都会被用来计算哈希值,因为第一个出现的 { 和它右边第一个出现的 } 之间没有任何字符。    3、对于 user{{momoid}}following 这个键,用来计算哈希值的是 "{momoid" 这个子串,因为它是第一个 { 及其右边第一个 } 之间的内容。    4、对于 user{momoid}{following} 这个键,用来计算哈希值的是 "momoid" 这个子串,因为算法会在第一次有效或无效(比如中间没有任何字节)地匹配到 { 和 } 的时候停止。    5、按照这个算法,如果一个键是以 {} 开头的话,那么就当作整个键会被用来计算哈希值。当使用二进制数据做为键名称的时候,这是非常有用的。

Redis 集群相关命令

集群    1、CLUSTER INFO 打印集群的信息      2、CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。     3、CLUSTER FAILOVER 手动故障转移,需要在转移的主节点的从节点上执行 节点      1、CLUSTER MEET   将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。      2、CLUSTER FORGET  从集群中移除 node_id 指定的节点。      3、CLUSTER REPLICATE  将当前节点设置为 node_id 指定的节点的从节点。      4、CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。  槽(slot)      1、CLUSTER ADDSLOTS  [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。      2、CLUSTER DELSLOTS  [slot ...] 移除一个或多个槽对当前节点的指派。      3、CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。      4、CLUSTER SETSLOT  NODE  将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽,然后再进行指派。      1、CLUSTER SETSLOT  MIGRATING  将本节点的槽 slot 迁移到 node_id 指定的节点中。      2、CLUSTER SETSLOT IMPORTING  从 node_id 指定的节点中导入槽 slot 到本节点。      3、CLUSTER SETSLOT  STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。  键      1、CLUSTER KEYSLOT  计算键 key 应该被放置在哪个槽上。      2、CLUSTER COUNTKEYSINSLOT  返回槽 slot 目前包含的键值对数量。      3、CLUSTER GETKEYSINSLOT   返回 count 个 slot 槽中的键。    不支持的命令:    1、不支持SELECT 命令,集群只使用数据库 0     2、不支持多个KEY的操作 如 MSET、SUION、SINTER等命令 (因为KEYS 无法hash到同一个slot中) redis-trib.rb 相关命令    1、redis-trib.rb create [--replicas N] host:ip [host:ip ...]  创建集群    2、redis-trib.rb add-node host:ip host:ip  将前面的host:ip 添加到集群中    3、redis-trib.rb check host:ip 检查集群的状态    4、redis-trib.rb reshard host:ip OR  redis-trib.rb reshard --from host:port --to host:port --slots --yes集群重新分片    5、redis-trib.rb del-node host:ip 'NODE ID' 将节点从集群中移除

Redis 集群配置

redis 集群需要运行在 集群模式的redis实例,不是普通的redis实例。集群模式需要添加集群相关的配置。开启集群模式的redis实例,可以使用集群特有的命令和特性

其中相关配置如下:

必须配置:cluster-enabled yes                         --> 开启集群模式cluster-config-file nodes-30000.conf        --> 集群相关的信息cluster-node-timeout 15000                  --> 节点超时时间,用来failover的操作 可选配置:cluster-slave-validity-factor 10            cluster-migration-barrier 1cluster-require-full-coverage yes

Redis Cluster 主从搭建

启动集群模式的实例(与普通启动方式一致),不需搭建主从关系

搭建集群: 在上述启动的6个redis实例中,搭建集群。通过redis自带的集群命令行工具 redis-trib.rb 。 redis-trib.rb 位于redis源码包中src文件中。它可以完成创建集群、检查集群、集群reshard、添加节点、删除节点等操作

创建集群 redis-trib.rb create [–replicas [N]] host:ip [host:ip]

redis-trib.rb create --replicas 1 127.0.0.1:30000 127.0.0.1:30001 127.0.0.1:30001 127.0.0.1:31000 127.0.0.1:31001 127.0.0.1:31002其中 --replicas N 选项表明集群中的每个节点带几个从节点 输出日志:    [OK] All 16384 slots covered

集群状态检查 redis-trib.rb check host:ip

redis-trib.rb check 127.0.0.1:30000输出日志:    Connecting to node 127.0.0.1:30000: OK    Connecting to node 127.0.0.1:30002: OK    Connecting to node 127.0.0.1:31000: OK    Connecting to node 127.0.0.1:31001: OK    Connecting to node 127.0.0.1:30001: OK    Connecting to node 127.0.0.1:31002: OK    >>> Performing Cluster Check (using node 127.0.0.1:30000)    M: 36801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000        slots:0-5961,10923-11421 (6461 slots) master        1 additional replica(s)    M: 98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002        slots:11422-16383 (4962 slots) master        1 additional replica(s)    S: 54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000        slots: (0 slots) slave        replicates 36801ef9849f12526be1e954f9e6f6fa24c50d46    S: 3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001        slots: (0 slots) slave        replicates 6b880ae14f8c9dbfd54f8c4811cf0c039d523216    M: 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001        slots:5962-10922 (4961 slots) master        1 additional replica(s)    S: 81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002        slots: (0 slots) slave        replicates 98c4c66ee189569dec47a9600b057f90626cc6a7    [OK] All nodes agree about slots configuration.    >>> Check for open slots...    >>> Check slots coverage...    [OK] All 16384 slots covered.

添加节点: 启动一个新的集群模式的redis实例。使用 redis-trib.rb add-node host:ip host:ip

redis-trib.rb add-node 127.0.0.1:30004 127.0.0.1:3000其中  127.0.0.1:30004 为新节点  127.0.0.1:30000 为集群中任意节点 查看集群节点:    redis-cli  -c -p 30000    127.0.0.1:30000> CLUSTER NODES    98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002 master - 0 1429686483614 3 connected 11422-16383    54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000 slave 36801ef9849f12526be1e954f9e6f6fa24c50d46 0 1429686485615 7 connected    3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001 slave 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 0 1429686484614 5 connected    2eb135bf03dbdbc57e704578b2833cc3fb860b6e 127.0.0.1:30004 master - 0 1429686479607 0 connected   --> 新节点    6b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001 master - 0 1429686481612 2 connected 5962-10922    81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002 slave 98c4c66ee189569dec47a9600b057f90626cc6a7 0 1429686482613 6 connected    36801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000 myself,master - 0 0 7 connected 0-5961 10923-11421 输出信息解析:    1、节点ID    2、IP:PORT    3、节点状态标识: master、slave、myself、fail?、fail    4、如果是从节点,表示主节点的ID。如果是主节点,为 '-'    5、集群最近一次向各个节点发送PING命令后,过去多长时间还没有接到回复    6、节点最近一次返回PONG的时间戳    7、节点的配置纪元    8、本节点的网络连接情况: connected、disconnected    9、如果是主节点,表示节点包含的曹

添加从节点: CLUSTER REPLICATE ID

 127.0.0.1:31004> CLUSTER REPLICATE 2eb135bf03dbdbc57e704578b2833cc3fb860b6e        其中  2eb135bf03dbdbc57e704578b2833cc3fb860b6e 为主库的集群ID

集群reshard: 为新节点分片slots redis-trib.rb reshard host:port

redis-trib.rb reshard 127.0.0.1:30004日志输出:Shell# redis-trib.rb reshard 127.0.0.1:30004Connecting to node 127.0.0.1:30004: OKConnecting to node 127.0.0.1:30000: OKConnecting to node 127.0.0.1:31001: OKConnecting to node 127.0.0.1:30001: OKConnecting to node 127.0.0.1:31000: OKConnecting to node 127.0.0.1:30002: OKConnecting to node 127.0.0.1:31002: OK>>> Performing Cluster Check (using node 127.0.0.1:30004)M: 2eb135bf03dbdbc57e704578b2833cc3fb860b6e 127.0.0.1:30004      --> 新节点信息   slots: (0 slots) master   0 additional replica(s)M: 36801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000   slots:0-5961,10923-11421 (6461 slots) master   1 additional replica(s)S: 3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001   slots: (0 slots) slave   replicates 6b880ae14f8c9dbfd54f8c4811cf0c039d523216M: 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001   slots:5962-10922 (4961 slots) master   1 additional replica(s)S: 54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000   slots: (0 slots) slave   replicates 36801ef9849f12526be1e954f9e6f6fa24c50d46M: 98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002   slots:11422-16383 (4962 slots) master   1 additional replica(s)S: 81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002   slots: (0 slots) slave   replicates 98c4c66ee189569dec47a9600b057f90626cc6a7[OK] All nodes agree about slots configuration.>>> Check for open slots...>>> Check slots coverage...[OK] All 16384 slots covered.How many slots do you want to move (from 1 to 16384)? 1000               --> slot数量What is the receiving node ID? 2eb135bf03dbdbc57e704578b2833cc3fb860b6e  --> 接收集群NODE ID  Please enter all the source node IDs.  Type 'all' to use all the nodes as source nodes for the hash slots.  Type 'done' once you entered all the source nodes IDs.Source node #1:36801ef9849f12526be1e954f9e6f6fa24c50d46                  --> 来源NODE IDSource node #2:done......

Redis Cluster failover机制

节点心跳

Redis 集群在运行的过程中,每个节点每秒会随机ping几个节点,不过每个节点都会保证去PING满足这个条件的其他节点:在过去的一半"cluster-node-timeout"时间里都没有发送PING包过去或者没有接收从那节点发来的PONG包的节点。在"cluster-node-timeout"时间过去之前,若TCP连接有问题,节点会尝试去重试连接,确保自己不会被当做不可达的节点。如果 “cluster-node-time” 被设为一个很小的数而节点数量(N)非常大,那么消息交流数量会比 O(N) 更大,因为每个节点都会尝试去 ping 每一个在过去一半 NODE_TIMEOUT 时间里都没更新信息的节点。

失效检测

Redis 集群失效检测是用来识别出大多数节点何时无法访问某一个主节点或从节点。当这个事件发生时,就提升一个从节点来做主节点;若如果无法提升从节点来做主节点的话,那么整个集群就置为错误状态并停止接收客户端的查询每个节点都有一份跟其他已知节点相关的标识列表。其中有两个标识是用于失效检测,分别是 PFAIL 和 FAIL.       PFAIL 标识: 表示可能失效(Possible failure),这是一个非公认的(non acknowledged)失效类型。              当一个节点在超过 "cluster-node-timeout" 时间后仍无法访问某个节点,那么它会用 PFAIL 来标识这个不可达的节点。无论节点类型是什么,主节点和从节点都能标识其他的节点为 PFAIL       FAIL 表示一个节点已经失效,而且这个情况已经被大多数主节点在某段固定时间内确认过的了。              满足以下条件,PFAIL 状态升级为 FAIL 状态:(设定集群含有 A B C AS BS CS 六个节点)                     1、节点A正常,节点C 状态为 PFAIL                     2、节点A 通过gossip字段收集集群中大部分节点标识节点C的状态信息                     3、如果大部分节点标识节点C为 PFAIL 状态,或者 cluster-node-timeout *  FAIL_REPORT_VALIDITY_MULT 这段时间内处于 PFAIL状态                                   此时节点A 会标记 节点C 为 FAIL 状态,并向所有的节点发送关于节点C的 FAIL 信息。 FAIL 信息会强制接收的节点把节点C 标识为 FAIL 状态              NOTE:       FAIL 标识基本都是单向的,也就是说,一个节点能从 PFAIL 状态升级到 FAIL 状态. 清除FAIL状态的方法:              1、节点已经恢复可达的,并且它是一个从节点。在这种情况下,FAIL 标识可以清除掉,因为从节点并没有被故障转移。              2、节点已经恢复可达的,而且它是一个主节点,但经过了很长时间(N * NODE_TIMEOUT)后也没有检测到任何从节点被提升了。

从选举与提升

 从节点的选举与提升都是由从节点处理的,主节点会投票要提升哪个从节点。当满足以下条件,一个节点可以发起选举:              1、该从节点的主节点处理 FALI 状态              2、这个主节点负责的HASH曹个数不为O              3、从节点和主节点之间的重复连接(replication link)断线不超过一段给定的时间,这是为了确保从节点的数据是可靠       一旦从节点被推选出来,就会想主节点请求投票,一旦从节点赢得投票,它会响所有其他节点发送PING 和 PONG 数据包,宣布自己已经成为主节点,并且提供它的HASH槽信息,并配置 currentEpoch 信息       为了加速其他节点的重新配置,该节点会广播一个 pong 包 给集群里的所有节点(那些现在访问不到的节点最终也会收到一个 ping 包或 pong 包,并且进行重新配置)。其他节点会检测到有一个新的主节点(带着更大的configEpoch)在负责处理之前一个旧的主节点负责的哈希槽,然后就升级自己的配置信息。 旧主节点的从节点,或者是经过故障转移后重新加入集群的该旧主节点,不仅会升级配置信息,还会配置新主节点的备份。

模拟宕机(实现故障转移)

集群当期转态:

127.0.0.1:30000> CLUSTER NODES98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002 master - 0 1429696352375 3 connected 11422-1638354d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000 slave 36801ef9849f12526be1e954f9e6f6fa24c50d46 0 1429696349869 9 connected3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001 slave 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 0 1429696346364 5 connected6b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001 master - 0 1429696351373 2 connected 5962-1092281a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002 slave 98c4c66ee189569dec47a9600b057f90626cc6a7 0 1429696350370 6 connected36801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000 myself,master - 0 0 9 connected 0-5961 10923-11421 其中 127.0.0.1:31000 节点为 127.0.0.1:30000 从节点

关闭其中的一个节点后(127.0.0.1:30000)的集群状态:

127.0.0.1:30001> CLUSTER NODES81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002 slave 98c4c66ee189569dec47a9600b057f90626cc6a7 0 1429696448146 6 connected98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002 master - 0 1429696447143 3 connected 11422-163836b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001 myself,master - 0 0 2 connected 5962-1092236801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000 master,fail? - 1429696434521 1429696430116 9 disconnected 0-5961 10923-114213f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001 slave 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 0 1429696445139 5 connected54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000 slave 36801ef9849f12526be1e954f9e6f6fa24c50d46 0 1429696449148 9 connected 其中 127.0.0.1:30000 的状态fail? 表示正在判断是否失败 127.0.0.1:30001> CLUSTER NODES81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002 slave 98c4c66ee189569dec47a9600b057f90626cc6a7 0 1429696473317 6 connected98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002 master - 0 1429696474317 3 connected 11422-163836b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001 myself,master - 0 0 2 connected 5962-1092236801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000 master,fail - 1429696434521 1429696430116 9 disconnected3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001 slave 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 0 1429696472315 5 connected54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000 master - 0 1429696471313 10 connected 0-5961 10923-11421 其中 127.0.0.1:30000 的状态 fail 表示节点失败,127.0.0.1:30000 节点提升为主库。

恢复关闭的实例

127.0.0.1:30001> CLUSTER NODES81a3a70ce2fbb8bcce2e9be9ed77e34d9d4d5b21 127.0.0.1:31002 slave 98c4c66ee189569dec47a9600b057f90626cc6a7 0 1429696545465 6 connected98c4c66ee189569dec47a9600b057f90626cc6a7 127.0.0.1:30002 master - 0 1429696542960 3 connected 11422-163836b880ae14f8c9dbfd54f8c4811cf0c039d523216 127.0.0.1:30001 myself,master - 0 0 2 connected 5962-1092236801ef9849f12526be1e954f9e6f6fa24c50d46 127.0.0.1:30000 slave 54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 0 1429696542458 10 connected3f5ae989b9b1b6617c53e77ed4853b618408bbe6 127.0.0.1:31001 slave 6b880ae14f8c9dbfd54f8c4811cf0c039d523216 0 1429696546467 5 connected54d7d1241b1d9c24f76d99e9814d8cf8d8db474e 127.0.0.1:31000 master - 0 1429696547470 10 connected 0-5961 10923-11421 其中 127.0.0.1:30000 变成 127.0.0.1:31000的从库

总结:

优点:    1、redis 在主节点下线后,从节点会自动提升为主节点,提供服务    2、redis 宕机节点恢复后,自动会添加到集群中,变成从节点缺点:    1、由于redis的复制使用异步机制,在自动故障转移的过程中,集群可能会丢失写命令。然而 redis 几乎是同时执行(将命令恢复发送给客户端,以及将命令复制到从节点)这两个操作,所以实际中,命令丢失的窗口非常小。

集群订阅、发布

Redis 集群中,客户端能订阅任何一个节点,也能发布消息给任何一个节点。集群会确保发布的消息都会按需进行转发

 

posted @ 2017-07-30 12:35  yijiaotu  阅读(94)  评论(0编辑  收藏  举报