目录

Redis学习-主从、哨兵、集群

主从

需要注意,主从复制的开启,完全是在从节点发起的;不需要我们在主节点做任何事情。 从节点开启主从复制,有3种方式:

(1)配置文件
在从服务器的配置文件中加入:slaveof <masterip> <masterport>

(2)启动命令
redis-server启动命令后加入 --slaveof <masterip> <masterport>

(3)客户端命令
Redis服务器启动后,直接通过客户端执行命令:slaveof <masterip> <masterport>,则该Redis实例成为从节点。

复制

psync命令的执行会执行全量/增量的复制。

主从复制原理

当从数据库启动时,会向主数据库发送sync命令,主数据库接收到sync后开始在后台保存快照rdb,在保存快照期间受到的命令缓存起来,当快照完成时,主数据库会将快照和缓存的命令一块发送给从。复制初始化结束。 之后,主每受到1个命令就同步发送给从。 当出现断开重连后,2.8之后的版本会将断线期间的命令传给重数据库。增量复制

主从复制是乐观复制,当客户端发送写执行给主,主执行完立即将结果返回客户端,并异步的把命令发送给从,从而不影响性能。也可以设置至少同步给多少个从主才可写。

哨兵

当主数据库遇到异常中断服务后,开发者可以通过手动的方式选择一个从数据库来升格为主数据库,以使得系统能够继续提供服务。然而整个过程相对麻烦且需要人工介入,难以实现自动化。 为此,Redis 2.8中提供了哨兵工具来实现自动化的系统监控和故障恢复功能。

哨兵的作用就是监控redis主、从数据库是否正常运行,主出现故障自动将从数据库转换为主数据库。

哨兵节点本质还是一个redis实例,与主从节点不同的是sentinel节点作用是用于监控redis数据节点的,可以有多个哨兵节点。 ./pic1.png 上图就是一主二从多个哨兵。

哨兵原理

哨兵节点之间相互发消息,来检测其余哨兵是否正常工作。 哨兵也会向主从节点发送消息来检测主从节点是否在正常工作。如果主节点发送故障,那么某一个哨兵向它发送数据后就收不到回复,该哨兵会再向其他哨兵发消息来询问是否也认为该主节点异常,如果有一半的哨兵认为主节点异常,那么就进行主从节点的故障转移。

故障转移的基本思路是在从节点中选取某个从节点向其发送slaveof no one(假设选取的从节点为127.0.0.1:6380),使其称为独立的节点(也就是新的主节点),然后sentinel向其余的从节点发送slaveof 127.0.0.1 6380命令使它们重新成为新的主节点的从节点。重新分配之后sentinel节点集合还会继续监控已经下线的主节点(假设为127.0.0.1:6379),如果其重新上线,那么sentinel会向其发送slaveof命令,使其成为新的主机点的从节点,如此故障转移工作完成。

哨兵配置

在redis安装目录下有个默认的sentinel配置文件sentinel.conf。

  • 每个sentinel的myid参数也要进行修改,因为sentinel之间是通过该属性来唯一区分其他sentinel节点的。
  • 参数中sentinel monitor mymaster 127.0.0.1 6379 2,因为sentinel是通过检测主节点的状态来得知当前主节点的从节点有哪些的,因而设置为主节点的端口号即可

配置完成后我们首先启动三个主从节点,然后分别使用三个配置文件使用如下命令启用sentinel:

./src/redis-sentinel sentinel-26379.conf 哨兵节点本身也是redis实例,我们可以连接上,并查看主从节点的状态。

集群

主从模式可以解决读写分离,哨兵可以保证主从问题的容错切换,但是他们还是在单机,主从节点都要保存所有的数据。

当单机内存、并发和流量瓶颈的时候,需要使用集群方法来解决。 集群可以多个节点,每个节点可以有一个master,当master异常时,它的从节点切换。如果从节点也失败了,那么集群也就失败了。

Keys分布模型

redis集群中数据是和槽(slot)挂钩的,其总共定义了16384个槽,所有的数据根据一致哈希算法会被映射到这16384个槽中的某个槽中;另一方面,这16384个槽是按照设置被分配到不同的redis节点上的,比如启动了三个redis实例:cluster-A,cluster-B和cluster-C,这里将0-5460号槽分配给cluster-A,将5461-10922号槽分配给cluster-B,将10923-16383号槽分配给cluster-C。

redis集群投票机制

redis集群中有多台redis服务器不可避免会有服务器挂掉。redis集群服务器之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了。

其他

在redis的官方文档中,对redis-cluster架构上,有这样的说明:在cluster架构下,默认的,一般redis-master用于接收读写,而redis-slave则用于备份,当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可通过readonly命令,将slave设置成可读,然后通过slave获取相关的key,达到读写分离。

redigo库本身不支持redis哨兵和集群,redis-go-cluster库在此基础上在本地缓存了slot,并自动更新,为每一个节点管理连接池。 go-sentinel库也是支持redigo库来实现哨兵模式