1、Redis集群要求
Redis版本需要是 3.0及更高版本
需要2个TCP端口,一个是提供给客户端的端口,例如默认的6379;一个是集群总线通信端口,例如16379(一般是为客户端提供服务的端口号+10000)
目前Redis集群不支持NATted环境和IP地址或TCP端口重新映射的一般环境。
注意事项:如果没有开启上述端口,那么集群可能不会按照预想的方式工作;如果存在防火墙,那么,需要在防火墙上同时开启两个端口。
2、Redis集群作用
1)、自动在多个节点上分割数据集
2)、当节点失败后,可以继续执行操作
集群总线的作用:失败节点的探测、配置数据更新、认证失败、节点与节点之间的数据交换等等。集群总线使用比较小的带宽和处理时间。
3、Redis集群运行方式
1)、通过Docker运行。使用Docker暴漏端口的方式,可以实现多个容器在同一台服务器上同一时间使用同一个端口
注意事项:为了保证Docker正常运行Redis集群,需要使用Docker的主机网络模式(Host Networking mode),可以在Docker文档中,查看 --net=host参数
4、Redis集群数据共享
Redis Cluster不使用一致的哈希,而是一种不同形式的分片,其中每个键都是我们称为哈希槽(Hash Slot)的概念的一部分。
在Redis Cluster中一共有 16384 个哈希槽,要计算给定密钥的哈希槽,只需取该密钥的CRC16对16384进行模运算。
举例,如果有一个3个节点的集群,如下:
Node A contains hash slots from 0 to 5500.
Node B contains hash slots from 5501 to 11000.
Node C contains hash slots from 11001 to 16383.
如何实现Redis集群中节点增加和删除的管理操作?
1)、增加新节点。需要从A、B、C节点移动一些哈希槽给到D,
2)、删除旧节点。移动A节点的哈希槽值给到B、C,等A完全空了之后从集群中移除
5、Redis集群主从模式(Master-Slave mode)
为了在主节点子集失败或无法与大多数节点通信时保持可用,Redis集群使用一个主从模型,其中每个哈希槽有1个(主节点本身)到N个副本(N-1个额外的从节点)
例如,在上述3个节点的集群中,如果B节点不可用,那么哈希槽5501-11000将不可用。如果我们在集群上每个主节点加上一个从节点,则A、B、C为主节点,A1、B1、C1为从节点,这样,尽管B节点不可用了,那么Redis集群会将从节点B1提升为主节点。
注意,如果B节点和B1节点同时故障,Redis Cluster将无法继续运行。
6、Redis集群保证一致性
Redis集群不能保证非常强的一致性。在实际操作中,这意味着在当前的某些条件下,Redis集群可能在系统返回给客户端确认前,丢失一部分数据写入。 具体原因:1)、Redis集群采用的是异步复制模式 2)、如果Redis集群使用的是同步的方式,那么会大大降低集群的性能
Redis操作的生命周期:
1)、redis-cli连接redis-server
2)、redis执行客户端命令
3)、redis-server中写入数据到磁盘
4)、redis-server将写入结果返回给客户端
如果在绝对需要的场景中需要实现同步写的话,那么可以使用WAIT命令,这样可以尽可能地减少丢失写的操作。但是要注意:即使这样,也不能完全保证不丢失写的数据。
还有一个值得注意的场景是Redis Cluster会丢失写操作,这发生在一个网络分区中,其中一个客户端与包括至少一个主服务器在内的少数实例隔离。 也就是说,如果在 6 个节点的集群中包括:A, B, C, A1, B1, C1, 有3 个masters 和3 个slaves。同时还有一个客户端Z1,如果出现分区,那么就会一面有A, C, A1, B1, C1,另一面有B 和Z1。Z1是还可以写入到B的,如果分区在很短的时间内恢复,集群将继续正常运行。 但是,如果分区持续的时间足够让B1在分区的多数端提升为master,那么Z1在此期间发送给B的写操作就会丢失。这个时候,就需要配置一个时间量,这个时间量是Redis Cluster的一个非常重要的配置指令,被称为节点超时(node timeout)。 在节点超时后,主节点被认为是失败的,可以用它的一个副本替换。 类似地,当节点超时后,主节点无法感知其他大多数主节点时,它将进入错误状态并停止接受写操作。
7、Redis集群配置参数
配置文件名:redis.conf
参数详解:
cluster-enabled
cluster-config-file
cluster-node-timeout
cluster-slave-validity-factor
cluster-migration-barrier
cluster-require-full-coverage
cluster-allow-reads-when-down
8、创建Redis集群
为了创建一个集群,我们首先需要在集群模式下运行一些空的Redis实例。 这基本上意味着集群不是使用普通的Redis实例创建的,因为需要配置一种特殊的模式,这样Redis实例才能启用集群特定的功能和命令。
最小化集群配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
注意:最小集群需要是要包含3个master节点。建议使用6个节点部署,其中包括 3个主节点和3个从节点。
本地部署集群步骤:
# 创建集群运行目录
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005
# 拷贝redis-server可执行文件,到cluster-test目录中,然后进入到节点目录中
cd 7000
../redis-server ./redis.conf
# 由于nodes.conf文件不存在,那么每个集群节点会分配自己一个新的ID,在每个实例的日志中可以看到:
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
上述ID,就是集群中每个节点互相记住的凭证。我们称之为Node ID。
2种创建Redis集群的方式
# 第一种方式,使用redis-cli客户端
# 创建集群,在Redis 5及更高版本中,可以直接使用redis-cli,如果是Redis3或者Redis4中,需要使用redis-trib.rb
# Redis5版本及以上
redis-cli --cluster create 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 \
--cluster-replicas 1
参数说明:
*--cluster-replicas 1 表示每个集群主节点增加一个从节点
#Redis-cli将为您提供一个配置。 输入yes接受建议的配置。 集群将被配置并加入,这意味着,实例将被引导到彼此之间进行对话。如果一切顺利,你会看到这样一条消息:
[OK] All 16384 slots covered
#Redis3或者Redis4
./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
# 第二种方式,使用create-cluster脚本
#一般是在: utils/create-cluster 目录下,可以创建一个6个节点的集群,包括3个主节点和3个从节点
create-cluster start
create-cluster create
create-cluster stop
9、重新分配集群数据
重分片基本上意味着将散列槽从一组节点移动到另一组节点,与集群创建类似,它是使用redis-cli实用程序完成的。
# 操作方式:只需要指定一个节点
$ redis-cli --cluster reshard 127.0.0.1:7000
How many slots do you want to move (from 1 to 16384)?
$ redis-cli -p 7000 cluster nodes | grep myself
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5460
$ redis-cli --cluster check 127.0.0.1:7000
# 脚本操作方式
$ redis-cli --cluster reshard
10、测试并检查集群状态
$ redis-cli -p 7000 cluster nodes | grep master
3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385482984082 0 connected 5960-10921
2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 master - 0 1385482983582 0 connected 11423-16383
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422
$ redis-cli -p 7000 cluster nodes
3fc783611028b1707fd65345e763befb36454d73 127.0.0.1:7004 slave 3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 0 1385503418521 0 connected
a211e242fc6b22a9427fed61285e85892fa04e08 127.0.0.1:7003 slave 97a3a64667477371c4479320d683e4c8db5858b1 0 1385503419023 0 connected
97a3a64667477371c4479320d683e4c8db5858b1 :0 myself,master - 0 0 0 connected 0-5959 10922-11422
3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 127.0.0.1:7005 master - 0 1385503419023 3 connected 11423-16383
3e3a6cb0d9a9a87168e266b0a0b24026c0aae3f0 127.0.0.1:7001 master - 0 1385503417005 0 connected 5960-10921
2938205e12de373867bf38f1ca29d31d0ddb3e46 127.0.0.1:7002 slave 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e 0 1385503418016 3 connected
参数结果字段说明:
Node ID
ip:port
flags: master, slave, myself, fail, ...
if it is a slave, the Node ID of the master
Time of the last pending PING still waiting for a reply.
Time of the last PONG received.
Configuration epoch for this node (see the Cluster specification).
Status of the link to this node.
Slots served...
11、集群中添加新节点
# 添加新节点的步骤
1)、Create a new tab in your terminal application.
2)、Enter the cluster-test directory.
3)、Create a directory named 7006.
4)、Create a redis.conf file inside, similar to the one used for the other nodes but using 7006 as port number.
5)、Finally start the server with ../redis-server ./redis.conf
# 添加节点指令
$ redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
# 添加从节点指令
$ redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave
# 为指定节点添加从节点
$ redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
# redis 127.0.0.1:7006> cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
12、删除集群中的节点
$ redis-cli --cluster del-node 127.0.0.1:7000 `
# 注意:如果需要删除一个master节点,那么需要保证这个节点是空的
13、更新集群中的节点
# 建议的处理过程
1)、使用 CLUSTER FAILOVER 手动触发失败
2)、等待master节点变为slave节点
3)、更新节点
4)、如果想把更新后的节点变为master节点,那么再执行 CLUSTER FAILOVER 手动触发失败
14、Redis集群迁移数据
假设你已经将现有的数据集划分为N个主数据集,如果你没有现有的分片,在N=1时,如果你没有预先存在的分片,以下步骤是为了迁移你的数据集到Redis集群:
1)、停止客户端。目前还不可能自动迁移到Redis集群。 您可能能够在应用程序/环境的上下文中编排一个实时迁移。
2)、使用BGREWRITEAOF命令为N个Master节点生成一个AOF文件,然后等待AOF文件完成
3)、保存AOF文件为aof1~aofN,然后在这个时间点上,停止你旧的实例
4)、创建一个带有N个master节点,包含0个从节点的Redis集群,slave后面再添加,需要保证集群中的每个节点都是以AOF方式持久化
5)、停止所有集群节点,用你之前准备好的AOF文件一一对应替换现有节点的AOF文件
6)、使用新的AOF文件启动你的集群节点,启动中会提示没有相应的keys在AOF文件中
7)、使用 redis-cli --cluster fix 修复集群,以便keys根据哈希槽进行迁移
8)、最后使用 redis-cli --cluster check 命令保证集群是ok的
9)、修改适用于客户端的Redis集群库,然后重启客户端
有一个可供选择的方式,从外部实例导入数据到Redis集群,使用 redis-cli --cluster import 命令