Redis 是完全开源免费的,是一个高性能的key-value类型的内存数据库。整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。
Redis有以下四种架构模式:
单机模式
优点:
- 部署简单;
- 成本低,无备用节点;
- 高性能,单机不需要同步数据,数据天然一致性。
缺点:
- 可靠性保证不是很好,单节点有宕机的风险。
- 单机高性能受限于 CPU 的处理能力,Redis 是单线程的。
单机 Redis 能够承载的 QPS(每秒查询速率)大概在几万左右。取决于业务操作的复杂性,Lua 脚本复杂性就极高。假如是简单的 key value 查询那性能就会很高。
假设上千万、上亿用户同时访问 Redis,QPS 达到 10 万+。这些请求过来,单机 Redis 直接就挂了。系统的瓶颈就出现在 Redis 单机问题上,此时我们可以通过主从复制解决该问题,实现系统的高并发。
主从复制
Redis主从复制原理:
①从数据库向主数据库发送sync(数据同步)命令。
②主数据库接收同步命令后,会保存快照,创建一个RDB文件。
③当主数据库执行完保持快照后,会向从数据库发送RDB文件,而从数据库会接收并载入该文件。
④主数据库将缓冲区的所有写命令发给从服务器执行。
⑤以上处理完之后,之后主数据库每执行一个写命令,都会将被执行的写命令发送给从数据库。可以同步发送也可以异步发送,同步发送可以不用每台都同步,可以配置一台master,一台slave,同时这台salve又作为其他slave的master。异步方式无法保证数据的完整性,比如在异步同步过程中主机突然宕机了,也称这种方式为数据弱一致性。
注意:在Redis2.8之后,主从断开重连后会根据断开之前最新的命令偏移量进行增量复制。
优点:
- Master/Slave 角色方便水平扩展,QPS 增加,增加 Slave 即可;
- 降低 Master 读压力,转交给 Slave 节点;
- 主节点宕机,从节点作为主节点的备份可以随时顶上继续提供服务;
缺点:
- 可靠性保证不是很好,主节点故障便无法提供写入服务;
- 没有解决主节点写的压力;
- 数据冗余(为了高并发、高可用和高性能,一般是允许有冗余存在的);
- 一旦主节点宕机,从节点晋升成主节点,需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预;
- 主节点的写能力受到单机的限制;
- 主节点的存储能力受到单机的限制。
哨兵模式
Redis版本:2.8版本及以上
特性:高可用、可扩展性、分布式、容错
哨兵模式工作原理:
当主节点出现故障时,由Redis Sentinel自动完成故障发现和转移,并通知应用方,实现高可用性。哨兵机制建立了多个哨兵节点(进程),共同监控数据节点的运行状况。同时哨兵节点之间也互相通信,交换对主从节点的监控状况。每隔1秒每个哨兵会向整个集群:Master主服务器+Slave从服务器+其他Sentinel(哨兵)进程,发送一次ping命令做一次心跳检测。这个就是哨兵用来判断节点是否正常的重要依据,涉及两个新的概念:主观下线和客观下线。一个哨兵节点判定主节点down掉是主观下线,只有半数哨兵节点都主观判定主节点down掉,此时多个哨兵节点交换主观判定结果,才会判定主节点客观下线。基本上哪个哨兵节点最先判断出这个主节点客观下线,就会在各个哨兵节点中发起投票机制Raft算法(选举算法),最终被投为领导者的哨兵节点完成主从自动化切换的过程。
优点:
- 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都有;
- 主从可以自动切换,系统更健壮,可用性更高;
- Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
缺点:
- 主从切换需要时间,会丢失数据;
- 还是没有解决主节点写的压力;
- 主节点的写能力,存储能力受到单机的限制;
- 动态扩容困难复杂,对于集群,容量达到上限时在线扩容会变得很复杂。
集群模式(主从模式)
redis版本:3.0版本及以上
特性:高可用、可扩展性、分布式、容错
优点:
- (1)无需Sentinel哨兵监控,如果Master挂了,Redis Cluster内部自动将Slave切换Master
- (2)可以进行水平扩容
- (3)支持自动化迁移,当出现某个Slave宕机了,那么就只有Master了,这时候的高可用性就无法很好的保证了,万一Master也宕机了,咋办呢? 针对这种情况,如果说其他Master有多余的Slave ,集群自动把多余的Slave迁移到没有Slave的Master 中。
缺点:
- (1)批量操作是个坑,不同的key会划分到不同的slot中,因此直接使用mset或者mget等操作是行不通的。如果执行的key数量比较少,就不用mget了,就用串行get操作。如果真的需要执行的key很多,就使用Hashtag保证这些key映射到同一台Redis节点上。
- (2)资源隔离性较差,容易出现相互影响的情况。