一、简介
主从模式可以避免单点故障,实现读写分离。
一个主节点(M)可以有多个从节点(S),在S的配置文件里配M的地址、端口、密码即可。S一般是只读的,修改配置slave-read-only no
可以让S可写。
主从同步过程:
Redis全量复制一般发生在Slave首次初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体主从同
步骤如下:
1)从服务器连接主服务器,发送SYNC命令;
2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB快照文件并使用缓冲区记录此后执行的所有写命令;
3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
7)后期同步会先发送自己slave_repl_offset位置,只同步新增加的数据,不再全量同步。
二、Sentinel(哨兵模式)
Redis Sentinel程序集群(一般有3-5个节点)用来监控redis集群,客户端连进来时会先连接sentinel,获取Master的地址,再去连接Master进行操作。假如某个Master挂了,sentinel就从Slave节点中选一个最优的转为Master,然后将这个节点的地址告诉客户端。原先挂点的节点恢复之后,会变成Slave加入到集群。
sentinel尽可能为了尽可能保证消息少丢失,有2个参数限制主从延迟过大:
min-slaves-to-write 1
min-slaves-max-lag 10
第一个参数表示主节点至少有1个从节点在正常复制,否则就停止提供写服务。
第二个参数表示如果10秒内主节点没收到从节点的反馈,那么就意味着主从同步不正常。
缺点:不好扩容
三、Codis
redis客户端通过Codis中间件集群来读写,Codis拿到key时,将它那些crc32得到hash值,然后对1024(可配)取模得到一个槽位(slot),Codis就将这个key存到对应的redis节点上。不同的Codis实例直接通过zk来同步槽位信息。增加节点时,Codis会扫描slot下的所有key,进行迁移。迁移过程中如果收到某个key的命令,那就对该key先进行迁移(如果需要的话),然后再去新的节点里操作。
缺点:
- 不支持事务,rename等。因为事务只能在单实例里完成,rename的两个key如果在不同实例里的话也是无法完成的。
- 单个key对应的value不宜过大,否则迁移较慢
- 因为是中间件,增加网络开销,稍微影响性能。
- 需要维护zk
优点:
设计简单,后台管理界面友好,支持服务服务集群管理,也不像redis cluster那样需要大量调优的参数。
四、Redis Cluster
他,是Redis的亲儿子,他将所有数据划分为16384个slots,拿到key时默认会对key进行crc32进行hash,然后将得到的值对16384取模,得到的结果作为slot。每个节点负责一部分,槽位信息存在每个节点里。当client连接集群时,它也会得到一份集群的槽位配置信息,当client要查某个key时,直接定位点目标节点。
跳转
当客户端像一个错误的节点发出指令时,该节点发现所属槽位不归自己管,就给客户端回个MOVED
指令:-MOVED 3999 127.0.0.1:6381
,表示3999槽位已经迁移到127.0.0.1:6381节点了,然后客户端修改自己的槽位映射表。
迁移
Redis Cluster提供了redis-trib让运维人员可以手动迁移。迁移的单位是slot,过程大概就是从源节点获取内容 => 存到目标节点 => 从源节点删除内容
。
Redis Cluster可以为每个主节点设置从节点,主节点down掉时,从节点可以提升为主节点。真实的机房里往往会出现网络抖动,就是部分节点直接连接变得不可访问,然后又很快恢复。因此redis cluster提供参数cluster-node-timeout
表示某节点一定时间timeout时才被判定down掉了。如果节点down了,客户端会收到ClusterDown的错误,这时客户端就会关闭所有的连接,清空槽位映射关系表,然后向上层抛错。待下一条指令过来时,就会重新尝试初始化节点信息。
参考资料
《Redis 深度历险: 核心原理和应用实践》
Redis 主从配置
网友评论