Redis学习(4)-----集群

思维导图:

引言

    本文是对Redis集群机制的简单介绍。主要内容有主从节点的原理,Cluster集群的构建及原理,最后,简单介绍了Redis的哨兵机制。

 

一.主从节点

    在对Cluster集群进行介绍之前,需要先了解Redis的主从节点机制,其本质思想是冗余设计,即当主节点异常时使用从节点代替主节点以使系统可以继续进行服务。

1.1 CAP原理

    因为Redis通常会在分布式系统中使用,所以这里对CAP原理进行简单介绍。

  • C :Consistent 一致性
  • A :Availability 可用性 
  • P : Partition tolerance 分区容忍性。

    分布式节点经常会出现网络断开,这种情况被称之为网络分区。每当出现网络分区的时候,数据的一致性便得不到满足,因为节点之间已不能进行通讯。而为了保持系统的一致性,便只能牺牲系统的可用性,即断掉出现网络分区的节点,也就是使用从节点从而保证系统的一致性。当无从节点可用的时候,整个系统便不能正常工作了。

    总之,当出现网络分区时,一致性和可用性便是鱼与熊掌不可兼得。

1.2 同步机制

    使用Cluster集群时,数据默认的复制方式是异步同步的,也被称为最终一致性。主节点会将必要的指令传输给从节点使其执行以保证一致性。从节点出现网络分区后,如果从节点再次成功接入主节点,那么从节点会采取多种方式同步数据。当然,Cluster也支持数据同步同步,使用wait命令即可做到,代价是速度的牺牲以及可能出现的永久性阻塞。

    Cluster集群有两种同步方式,一种是增量同步,一种是快照同步,其原理类似于持久化的AOF和快照。

增量同步

    Redis中内存有有一个缓存buffer,其数据结构是环形数组。Redis会将其执行的存在内容修改的指令存入次环形数组中,然后将环形数组的内容传输给从节点以保证数据的一致性。从节点在收到指令并执行后,会返回以执行到哪里的信息,也就是偏移量。所以,Cluster存在一个问题。当从节点长时间与主节点断开连接时,主节点环形数组的大小是有限的,可能就会出现还尚未传输的指令直接被覆盖的情况。这种时候就需要使用快照同步了。

快照同步

    快照同步就是Redis在本地做一次快照bgsave,然后将生成的持久化文件直接传输到从节点,最后从节点(已清空)执行快照文件的内容。因为在本地进行快照会消耗相当大的IO资源,所以有了无盘同步,其实就是直接将快照的信息通过套接字传输给从节点而不再本地写入快照文件。

 

二. Cluster集群

    Cluster集群只是Redis集群化方案的其中一种,但是这是由Redis作者支持的,所以Redis的集群以Cluster为例。

2.1 Cluster原理

    Redis Cluster会将所有数据划分为16384个槽位。集群的每个节点会负责其中的一部分,即槽位和节点之间是存在映射关系的。节点对应的槽位信息会被持久化到本地的文件中。

    客户端则会缓存槽位的相关信息,这样,当客户端需要定位某个key时,就可以直接定位到目标节点。

2.1.1 槽位定位

    Redis Cluster默认使用crc16算法进行hash然后对16384取模以确定key对应的槽位。也可以使用tag标记强制性的将key定位在tag所在的槽位上

2.1.2 跳转

    当客户端向错误的节点发送指令后,该节点会发现此槽位不归自己管理,他会发送一个特殊的跳转指令并携带目标操作的节点地址,客诉客户端连接这个节点可以获取数据,如下图:

get x                                     //获取key x
-MOVED 1000 127.0.0.0:7000                //1000表示槽位编号,后面则是正确节点的IP地址和端口号

2.1.3 迁移

    Redis Cluster可以利用redis-trib工具将一个槽位迁移至另一个节点。当槽位正在进行迁移时,源节点的此槽位会被设置为中间状态migrating,目标节点此槽位被设置为importing状态。随后,redis-trib会获取源节点此槽位中的key列表,然后一个一个key的存入目标节点并删除源节点中的数据。如果key很大的话,会导致Redis的阻塞,而key小则不会有太大的影响,所以尽量避免大key出现。

    当槽位的某个key正在迁移而客户端又恰恰好在此时访问时,源节点则会返回一个 -ASK targetNodeAddr 的重定向指令。客户端接收到 ASK指令后会去目标节点执行一个没有任何参数的ASKING指令。然后会在目标节点重新执行原先的操作指令。执行ASKING指令的原因是当客户端请求源节点时,源节点发现槽位正在迁移,所以返回一个MOVED指令,这样就可能会出现重定向循环,ASKING指令就是说,下一个指令必须当成自己的槽位处理。

