Redis集群(一)
一、简介
- redis是一个开源的key value存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群,我这里用的是redis3.0.0版本;
- redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
- redis集群是没有统一的入口的,客户端(client)连接集群的时候连接集群中的任意节点(node)即可,集群内部的节点是相互通信的(PING-PONG机制),每个节点都是一个redis实例;
- 为了实现集群的高可用,即判断节点是否健康(能否正常使用),redis-cluster有这么一个投票容错机制:如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法;
- 那么如何判断集群是否挂了呢? -> 如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法;
- 那么为什么任意一个节点挂了(没有从节点)这个集群就挂了呢? -> 因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果。再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作。
- 综上所述,每个Redis集群理论上最多可以有16384个节点。
二、三种集群模型
1、主从模型
在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。
当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。
为了在主节点子集发生故障或无法与大多数节点通信时保持可用,Redis Cluster使用主从模型,其中每个哈希槽具有从1(主节点本身)到N个副本(N个) -1个其他从属节点)。在具有节点A,B,C的示例集群中,如果节点B失败,则集群将无法继续,因为我们不再有办法为5501-11000范围内的哈希槽提供服务。
但是,在创建集群(或稍后)时,我们向每个主节点添加一个从属节点,以便最终集群由作为主节点的A,B,C和作为从属节点的A1,B1,C1组成,如果节点B发生故障,系统将能够继续。
节点B1复制B,并且B发生故障,群集会将节点B1提升为新的主节点,并将继续正常运行。
但是请注意,如果节点B和B1同时失败,则Redis Cluster无法继续运行。
解决问题:
解决Redis单例下,数据体量大与数据备份造成的性能瓶颈问题,redis cluster 主从模型很好的解决这个问题。可以将读写操作分离到不同redis实例上,提高系统的吞吐量
引入新的问题:
1、配置重连问题
不同的redis实例,需要不同的ip和端口对应,如果某个实例下线了,需要重新更改配置进行重连
2、故障转移问题
如果某个结点故障下线,无法进行故障转移,比如某个master下线,对应的slave结点也只能进行读操作,无法进行写操作,替代不了master的功能。
特点如下:
- 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
- 从数据库一般都是只读的,并且接收主数据库同步过来的数据
- 一个master可以拥有多个slave,但是一个slave只能对应一个master
- slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
- master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
- master挂了以后,不会在slave节点中重新选一个master
缺点如下:
master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务,不具备高可用性。
2、哨兵模型
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance)。
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会进行选举,将其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
解决问题:
Sentinel哨兵模式,确实实现自动故障切换。提供稳定的服务,解决主从模型引入的新问题。
未解决的问题:
在哨兵模式中,仍然只有一个Master节点。当并发写请求较大时,哨兵模式并不能缓解写压力。
特点如下:
- Sentinel可以监控任意多个Master和该Master下的Slaves。(即多个主从模式)
- 同一个哨兵下的、不同主从模型,彼此之间相互独立。
- Sentinel会不断检查Master和Slaves是否正常。
- 监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监视服务器的信息,在sentinel网络中,只要还有一个sentinel活着,就可以实现故障切换。当只有一个sentinel的时候,如果这个sentinel挂掉了,那么就无法实现自动故障切换了。
- 故障转移:投票(半数原则),当任何一个Sentinel发现被监控的Master下线时,会通知其它的Sentinel开会,投票确定该Master是否下线(半数以上,所以sentinel通常配奇数个)。
- 故障转移:选举,当Sentinel确定Master下线后,会在所有的Slaves中,选举一个新的节点,升级成Master节点。其它Slaves节点,转为该节点的从节点。
- 原Master重新上线,当原Master节点重新上线后,自动转为当前Master节点的从节点。
3、Redis cluster 集群
从Redis 3.0
之后版本支持 Redis Cluster
集群,Redis Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
目标:
- 高达1000个节点的高性能和线性可扩展性。没有代理,使用异步复制,并且不对值执行合并操作。
- 可接受的写安全程度:系统尝试(以尽力而为的方式)保留所有来自与大多数主节点连接的客户端的写操作。通常,有一些小窗口,在这些小窗口中,可能会丢失已确认的写入。当客户端位于少数分区中时,丢失已确认写入的Windows更大。
- 可用性:Redis Cluster能够在大多数主节点可访问且每个不再可用的主节点上至少有一个可访问的从节点的分区中生存。而且,通过使用副本迁移,不再由任何从属复制的主将从一个由多个从属覆盖的主接收一个。
高性能:
- 采用了异步复制机制,向某个节点写入数据时,无需等待其它节点的写数据响应。
- 无中心代理节点,而是将客户端直接重定向到拥有数据的节点。
- 对于N个 Master 节点的 Cluster ,整体性能理论上相当于单个 Redis 的性能的N倍。
高可用:
采用了主从复制的机制,Master 节点失效时 Slave 节点自动提升为 Master 节点。如果 Cluster 中有N个 Master 节点,每个 Master 拥有1个 Slave 节点,那么这个 Cluster 的失效概率为 1/(2*N-1),可用概率为 1-1/(2*N-1)。
高可扩展:
可支持多达1000
个服务节点。随时可以向 Cluster 中添加新节点,或者删除现有节点。Cluster 中每个节点都与其它节点建立了相互连接