1.主从模式
一个Master与若干Slave组成主从关系,当Slave与Master首次建立连接时,Master向Slave进行全量数据复制,复制结束后,再根据Master的最新数据变更进行增量数据复制。
Master向过多的Slave复制数据,则同样会出现“复制风暴”的问题。
在主从模式下,Master宕机后,需要手动把一台Slave服务器切换为主服务器。
2.哨兵模式
哨兵模式的核心还是主从模式,只不过它在相对于主从模式下Master宕机导致不可写的情况下,提供了一种自动竞选机制:所有的Slave竞选新的Master。
竞选机制的实现依赖于Sentinel服务器。在一个主从模式的Redis架构中会部署若干Sentinel节点,每个Sentinel节点都会与Master、Slave维持心跳。当超过N个Sentinel节点认为Master宕机时,Sentinel节点会协商选举出一个Slave担任新的Master。Sentinel节点会告知所选举出的Slave节点它已被提升为Master,其他的Slave则转而与这个新的Master建立连接,复制数据。引入Sentinel节点可以自动进行主从切换。
3.集群模式
无论是主从模式还是哨兵模式,都只有一个Master对外提供服务。实际上,互联网公司在应用Redis时会采用数据分片的方式:多个Master对外提供服务,全量数据分散在各个Master中。
集群模式使得Redis真正拥有了分布式存储能力。一个Redis集群由多个Redis节点组成,一个Master和若干Slave组成一个组,代表一个数据分片。每个数据分片都通过主从模式保证高可用。
Redis集群基于哈希槽进行数据分片:整个Redis数据库被划分为16384个哈希槽,这些Master把16384个槽位都瓜分了。
当向Redis集群中写入某个数据时,会基于数据Key进行CRC16算法,然后将结果与16384取模得到一个槽位。此数据会被归属到这个槽位上,会被存储到管理这个槽位的Master上。
Redis集群中每个节点都保存有各个节点的IP地址及其所负责的槽位信息,于是Redis客户端连接任意一个节点都能保证对数据的读写路由到正确的数据分片。
Gossip协议
- 在一个节点数量有限的通信网络中,每个节点都会随机与部分节点通信,经过多轮迭代通信后,各个节点的信息在一定时间内回达成一致。
- 与Redis集群相关的消息类型有:meet, ping, pong, fail
- 相关的事件:集群新增节点,节点故障转移
- Gossip协议优点在于集群元信息的更新比较分散,但是需要经过多次传播才能通知到集群内所有的节点,它是一个最终一致性协议
- 当节点只有几百个时,可以运行良好,如果集群节点有成千上万个时,Gossip协议回造成集群内部存在大量网络通信,严重占用网络带宽,形成Gossip风暴
- 解决Gossip风暴问题的最好方法就是使用中心化结构
4.中心化集群结构
Twemproxy代理
- 通过中间代理的形式,Redis客户端将请求发送到Twemproxy,然后Twemproxy根据数据路由规则将请求发送到正确的Redis节点,最后Twemproxy将请求执行结果汇总并返回给客户端
- 通过引入Twemproxy作为客户端访问Redis节点的中间代理,为集群提供了数据分片的负载均衡能力,提高了Redis节点的高可用性和可扩展性。
- 优点:减少客户端与Redis实例连接数,使用方便,核心逻辑在Twemproxy
- 缺点:管理后台不友好,无法支持平滑的Redis集群扩容
Codis项目
- 将数据划分为N个槽位(1024个),每个槽位负责存储若干数据(使用CRC32算法)
- 四大核心组件
Codis Server:经过二次开发的Redis服务器,支持数据迁移操作。
Codis Proxy:接收客户端请求并转发给Codis Server,作用与Twemproxy一样,都是中间代理。
ZooKeeper集群:用于保存Redis集群元信息,包括每个Redis数据分片负责管理的槽位信息、各个Redis节点的地址信息。还保存了Codis Proxy的地址列表,提供Redis客户端访问Redis集群的服务发现能力。
Codis Dashboard和Codis Fe:共同组成了集群运维管理工具,前者负责Redis集群扩缩容、Codis Proxy集群扩缩容、槽位迁移等,后者负责提供Dashboard的友好Web操作界面。 - Codis将Redis集群中每个数据分片定义为Redis Server Group。一个Group包括一个Redis Master和若干Slave,用于保证每个数据分片的高可用。
参考
- 《亿级流量系统架构设计与实战》 李琛轩