在上一篇我们已经介绍了Redis集群分区的规则,在这一篇我们开始上干货,真真正正的搭建一个Redis集群。搭建Redis集群主要分3步:
1.准备节点 2.节点握手 3.分配槽
下面我们分别介绍一下上面3个步骤的的详细使用。
既然是搭建集群那么节点一定是多节点的,通常来说节点数量至少为6个才能保证高可用的集群。除此之外每个节点还需要配置cluster-enabled yes。由于每个节点的配置除了端口不同其它的配置均相同,所以我们已一个节点的配置为例,来介绍一个集群节点的配置。具体配置如下:
# 节点端口
port 6379
# 开启集群模式
cluster-enabled yes
# 节点超时时间,单位为毫秒
cluster-node-timeout 15000
# 集群内部配置文件
cluster-config-file "nodes-6379.conf"
下面我们启动6个节点:
./src/redis-server redis-6379.conf
./src/redis-server redis-6380.conf
./src/redis-server redis-6381.conf
./src/redis-server redis-6382.conf
./src/redis-server redis-6383.conf
./src/redis-server redis-6384.conf
当节点启动成功后,如果没有集群配置文件,Redis会自动创建一份,文件名就是我们Redis配置文件中cluster-config-file参数指定的名字。如果启动时存在集群配置文件,节点会使用配置文件中的内容初始化集群信息。具体的启动过程如下图所示:
集群模式的Redis除了原有的配置文件外还有一份集群配置文件。这是因为当集群內节点信息发生变化时,如添加节点、节点下线、故障转移等。节点会自动保存集群状态到配置文件中。并且集群配置文件不需要用户修改,而是由Redis自动维护。
由于我们刚刚启动了6379节点,所以Redis默认在Redis根路径生了nodes-6379.conf文件。下面我们看一下该文件中的内容。
nodes-6379.conf:
3f9fa1009630b24e8049117b8492503af64dbabb :6379@16379 myself,master - 0 0 0 connected 3612 5257 7743 8021 8280 9558 11276 12216 12539 14895
vars currentEpoch 0 lastVoteEpoch 0
文件内容记录了集群的初始状态。包括节点ID。它是一个40位16进制的字符串构成的,也是用来区分集群节点的唯一标识。上面提到的是节点ID并不是运行ID。它们有着很大的不同的。因为节点ID是集群初始化时只会创建一次,节点重启时会加载集群配置文件重用,而Redis的运行ID每次重启都会发生变化。除此之外我们也可以通过cluster nodes命令获取集群节点的信息。
每个节点暂时只能识别出自己的节点信息。虽然我们启动了6个节点,但它们彼此之间并不知道对方的存在。所以接下来我们要通过节点握手让它们彼此之间建立联系从而组成一个集群。
节点握手是指一批运行在集群模式下的节点通过Gossip协议彼此通信,从而可以感知其它节点的存在。节点握手是集群彼此通信的和一步,具体操作是在客户端发起下面命令:
cluster meet {ip} {port}
上图中的执行逻辑是:cluster meet 127.0.0.1 6380让节点6379和6380节点进行握手通信。cluster meet命令是一个异步命令,执行之后立刻返回。在Redis内部发起与目标节点进行握手通信。 下面我们执行下面命令让其它节点加入到集群中并可以使用cluster nodes命令查看其它节点是否加入了集群中。
我们在集群中任意节点执行cluster meet命令加入新节点时,握手状态会通过消息在集群内传播,这样其它节点会自动发现新节点并发起握手流程。节点建立握手之后集群还不能工作,因为集群处于下线状态,所有的数据读写都被禁止了。
我们看提示信息,提供槽没有提供服务。这是因为我们还没有为Redis分配槽。
Redis集群把所有的数据映射到16384个槽中。每个key会映射为一个固定的槽,只有当节点分配了槽,才能响应和这些槽关联的键命令。在Redis中可以通过cluster addslots命令为节点分配槽。具体命令如下:
按照上面的命令我们已经将16384个slot平均分配给了6379、6380、6381三个节点。我们可以通过cluster info命令查看集群状态。
通过上图我们知道集群的状态是ok的,说明集群已经进入了在一状态。并且所有的槽已经分配了节点,执行cluster nodes命令可以看到节点和槽的分配关系:
因为我们将槽分配到了前3个前点,还有其它的3个节点而没有使用。这是因为一个完整的集群,每个负责的处理槽都应该具有从节点为,以保障出现故障时自动进行故障转移。在集群模式下,Redis的节点会被分为主节点和从节点。因为我们将槽分配到了主节点,所以从节点主要复制主节点的槽信息和相关的数据即可。在Redis中我们可以通过cluster replicate {nodeId}命令让一个节点成为从节点。上述命令只能在从节点上执行,并且nodeId是主节点的ID,而不是运行ID。
Redis集群模式下的主从复制使用了之前文章中介绍的复制流程,依然支持全量和部分复制。我们依然可以通过cluster nodes命令查看集群状态和复制关系。
上述内容就是使用Redis中的Gossip协议手动的搭建了一个集群环境。通过上述的搭建我们知道手动搭建集群虽然可以加深我们对Redis集群流程的理解和细节,但是它的弊端也是有的,就是有很多个步骤,当集群节点过多时,我们手动搭建集群的复杂度和时间成本也就越大了。所以Redis为了帮助我们快速的搭建一个集群环境,于是提供了redis-trib.rb工具。通过此工具我们可以很快的搭建一个Redis集群。在下一篇中,我们将介绍redis-trib.rb工具的详细使用。