https://blog.csdn.net/miss1181248983/article/details/90056960
主从复制
复制(replication),可以让其他服务器拥有一个不断更新的数据副本,从而使得拥有数据副本的服务器可以处理客户端发送的读请求。关系数据库通常会使用一个主服务器(master)向多个从服务器(slaver)发送更新,并使用从服务器来处理所有的读请求(读写分离),从而实现高可用、高并发。Redis也采用了同样的方法来实现自己的复制特性,并将其作为扩展性能的一种手段。
Redis主从复制的特点是一般包含一个主,一个或多个从,从节点从主节点复制数据,可以实现读写分离,主节点做写,从节点做读。
实现方式:开启从服务器的选项只有一个:slaveof,如果在启动Redis服务器的时候指定了一个包含slaveof host port
选项的配置文件,那么Redis服务器就会根据指定的IP地址和端口号来连接主服务器。
- slave no one命令让服务器终止复制操作,不再接受主服务器的数据更新
- slaveof host port命令来让服务器开始复制一个新的主服务器。
- 从服务器在进行同步时,会清空自己的所有数据,并被替换成主服务器发来的数据;
- Redis不支持主主复制;
- 从服务器也可以有自己的从服务器,并由此形成主从链
实现原理:
- 从服务器向主服务器发送SYNC命令
- 主服务器收到SYNC命令后,执行BGSAVE命令,在后台生成RDB文件,使用缓冲区记录从现在开始执行的所有的写命令。
- 当主服务器的BGSAVE命令执行完毕后,主服务器后将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
- 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。
主从复制的优缺点:
- 优点:可以实现读写分离,主节点的数据会自动复制到从节点,分担主节点的压力。
- 缺点:当主节点master出现故障后,服务就不可用了,需要手动将slaver修改为master。要实现自动,就需要Redis哨兵模式。
哨兵模式(sentinel)
哨兵模式的高可用原理:哨兵发送命令,等待Master主节点响应,从而监控主节点的运行,当主节点出现故障时,由Redis哨兵自动完成故障发现和转移,并通知Redis客户端,实现高可用性。
Redis哨兵进程:用于监控Redis集群中Master主服务器状态。在Master主节点发生故障时,可以实现Master和Slave服务器的自动切换,保证系统的高可用性。每个哨兵进程会向其他Redis哨兵、Master主节点、Slave从节点定时发送信息,以确定被“监控”的节点是否还“活着”。如果发现对方在指定时间内未得到回应,那么暂时认为被监控节点已死机,即所谓的“客观下线”。
Redis哨兵的启动:可以由一个单独的可执行文件redis-sentinel
控制启动,也可以在Redis服务器启动时指定sentinel选项来启动Redis哨兵。
Redis哨兵模式工作原理
- 每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否“活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown)。
- 若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。
- 虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。
哨兵(sentinel) 的一些设计思路和zookeeper
非常类似。
哨兵模式的优缺点
- 优点:哨兵模式可以算主从模式的升级吧,读写分离都有,而且哨兵还有监控的功能,当主节点宕机之后哨兵会推选一个健康的从节点做主节点,这样提高了软件的可用性。
- 缺点:主从模式的缺点都有,而且配置哨兵啥的比较麻烦,而且在重新选举主节点期间,无法确定主从,无法工作。
Cluster集群
Redis的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台redis服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了Cluster模式,实现的redis的分布式存储,也就是说每台redis节点上存储不同的内容。
Cluster集群采用了多主多从,按照一定的规则进行分片,将数据分别存储,一定程度上解决了哨兵模式下单机存储有限的问题。
Cluster集群通过以下手段实现高可用、高性能:
- 数据分片:将数据切分到多个Redis节点,每个Redis集群中包含16384个哈希槽(hash slot),Redis中存储的每个key都属于这些哈希槽中的一个。可通过计算得知每个key应该存放的具体哈希槽:
key存放的哈希槽 = CRC(key) %16384
,CRC(16)是计算key的CRC16检验和的。 - 支持动态迁移数据:当集群中部分节点失效或者无法进行通信时,整个集群仍然可以处理请求:Redis集群中的每个Redis节点负责处理一部分哈希槽,哈希槽分布在不同的Redis节点,向集群中添加或者删除Redis节点时只需将部分哈希槽移动到插入的Redis结点或将删除的Redis结点的数据均分到其他Redis结点即可。如向Redis集群中加入节点D,只需将节点A、B、C中的部分哈希槽移动到节点D即可。
Redis Cluster集群容错:判断当前结点是否下线需要集群中所有的Redis Master节点参与。如果集群中半数以上的Master节点与当前节点通信超时,则认为当前节点下线。
整个集群不可用的情况:
- 某个Master节点下线,并且这个Master节点没有可用的Slave节点;
- 集群中超过半数以上的Master节点下线,无论Master节点是否有Slave节点。
Redis集群中的一致性问题:在谈Redis集群一致性问题前,先了解CAP定理。CAP定理指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)三者不可兼得,只能同时满足其中的两个。
Redis集群作为一个分布式系统,也存在相应的问题,Redis对可用性和分区容错性有较好的支持(AP)。因此Redis集群模式下数据一致性存在一定的问题,即Redis集群不保证强一致性。
在Redis集群中,主从节点之间的复制是异步执行的,即主节点对命令的复制工作发生在返回命令回复给客户端之后,如果每次处理命令请求都需要等待复制操作完成,那么主节点处理命令请求的速度将极大地降低——必须在性能和一致性之间做出权衡。这种情况下会存在数据一致性问题,即集群中部分节点短时间内获取不到最新的主节点新增的数据。