参考redis三种模式对比
Redis 是一个开源的 key-value 存储系统,由于出众的性能,大部分互联网企业都用来做服务器端缓存。
1 单实例模式
问题:
(1)内存容量有限。
(2)处理能力有限。
(3)无法高可用。
Redis 在3.0版本前只支持单实例模式,虽然支持主从模式、哨兵模式部署来解决单点故障,但是现在互联网企业动辄大几百G的数据,可完全是没法满足业务的需求,所以,Redis 在 3.0 版本以后就推出了集群模式。
2 集群模式
redis集群有三种方式:主从复制,哨兵,集群(master-cluster)。
Redis 集群采用了P2P的模式,完全去中心化。Redis 把所有的 Key 分成了 16384 个 slot,每个 Redis 实例负责其中一部分 slot 。集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新。
Redis 客户端可以在任意一个 Redis 实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。
2.1 主从复制(Master-Slave)版本2.8之前的模式
数据库分为两类,Master数据库和Slave数据库。
Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。
只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器(master)就会一直将发生在自己身上的数据更新同步给从服务器(slave),从而一直保证主从服务器的数据相同。
同Mysql主从复制的原因一样,Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。为了分担读压力,Redis支持主从复制,Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。
例如:级联结构。
原理:
全量同步
(1)slave连接master发送sync命令。
(2)master持久化数据生成rdb文件并缓存这段时间的写命令。
(3)master向slave发送rdb文件和缓存的命令。
(4)slave载入rdb快照后执行缓存的命令(slave初始化完成)。
增量同步
(5)master每接收到一个写命令就发送给slave执行(slave初始化完成后的操作)。
特点:
解决数据备份问题。
做到读写分离,提高服务器性能。
(1)master/slave 角色。
(2)master/slave 数据相同。
(3)降低 master 读压力,master一般是接受读写的,slave只接受读操作。
(4)一个master下面可以有多个slave,但是一个slave上面只能有一个master。
问题:
(1)无法保证高可用。
每个客户端连接redis实例的时候都是指定了ip和端口号的,如果所连接的redis实例因为故障下线了,而主从模式也没有提供一定的手段通知客户端另外可连接的客户端地址,因而需要手动更改客户端配置重新连接。
(2)没有解决master写的压力。
(3)主从模式下,如果主节点由于故障下线了,那么从节点因为没有主节点而同步中断,因而需要人工进行故障转移工作。
(4)无法实现动态扩容。
2.2 哨兵模式sentinel版本2.8及之后的模式
哨兵是用来监控主从数据库的,当master挂掉后选择一个salve当做master。
Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。
Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。
原理:
与master建立连接后,哨兵会执行三个操作,这三个操作的发送频率都可以在配置文件中配置:
(1)定期向master和slave发送INFO命令。
(2)定期向master和各slave的sentinel:hello频道发送自己的信息。
(3)定期向master、slave和其他哨兵发送PING命令。
master挂掉后从slave中选取规则
(1)所有在线的slave中选择优先级最高的,优先级可以通过slave-priority配置。
(2)如果有多个最高优先级的slave,则选取复制偏移量最大(即复制越完整)的当选。
(3)如果以上条件都一样,选取id最小的slave。
server1掉线后。
升级server2为新的主服务器。
三个特性:
(1)监控(Monitoring):Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
(2)提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
(3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。
特点:
(1)保证高可用
(2)监控各个节点
(3)自动故障迁移
如果Master 异常,则会进行Master-slave 转换,将其中一个Slave作为Master,将之前的Master作为Slave。
Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
缺点:
(1)主从模式,切换需要时间丢数据。
(2)没有解决 master 写的压力。
(3)如果是从节点下线了,sentinel是不会对其进行故障转移的,连接从节点的客户端也无法获取到新的可用从节点。
(4)无法实现动态扩容。
2.3 集群redis-cluster版本redis3.0之后的模式
redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。
使用集群,只需要将每个数据库节点的cluster-enable配置打开即可。
每个集群中至少需要三个主数据库才能正常运行。
从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。
每一个蓝色的圈都代表着一个redis的服务器节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点,对其进行存取和其他操作。
一般集群建议搭建三主三从架构,三主提供服务,三从提供备份功能。
每一个节点都存有这个集群所有主节点以及从节点的信息。
它们之间通过互相的ping-pong判断是否节点可以连接上。
如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,然后去连接它的备用节点。
如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。
如果有一半以上的主节点宕机,那么我们集群同样进入fail状态。
特点:
(1)无中心架构(不存在哪个节点影响性能瓶颈)。
(2)数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
(3)可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
(4)高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本。
(5)实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。
优点:
(1)有效的解决了redis在分布式方面的需求。
(2)遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的。
(3)可实现动态扩容。
(4)P2P模式,无中心化。
(5)通过Gossip协议同步节点信息。
(6)自动故障转移、Slot迁移中数据可用。
缺点:
(1)资源隔离性较差,容易出现相互影响的情况。
(2)数据通过异步复制,不保证数据的强一致性。
(3)架构比较新,最佳实践较少。
(4)为了性能提升,客户端需要缓存路由表信息。
(5)节点发现、reshard操作不够自动化。