2.1.4 主从切换

    因为网络可能会出现网络抖动,即突然间部分连接不可访问,然后又突然可以访问了。我们可以通过设置cluster-node-timeout来避免出现误判。他的意思是必须超过此时间才会认定出现节点故障。

    Redis Cluster是去中心化得,所以当少量的节点认为某个节点出现出现故障后并不会进行主从切换,而是广播此节点失联了   P FAIL。只有当大量节点认为某个节点出现主从故障时即P FAIL COUNT 以达到集群的大多数时,会立即对该节点进行主从切换。

 

2.2 Cluster构建

    Redis Cluster 集群的构建主要分为三大步骤:

  1. 修改redis.conf配置
  2. 启动redis
  3. 运行cluster构建命令

    看网上的博客,以前在配置Cluster集群的时候需要用到Ruby,但是最新版本的Redis已经不需要使用Ruby就可以构建Cluster集群了。取而代之的时redis-cli。以前用的命令都被移植到了这个命令下,系统会有提示。

    为了模拟三主三从共六个节点的场景,我们首先创建这六个节点所在的文件夹

mkdir redis-cluster //用于储存6个节点
mkdir 7000 7001 7002 7003 7004 7005 //以端口号在同一台机器上区分6个节点
cp ../redis-5.0.4/redis.conf  ./7000 //每个节点的文件夹下都创建一个配置文件

 

2.2.1 redis.conf配置

    我们将redis.conf文件经过以下修改,每个节点的端口号不同,分别copy到6个节点的文件夹下

bind 127.0.0.1  //绑定服务器IP地址

port 7000  //绑定端口号,必须修改,以此来区分Redis实例

daemonize yes  //后台运行

pidfile /var/run/redis-7000.pid  //修改pid进程文件名,以端口号命名

logfile /home/zhouhao/redis-cluster/7000/redis.log  //修改日志文件名称,以端口号为目录来区分

dir /home/zhouhao/redis-cluster/7000/  //修改数据文件存放地址,以端口号为目录名来区分

cluster-enabled yes  //启用集群

cluster-config-file nodes-7000.conf  //配置每个节点的配置文件,同样以端口号为名称

cluster-node-timeout 15000  //配置集群节点的超时时间,可改可不改

appendonly yes  //启动AOF增量持久化策略

appendfsync always  //发生改变就记录日志

2.2.2 运行Redis

    使用服务端命令启动六个Redis实例并指定redis.conf文件位置。我这里使用的相对路径,所以在不同机器上实验时路径可能有变化。

./src/redis-server ../redis-cluster/7000/redis.conf
./src/redis-server ../redis-cluster/7001/redis.conf
./src/redis-server ../redis-cluster/7002/redis.conf
./src/redis-server ../redis-cluster/7003/redis.conf
./src/redis-server ../redis-cluster/7004/redis.conf
./src/redis-server ../redis-cluster/7005/redis.conf

2.2.3 创建Cluster集群

//replicas 1 指主从节点配置比例为1:1
//-a zhouhao960824 因为我的redis文件中定义了密码,所以需要指定米面
./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 -a zhouhao

2.2.4 使用

//进入指定节点 -c 必须,指cluster集群,-h ip,-p 端口号
./redis-cli -c -h 127.0.0.1 -p 7000
//查看节点状态
cluster nodes

运行上述命令后便可以查看cluster集群的状态了,如下图:

 

三 哨兵 Sentinel

    这个小节会对哨兵做简单的概念性介绍。

    哨兵是官方提供的一种用于抵抗节点故障的一种方案。他可以帮组我们在节点故障的时候自动进行主从切换,而不需要运维人员维护。

    假如有如下场景,现有一主两从的Redis 哨兵集群。哨兵就会持续监控主节点的健康状态。客户端连接集群时,会首先连接哨兵,通过哨兵来查询主节点地址,然后在连接主节点进行数据交互。

    如果主节点挂掉了,哨兵会自动选择一个最优的从节点切换成主节点。此后,如果客户端再次访问,哨兵就会将最新的主节点地址返回客户端。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值