1. 首页 > 笙耀百科 >

redis 哨兵配置 redis哨兵配置必须一样吗

美团二面:为什么Redis会有哨兵?

话不多说,发车发车!

redis 哨兵配置 redis哨兵配置必须一样吗redis 哨兵配置 redis哨兵配置必须一样吗


redis 哨兵配置 redis哨兵配置必须一样吗


在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点()挂了,那么将没有主节点来服务客户端的写作请求,也没有主节点给从节点(sle)进行数据同步了。

这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。

这样也不太“智能”了,要是有一个节点能「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切换为「主节点」的话,那么可以节省我们很多事情啊!

Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制 ,它的作用是实现 主从节点故障转移 。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

当然,它不仅仅是观察那么简单,在它观察到有异常的状况下,会做出一些“动作”,来修复异常状态。

哨兵节点主要负责三件事情: 、选主、通知 。

所以,我们重点要学习这三件事情:

哨兵主从节点

如果主节点或者从节点没有在规定的时间内响应哨兵的 PING 命令,哨兵就会将它们标记为「 主观下线 」。这个「规定的时间」是配置项 down-after-milliseconds 参数设定的,单位是毫秒。

是这主要 通过 Redis 的发布者/者机制来实现 的。每个哨兵节点提供发布者/者机制,客户端可以从哨兵消息。的没错,客观下线只适用于主节点。

之所以针对「主节点」设计「主观下线」和「客观下线」两个状态,是因为有可能「主节点」其实并没有故障,可能只是因为主节点的系统压力比较大或者网络发送了拥塞,导致主节点没有在规定时间内响应哨兵的 PING 命令。

所以,为了减少误判的情况,哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成 哨兵集群 ( 最少需要三台机器来部署哨兵集群 ), 通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况通过这个方式,哨兵 B 和 C 也可以建立网络连接,这样一来,哨兵集群就形成了。不好,而误判主节点下线的情况 。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。

具体是怎么判定主节点为「客观下线」的呢?

当一个哨兵判断主节点为「主观下线」后,就会向其他哨兵发起命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出投票或者拒绝投票的响应。

当这个哨兵的赞同票数达到哨兵配置文件中的 quorum 配置项设定的值后,这时主节点就会被该哨兵标记为「客观下线」。

例如,现在有 3 个哨兵,quorum 配置的是 2,那么一个哨兵需要 2 张票,就可以标记主节点为“客观下线”了。这 2 张票包括哨兵自己的一张票和另外两个哨兵的票。

PS:quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。

哨兵判断完主节点客观下线后,哨兵就要开始在多个「从节点」中,选出一个从节点来做新主节点。

那么多「从节点」,到底选择哪个从节点作为新主节点的?

随机的方式好吗?随机的方式,实现起来很简单,但是如果选到一个网络状态不好的从节点作为新主节点,那么可能在将来不久又要主从故障迁移。

所以,我们首先要把网络状态不好的从节点给过滤掉。首先把已经下线的从节点过滤掉,然后把以往网络连接状态不好的从节点也给过滤掉。

怎么判断从节点之前的网络连接状态不好呢?

Redis 有个叫 down-after-milliseconds 10 配置项,其down-after-milliseconds 是主从节点断连的连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从节点的网络状况不好,不适合作为新主节点。

至此,我们就把网络状态不好的从节点过滤掉了,接下来要对所有从节点进行三轮考察: 优先级、进度、ID 号 。在进行每一轮考察的时候,哪个从节点优先胜出,就选择其作为新主节点。

Redis 有个叫 sle-priority 配置项,可以给从节点设置优先级。

每一台从节点的配置不一定是相同的,我们可以根据性能配置来设置从节点的优先级。

比如,如果 「 A 从节点」的物理内存是所有从节点中的, 那么我们可以把「 A 从节点」的优先级设置成。这样当哨兵进行轮考虑的时候,优先级的 A 从节点就会优先胜出,于是就会成为新主节点。

如果在轮考察中,发现优先级的从节点有两个,那么就会进行第二轮考察,比较两个从节点哪个进度。

什么是进度?主从架构中,主节点会将写作同步给从节点,在这个过程中,主节点会用 _repl_offset 记录当前的写作在 repl_backlog_buffer 中的位置,而从节点会用 sle_repl_offset 这个值记录当前的进度。

如果某个从节点的 sle_repl_offset 最接近 _repl_offset,说明它的进度是最靠前的,于是就可以将它选为新主节点。

什么是 ID 号?每个从节点都有一个编号,这个编号就是 ID 号,是用来标识从节点的。

到这里,选主的事情终于结束了。简单给大家总结下:

前面说过,为了更加“客观”的判断主节点故障了,一般不会只由单个哨兵的检测结果来判断,而是多个哨兵一起判断,这样可以减少误判概率,所以哨兵是以哨兵集群的方式存在的。

所以这时候,还需要在哨兵集群中选出一个 leeder,让 Leader 来执行主从切换。

选举 leeder 的过程其实是一个投票的过程,在投票开始前,肯定得有个「候选者」。

哪个哨兵节点判断主节点为「客观下线」,这个哨兵节点就是候选者,所谓的候选者就是想当 Leader 的哨兵。

举个例子,假设有三个哨兵。当哨兵 A 先判断到主节点「主观下线后」,就会给其他实例发送 is--down-by-addr 命令。接着,其他哨兵会根据自己和主节点的网络连接情况,做出投票或者拒绝投票的响应。

当哨兵 A 收到票数达到哨兵配置文件中的 quorum 配置项设定的值后,就会将主节点标记为「客观下线」,此时的哨兵 A 就是一个Leader 候选者。

候选者会向其他哨兵发送命令,表明希望成为 Leader 来执行主从切换,并让所有其他哨兵对它进行投票。

每个哨兵只有一次投票机会,如果用完后就不能参与投票了,可以投给自己或投给别人,但是只有候选者才能把票投给自己。

那么在投票过程中,任何一个「候选者」,要满足两个条件:

举个例子,假设哨兵节点有 3 个,quorum 设置为 2,那么任何一个想成为 Leader 的哨兵只要拿到 2 张票,就可以选举成功了。如果没有满足条件,就需要重新进行选举。

这时候有的同学就会问了,如果某个时间点,刚好有两个哨兵节点判断到主节点为客观下线,那这时不就有两个候选者了?这时该如何决定谁是 Leader 呢?

每位候选者都会先给自己投一票,然后向其他哨兵发起投票请求。如果投票者先收到「候选者 A」的投票请求,就会先投票给它,如果投票者用完投票机会后,收到「候选者 B」的投票请求后,就会拒绝投票。这时,候选者 A 先满足了上面的那两个条件,所以「候选者 A」就会被选举为 Leader。

如果哨兵集群中只有 2 个哨兵节点,此时如果一个哨兵想要成功成为 Leader,必须获得 2 票,而不是 1 票。

所以,如果哨兵集群中有个哨兵挂掉了,那么就只剩一个哨兵了,如果这个哨兵想要成为 Leader,这时票数就没办法达到 2 票,就无法成功成为 Leader,这时是无法进行主从节点切换的。

因此,通常我们至少会配置 3 个哨兵节点。这时,如果哨兵集群中有个哨兵挂掉了,那么还剩下两个个哨兵,如果这个哨兵想要成为 Leader,这时还是有机会达到 2 票的,所以还是可以选举成功的,不会导致无法进行主从节点切换。

当然,你要问,如果 3 个哨兵节点,挂了 2 个怎么办?这个时候得人哨兵其实是一个运行在特殊模式下的 Redis 进程,所以它也是一个节点。从“哨兵”这个名字也可以看得出来,它相当于是“观察者节点”,观察的对象是主从节点。为介入了,或者增加多一点哨兵节点。

再说一个问题,Redis 1 主 4 从,5 个哨兵 ,quorum 设置为 3,如果 2 个哨兵故障,当主节点宕机时,哨兵能否判断主节点“客观下线”?能否自动切换?

如果 quorum 设置为 2 的话,并且有 3 个哨兵故障。此时哨兵集群还是可以判定主节点为“客观下线”,但是哨兵不能完成主从切换了,大家可以自己推演下。

经过前面一系列的作后,哨兵集群终于完成了主从故障迁移,那么新主节点的信息要如何通知给客户端呢?

比如,客户端了主从切换的,当哨兵把新主节点选择出来后,就会发布新主节点的 IP 地址和端口信息,这个时候客户端就可以收到这条信息,然后用这里面的新主节点的 IP 地址和端口进行通信了。

前面提到了 Redis 的发布者/者机制,那就不得不提一下哨兵集群的组成方式,因为它也用到了这个技术。

不需要填其他哨兵节点的信息,我就好奇它们是如何感知对方的,又是如何组成哨兵集群的?

后面才了解到, 哨兵节点之间是通过 Redis 的发布者/者机制来相互发现的 。

在主从集群中,主节点上有一个名为 sentinel :hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。

在下图中,哨兵 A 把自己的 IP 地址和端口的信息发布到 sentinel :hello 频道上,哨兵 B 和 C 了该频道。那么此时,哨兵 B 和 C 就可以从这个频道直接获取哨兵 A 的 IP 地址和端口号。然后,哨兵 B、C 可以和哨兵 A 建立网络连接。

主节点知道所有「从节点」的信息,所以哨兵会向主节点发送 INFO 命令来获取所有「从节点」的信息。

如下图所示,哨兵 B 给主节点发送 INFO 命令,主节点接受到这个命令后,就会把从节点列表返回给哨兵。接着,哨兵就可以根据从节点列表中的连接信息,和每个从节点建立连接,并在这个连接上持续地对从节点进行。哨兵 A 和 C 可以通过相同的方法和从节点建立连接。

正式通过 Redis 的发布者/者机制,哨兵之间可以相互感知,然后组成集群,同时,哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行了。

参考资料:

Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制 ,它的作用是实现 主从故障自动转移 。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

哨兵一般是以集群的方式部署,至少需要 3 个哨兵节点,哨兵集群主要负责三件事情: 、选主、通知 。

哨兵节点通过 Redis 的发布者/者机制,哨兵之间可以相互感知,相互连接,然后组成哨兵集群,同时哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行了。

选举完 leader 哨兵节点后,就执行主从切换。完成主从切换后,通过 Redis 的发布者/者机制通知客户端新主节点的 IP 地址和端口。

如果觉得本文对你有帮助,可以转发关注支持一下~

连接redis时是连接的哨兵还是

当我们写入或者读取大量bigKey的时候,很有可能导致输入/输出缓冲区溢出。如果客户端占用的内存总量超过了设置的maxmemory时(默认4GB),将会直接触发的内存淘汰策略,如果有数据被淘汰,再要获取这些数据就需要到后端回源,间接降低了缓存系统的性能。同时,淘汰的如果是bigKey也同样会阻塞主线程。另外,在极端情况下,多个客户端占用了过多的内存将导致OOM,进而使得整个redis进程崩溃。

哨兵模式下,客户端一般会保持两种连接,与哨兵的连接,以及的连接。数据作当然使用连接,如果出故障了,可以通过与哨兵的连接来获取的地址。

Sentinel(哨兵)进程的作用

通过ip和port连接。

另外,有一些公司自己封装了redibigKey给tair带来的危害是多方面的,性能下降只是其中的一方面,极端情况下,bigKey甚至会导致缓存服务崩溃。下面我将从几个角度进行分析。s客户端,可以通过哨兵获得及其sles,采用读写分离,读sles,写。

浅析Redis的BigKey(阿里巴巴技术协会ATA同步发送)

bigKey一旦产生,将会对tair的性能以及稳定性造成较大的影响,下面我将详细介绍一下bigKey的危害。

在完成接入的需求时,我们需要记录上一个批次拉取的,并与当前拉取到的做出比对,从而进行分。我们目前的做法是使用redis来进行缓存:将上一个批次拉取到的缓存到一个list中。但是当数量过多时,value的大小会超过1M的限制,直接抛出异常。这其实是Tair出于性能的考虑而做出的限制,本文将谈谈我个人对于bigKey的理解。

顾名思义,bigKey指一个key对应的value占据的内存空间相对比较大,bigKe更多Redis相关技术文章,请访问Redis教程栏目进行学习!y通常会有两种表现形式:

我们可以看到:

另外,在Redis执行异步重写作时(bgrewriteaof),主线程会fork出一个子进程来执行重写命令,这个子进程会与主线程共享内存。当主线程收到了新增或者修改一个key的命令,主线程会申请一块额外的内存空间来保存数据。但如果这个key是一个bigKey时,主线程会去申请一块更大空间,同样会阻塞主线程(与JVM分配内存一样,涉及锁和同步)。如果申请不到足够的空间,会导致Swap甚至会有OOM的风险,这同样会降低Redis的性能和稳定性。

Tair中一个key为1M,我们就以1M举例,当访问这个key的QPS为1000时,每秒将会有1GB左右的流量,对于带宽来说将是一个较大压力。如果这个bigKey是一个热点key时,后果将不堪设想。

如果主从同步的 client-output-buffer-limit 设置过小,并且 存在大量bigKey(数据量很大),主从全量同步时可能会导致 buffer 溢出,溢出后主从全量同步就会失败。如果主从集群配置了哨兵,那么哨兵会让 sle 继续向 发起全量同步请求,然后 buffer 又溢出同步失败,如此反复,会形成风暴,这会浪费 大量的 CPU、内存、带宽资源,也会让 产生阻塞的风险。 另外,当我们使用Redis Cluster时,由于Redis Cluster采用了同步迁移的方式,bigKey同样会阻塞主线程。这里提一下Codis,Codis在迁移bigKey时,使用了异步迁移 + 指令拆分的方式,对于bigKey (类型) 中每个元素,用一条指令进行迁移,而不是把整个 bigKey 进行序列化后再整体传输。这种化整为零的方式,就避免了 bigKey 迁移时,因为要序列化大量数据而阻塞的问题。

常用的做法是通过./redis-cli --bigkeys命令对整个redis中的键值对进行统计,输出每种数据类型中的 bigkey 的信息。一般会配合-i参数一起使用,控制扫描间隔,避免长时间扫描降低 Redis 实例的性能。另外该命令不要在业务高峰期使用。

或者我们可以通过debug object key 命令去查看serializedlength属性,serializedlength表示key对应的value序列化后的字节数,通过观察serializedlength的大小可以辅助排查bigKey。使用scan + debug object key命令,我们可以计算其中每个key的serializedlength,进而发现其中的bigKey,并做好相应的和处理。不过对于类型的bigKey,debug object key 命令的执行效率不高,存在阻塞redis的风险。

另外,在读取bigKey的时候,我们尽量不要一次性将全部数据读取出来,而是采用分批的方式进行读取:利用scan命令进行渐进式遍历,将大量数据分批多次读取出来,减小redis的压力,避免阻塞的风险。

同样的,在删除bigKey的时候我使用切片集群的时候,我们通常会将不同的key存放在不同的实例上,如果存在bigKey的话,会导致相应实例的数据量增大,内存压力也相应增大。们也可以使用scan命令来进行批量删除。如果你是用的redis是4.0之后的版本,则可以利用unlink命令配合lazy free配置(需要手动开启)来进行异步删除,避免主线程阻塞。

redis哨兵和集群区别是什么?

如果设置了密码,就要设置:auth -password

redis哨兵和集群区别是:

主数据库和从数据库是否正常运行。

主数据库出现故障时自动将从数据库转换为主数据库。sentinel发现挂了后,就会从sle中重新选举一个。哨兵模式强调高可用。

Sentinel会不断地检查你的主和从是否运作正常。

提醒(Notification):当被的某个Re如果Master和Sle之间的链接出现断连现象,Sle可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。dis出现问题时,Sentinel可以通过API向或者其他应用程序发送通知。

自动故障迁移(Automatic failover):当一个主不能正常工作时,Sentinel会开始一次自动故障迁移作。

它会将失效主的其中一个从升级为新的主,并让失效主的其他从改为新的主。

当客户端试图连接失效的主时,集群也会向客户端返回新主的地址,使得集群可以使用新主代替失效。

客户端中不会记录redis的地址(某个IP),而是记录sentinel的地址,这样我们可以直接从sentinel获取的redis地址。

因为sentinel会对所有的、sle进行,它是知道到底谁才是真正的的,例如我们故障转移,这时候对于sentinel来说,是变了的,然后通知客户端。

而客户端根本不用关心到底谁才是真正的,只关心sentinel告知的。

集群即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。

为了化利用内存,可以采用集群,就是分布式存储。即每台redis存储不同的内容,共有16384个slot。

每个redis分得一些slot,hash_slot = crc16(key) mod 16384找到对应slot,键是可用键,如果有{}则取{}内的作为可用键,否则整个键是可用键。

集群模式提高并发量。

Redis:Remote Dictionary ,即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于总结:没有的方案,只有最合适的方案。内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

美团二面:为什么Redis会有哨兵?

话不多说,发车发车!

在 Redis 的主从架构中,由于主从模式是读写分离的,如果主节点()挂了,那么将没有主节点来服务客户端的写作请求,也没有主节点给从节点(sle)进行数据同步了。

这时如果要恢复服务的话,需要人工介入,选择一个「从节点」切换为「主节点」,然后让其他从节点指向新的主节点,同时还需要通知上游那些连接 Redis 主节点的客户端,将其配置中的主节点 IP 地址更新为「新主节点」的 IP 地址。

这样也不太“智能”了,要是有一个节点能「主节点」的状态,当发现主节点挂了 ,它自动将一个「从节点」切换为「主节点」的话,那么可以节省我们很多事情啊!

Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制 ,它的作用是实现 主从节点故障转移 。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

当然,它不仅仅是观察那么简单,在它观察到有异常的状况下,会做出一些“动作”,来修复异常状态。

哨兵节点主要负责三件事情: 、选主、通知 。

所以,我们重点要学习这三件事情:

哨兵主从节点

如果主节点或者从节点没有在规定的时间内响应哨兵的 PING 命令,哨兵就会将它们标记为「 主观下线 」。这个「规定的时间」是配置项 down-after-milliseconds 参数设定的,单位是毫秒。

是的没错,客观下线只适用于主节点。

之所以针对「主节点」设计「主观下线」和「客观下线」两个状态,是因为有可能「主节点」其实并没有故障,可能只是因为主节点的系统压力比较大或者网络发送了拥塞,导致主节点没有在规定时间内响应哨兵的 PING 命令。

所以,为了减少误判的情况,哨兵在部署的时候不会只部署一个节点,而是用多个节点部署成 哨兵集群 ( 最少需要三台机器来部署哨兵集群 ), 通过多个哨兵节点一起判断,就可以就可以避免单个哨兵因为自身网络状况不好,而误判主节点下线的情况 。同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。

具体是怎么判定主节点为「客观下线」的呢?

当一个哨兵判断主节点为「主观下线」后,就会向其他哨兵发起命令,其他哨兵收到这个命令后,就会根据自身和主节点的网络状况,做出投票或者拒绝投票的响应。

当这个哨兵的赞同票数达到哨兵配置文件中的 quorum 配置项设定的值后,这时主节点就会被该哨兵标记为「客观下线」。

例如,现在有 3 个哨兵,quorum 配置的是 2,那在我次搭建哨兵集群的时候,当时觉得很诧异。因为在配置哨兵的信息时,竟然只需要填下面这几个参数,设置主节点名字、主节点的 IP 地址和端口号以及 quorum 值。么一个哨兵需要 2 张票,就可以标记主节点为“客观下线”了。这 2 张票包括哨兵自己的一张票和另外两个哨兵的票。

PS:quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。

哨兵判断完主节点客观下线后,哨兵就要开始在多个「从节点」中,选出一个从节点来做新主节点。

那么多「从节点」,到底选择哪个从节点作为新主节点的?

随机的方式好吗?随机的方式,实现起来很简单,但是如果选到一个网络状态不好的从节点作为新主节点,那么可能在将来不久又要主从故障迁移。

所以,我们首先要把网络状态不好的从节点给过滤掉。首先把已经下线的从节点过滤掉,然后把以往网络连接状态不好的从节点也给过滤掉。

怎么判断从节点之前的网络连接状态哨兵的职责不好呢?

Redis 有个叫 down-after-milliseconds 10 配置项,其down-after-milliseconds 是主从节点断连的连接超时时间。如果在 down-after-milliseconds 毫秒内,主从节点都没有通过网络联系上,我们就可以认为主从节点断连了。如果发生断连的次数超过了 10 次,就说明这个从节点的网络状况不好,不适合作为新主节点。

至此,我们就把网络状态不好的从节点过滤掉了,接下来要对所有从节点进行三轮考察: 优先级、进度、ID 号 。在进行每一轮考察的时候,哪个从节点优先胜出,就选择其作为新主节点。

Redis 有个叫 sle-priority 配置项,可以给从节点设置优先级。

每一台从节点的配置不一定是相同的,我们可以根据性能配置来设置从节点的优先级。

比如,如果 「 A 从节点」的物理内存是所有从节点中的, 那么我们可以把「 A 从节点」的优先级设置成。这样当哨兵进行轮考虑的时候,优先级的 A 从节点就会优先胜出,于是就会成为新主节点。

如果在轮考察中,发现优先级的从节点有两个,那么就会进行第二轮考察,比较两个从节点哪个进度。

什么是进度?主从架构中,主节点会将写作同步给从节点,在这个过程中,主节点会用 _repl_offset 记录当前的写作在 repl_backlog_buffer 中的位置,而从节点会用 sle_repl_offset 这个值记录当前的进度。

如果某个从节点的 sle_repl_offset 最接近 _repl_offset,说明它的进度是最靠前的,于是就可以将它选为新主节点。

什么是 ID 号?每个从节点都有一个编号,这个编号就是 IDcodis是一个分布式的Redis解决方案,由豌豆荚开源,对于上层的应用来说,连接codis proxy和连接原生的redis server没什么明显的区别,上层应用可以像使用单机的redis一样使用,codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的redis服务。 号,是用来标识从节点的。

到这里,选主的事情终于结束了。简单给大家总结下:

前面说过,为了更加“客观”的判断主节点故障了,一般不会只由单个哨兵的检测结果来判断,而是多个哨兵一起判断,这样可以减少误判概率,所以哨兵是以哨兵集群的方式存在的。

所以这时候,还需要在哨兵集群中选出一个 leeder,让 Leader 来执行主从切换。

选举 leeder 的过程其实是一个投票的过程,在投票开始前,肯定得有个「候选者」。

哪个哨兵节点判断主节点为「客观下线」,这个哨兵节点就是候选者,所谓的候选者就是想当 Leader 的哨兵。

举个例子,假设有三个哨兵。当哨兵 A 先判断到主节点「主观下线后」,就会给其他实例发送 is--down-by-addr 命令。接着,其他哨兵会根据自己和主节点的网络连接情况,做出投票或者拒绝投票的响应。

当哨兵 A 收到票数达到哨兵配置文件中的 quorum 配置项设定的值后,就会将主节点标记为「客观下线」,此时的哨兵 A 就是一个Leader 候选者。

候选者会向其他哨兵发送命令,表明希望成为 Leader 来执行主从切换,并让所有其他哨兵对它进行投票。

每个哨兵只有一次投票机会,如果用完后就不能参与投票了,可以投给自己或投给别人,但是只有候选者才能把票投给自己。

那么在投票过程中,任何一个「候选者」,要满足两个条件:

举个例子,假设哨兵节点有 3 个,quorum 设置为 2,那么任何一个想成为 Leader 的哨兵只要拿到 2 张票,就可以选举成功了。如果没有满足条件,就需要重新进行选举。

这时候有的同学就会问了,如果某个时间点,刚好有两个哨兵节点判断到主节点为客观下线,那这时不就有两个候选者了?这时该如何决定谁是 Leader 呢?

每位候选者都会先给自己投一票,然后向其他哨兵发起投票请求。如果投票者先收到「候选者 A」的投票请求,就会先投票给它,如果投票者用完投票机会后,收到「候选者 B」的投票请求后,就会拒绝投票。这时,候选者 A 先满足了上面的那两个条件,所以「候选者 A」就会被选举为 Leader。

如果哨兵集群中只有 2 个哨兵节点,此时如果一个哨兵想要成功成为 Leader,必须获得 2 票,而不是 1 票。

所以,如果哨兵集群中有个哨兵挂掉了,那么就只剩一个哨兵了,如果这个哨兵想要成为 Leader,这时票数就没办法达到 2 票,就无法成功成为 Leader,这时是无法进行主从节点切换的。

因此,通常我们至少会配置 3 个哨兵节点。这时,如果哨兵集群中有个哨兵挂掉了,那么还剩下两个个哨兵,如果这个哨兵想要成为 Leader,这时还是有机会达到 2 票的,所以还是可以选举成功的,不会导致无法进行主从节点切换。

当然,你要问,如果 3 个哨兵节点,挂了 2 个怎么办?这个时候得人为介入了,或者增加多一点哨兵节点。

再说一个问题,Redis 1 主 4 从,5 个哨兵 ,quorum 设置为 3,如果 2 个哨兵故障,当主节点宕机时,哨兵能否判断主节点“客观下线”?能否自动切换?

如果 quorum 设置为 2 的话,并且有 3 个哨兵故障。此时哨兵集群还是可以判定主节点为“客观下线”,但是哨兵不能完成主从切换了,大家可以自己推演下。

经过前面一系列的作后,哨兵集群终于完成了主从故障迁移,那么新主节点的信息要如何通知给客户端呢?

比如,客户端了主从切换的,当哨兵把新主节点选择出来后,就会发布新主节点的 IP 地址和端口信息,这个时候客户端就可以收到这条信息,然后用这里面的新主节点的 IP 地址和端口进行通信了。

前面提到了 Redis 的发布者/者机制,那就不得不提一下哨兵集群的组成方式,因为它也用到了这个技术。

不需要填其他哨兵节点的信息,我就好奇它们是如何感知对方的,又是如何组成哨兵集群的?

后面才了解到, 哨兵节点之间是通过 Redis 的发布者/者机制来相互发现的 。

在主从集群中,主节点上有一个名为 sentinel :hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的。

在下图中,哨兵 A 把自己的 IP 地址和端口的信息发布到 sentinel :hello 频道上,哨兵 B 和 C 了该频道。那么此时,哨兵 B 和 C 就可以从这个频道直接获取哨兵 A 的 IP 地址和端口号。然后,哨兵 B、C 可以和哨兵 A 建立网络连接。

主节点知道所有「从节点」的信息,所以哨兵会向主节点发送 INFO 命令来获取所有「从节点」的信息。

如下图所示,哨兵 B 给主节点发送 INFO 命令,主节点接受到这个命令后,就会把从节点列表返回给哨兵。接着,哨兵就可以根据从节点列表中的连接信息,和每个从节点建立连接,并在这个连接上持续地对从节点进行。哨兵 A 和 C 可以通过相同的方法和从节点建立连接。

正式通过 Redis 的发布者/者机制,哨兵之间可以相互感知,然后组成集群,同时,哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行了。

参考资料:

Redis 在 2.8 版本以后提供的 哨兵(Sentinel)机制 ,它的作用是实现 主从故障自动转移 。它会监测主节点是否存活,如果发现主节点挂了,它就会选举一个从节点切换为主节点,并且把新主节点的相关信息通知给从节点和客户端。

哨兵一般是以集群的方式部署,至少需要 3 个哨兵节点,哨兵集群主要负责三件事情: 、选主、通知 。

哨兵节点通过 Redis 的发布者/者机制,哨兵之间可以相互感知,相互连接,然后组成哨兵集群,同时哨兵又通过 INFO 命令,在主节点里获得了所有从节点连接信息,于是就能和从节点建立连接,并进行了。

选举完 leader 哨兵节点后,就执行主从切换。完成主从切换后,通过 Redis 的发布者/者机制通知客户端新主节点的 IP 地址和端口。

如果觉得本文对你有帮助,可以转发关注支持一下~

浅析Redis的BigKey(阿里巴巴技术协会ATA同步发送)

哨兵集群会通过投票的方式判定主节点是否「客观下线」,如果判定主节点为客观下线,那么就会从所有的「从节点」中选择一个作为新主节点,选择的规则有以下步骤:

在完成接入的需求时,我们需要记录上一个批次拉取的,并与当前拉取到的做出比对,从而进行分。我们目前的做法是使用redis来进行缓存:将上一个批次拉取到的缓存到一个list中。但是当数量过多时,value的大小会超过1M的限制,直接抛出异常。这其实是Tair出于性能的考虑而做出的限制,本文将谈谈我个人对于bigKey的理解。

顾名思义,bigKey指一个key对应的value占据的内存空间相对比较大,bigKey通常会有两种表现形式:

我们可以看到例如::

另外,在Redis执行异步重写作时(bgrewriteaof),主线程会fork出一个子进程来执行重写命令,这个子进程会与主线程共享内存。当主线程收到了新增或者修改一个key的命令,主线程会申请一块额外的内存空间来保存数据。但如果这个key是一个bigKey时,主线程会去申请一块更大空间,同样会阻塞主线程(与JVM分配内存一样,涉及锁和同步)。如果申请不到足够的空间,会导致Swap甚至会有OOM的风险,这同样会降低Redis的性能和稳定性。

Tair中一个key为1M,我们就以1M举例,当访问这个key的QPS为1000时,每秒将会有1GB左右的流量,对于带宽来说将是一个较大压力。如果这个bigKey是一个热点key时,后果将不堪设想。

如果主从同步的 client-output-buffer-limit 设置过小,并且 存在大量bigKey(数据量很大),主从全量同步时可能会导致 buffer 溢出,溢出后主从全量同步就会失败。如果主从集群配置了哨兵,那么哨兵会让 sle 继续向 发起全量同步请求,然后 buffer 又溢出同步失败,如此反复,会形成风暴,这会浪费 大量的 CPU、内存、带宽资源,也会让 产生阻塞的风险。 另外,当我们使用Redis Cluster时,由于Redis Cluster采用了同步迁移的方式,bigKey同样会阻塞主线程。这里提一下Codis,Codis在迁移bigKey时,使用了异步迁移 + 指令拆分的方式,对于bigKey (类型) 中每个元素,用一条指令进行迁移,而不是把整个 bigKey 进行序列化后再整体传输。这种化整为零的方式,就避免了 bigKey 迁移时,因为要序列化大量数据而阻塞的问题。

常用的做法是通过./redis-cli --bigkeys命令对整个redis中的键值对进行统计,输出每种数据类型中的 bigkey 的信息。一般会配合-i参数一起使用,控制扫描间隔,避免长时间扫描降低 Redis 实例的性能。另外该命令不要在业务高峰期使用。

或者我们可以通过debug object key 命令去查看serializedlength属性,serializedlength表示key对应的value序列化后的字节数,通过观察serializedlength的大小可以辅助排查bigKey。使用scan + debug object key命令,我们可以计算其中每个key的serializedlength,进而发现其中的bigKey,并做好相应的和处理。不过对于类型的bigKey,debug object key 命令的执行效率不高,存在阻塞redis的风险。

另外,在读取bigKey的时候,我们尽量不要一次性将全部数据读取出来,而是采用分批的方式进行读取:利用scan命令进行渐进式遍历,将大量数据分批多次读取出来,减小redis的压力,避免阻塞的风险。

同样的,在删除bigKey的时候我们也可以使用scan命令来进行批量删除。如果你是用的redis是4.0之后的版本,则可以利用unlink命令配合lazy fre在我次搭建哨兵集群的时候,当时觉得很诧异。因为在配置哨兵的信息时,竟然只需要填下面这几个参数,设置主节点名字、主节点的 IP 地址和端口号以及 quorum 值。e配置(需要手动开启)来进行异步删除,避免主线程阻塞。

redis哨兵和集群同时使用不

那在选定了即将作为主节点的从节后,由哨兵集群中的哪个节点进行主从故障转移呢?

redis哨兵和集群不能同时使用,Redis哨兵和集群是两种不同的Redis高可用方案。

1、Re一般的客户端连接流程如下:dis哨兵是一种自动化的Redis高可用解决方案,可以监测主节点的状态,并在主节点宕机后自动将从节点升级为新的主节点,以保证Redis服务的高可用性。Redis哨兵适用于单节点或者主从的场景,可以通过哨兵节点来实现Redis的自动切换和故障恢复。

2、Redis集群则是一种分布式的Redis解决方案,可以将数据分散到多个节点上,提高数据存储如果在第二轮考察中,发现有两个从节点优先级和进度都是一样的,那么就会进行第三轮考察,比较两个从节点的 ID 号,ID 号小的从节点胜出。和读取的性能。Redis集群适用于大规模的数据存储和高并发读写的场景,可以通过数据分片和节点来实现数据的高可用和负载均衡。

redis有哪些集群模式

在这个图中,每一个蓝色的圈都代表着一个redis的节点。它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他作。

Redis集群一般有5种:

那在选定了即将作为主节点的从节后,由哨兵集群中的哪个节点进行主从故障转移呢?

1,主从

2,哨兵模式

3,Redis提供的Cluster集群模式(服务端)

4,Jedis sharding集群(客户端sharding)

5,利用中间件,比如豌豆荚的codis等

介绍完他们的模式,现在来分析一下他们的原理:

主从(Master-Sle Replication):

实现主从(Master-Sle Replication)的工作原理:Sle从节点服务启动并连接到Master之后,它将主动发送一个SYNC命令。Master服务主节点收到同步命令后将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Sle,以完成一次完全同步。而Sle从节点服务在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给Sles,Sle将在本次执行这些数据修改命令,从而达到最终的数据同步。

主从配置

修改从节点的配置文件:sleof ip port

哨兵模式:

该模式是从Redis的2.6版本开始提供的,但是当时这个版本的模式是不稳定的,直到Redis的2.8版本以后,这个哨兵模式才稳定下来,无论是主从模式,还是哨兵模式,这两个模式都有一个问题,不能水平扩容,并且这两个模式的高可用特性都会受到Master主节点内存的限制。

Sentinel(哨兵)进程是用于redis集群中Master主工作的状态,在Master主发生故障的时候,可以实现Master和Sle的切换,保证系统的高可用。

(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Sle是否运作正常。

提醒(Notification):当被的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向或者其他应用程序发送通知。

自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移作,它会将失效Master的其中一个Sle升级为新的Master, 并让失效Master的其他Sle改为新的Master;当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master。Master和Sle切换后,Master的redis.conf、Sle的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主的redis.conf配置文件中会多一行sleof的配置,sentinel.conf的目标会随之调换。

Sentinel(哨兵)进程的工作方式

每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主,Sle从以及其他Sentinel(哨兵)进程发送一个 PING 命令。

如果一个实例(instance)距离一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)

如果一个Master主被标记为主观下线(SDOWN),则正在监视这个Master主的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主的确进入了主观下线状态

当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主进入了主观下线状态(SDOWN), 则Master主会被标记为客观下线(ODOWN)

在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主、Sle从发送 INFO 命令。

当Master主被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主的所有 Sle从发送 INFO 命令的频率会从 10 秒一次改为每秒一次。

若没有足够数量的 Sentinel(哨兵)进程同意 Master主下线, Master主的客观下线状态就会被移除。若 Master主重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主的主观下线状态就会被移除。

Redis Cluster集群模式

Redis Cluster是一种Sharding技术,3.0版本开始正式提供。

Redis集群数据分片

在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取作。

Jedis sharding集群

Redis Sharding可以说是在Redis cluster出来之前业界普遍的采用方式,其主要思想是采用hash算法将存储数据的key进行hash散列,这样特定的key会被定为到特定的节点上。

庆幸的是,Ja Redis客户端驱动Jedis已支持Redis Sharding功能,即ShardedJedis以及结合缓存池的ShardedJedisPool

Jedis的Redis Sharding实现具有如下特点:

采用一致性哈希算法,将key和节点name同时hashing,然后进行映射匹配,采用的算法是MURMUR_HASH。采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的rehashing。一致性哈希只影响相邻节点key分配,影响量小。

为了避免一致性哈希只影响相邻节点造成节点分配压力,ShardedJedis会对每个Redis节点根据名字(没有,Jedis会赋予缺省名字)会虚拟化出160个虚拟节点进行散列。根据权重weight,也可虚拟化出160倍数的虚拟节点。用虚拟节点做映射匹配,可以在增加或减少Redis节点时,key在各Redis节点移动再分配更均匀,而不是只有相邻节点受影响。

ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,这样通过合理命名key,可以将一组相关联的key放入同一个Redis节点,这在避免跨节点访问相关数据时很重要。

利用中间件

中间件的作用是将我们需要存入redis中的数据的key通过一套算法计算得出一个值。然后根据这个值找到对例如,jedis就提供了哨兵模式的客户端连接池类JedisSentinelPool,在运行过程中,客户端会保持与哨兵以及的连接。应的redis节点,将这些数据存在这个redis的节点中。

常用的中间件有这几种

Twemproxy

Codis

nginx

连接redis时是连接的哨兵还是

选择好从节点后,就需要从哨兵集群选择一个 leader 执行主从切换。选举 leader 的过程,也是一个投票的过程,任何一个想成为 leader 的哨兵节点,要满足两个条件:

哨兵模式连接哨兵,根据的名称获取的ip和port。下,客户端一般会保持两种连接,与哨兵的连接,以及的连接。数据作当然使用连接,如果出故障了,可以通过与哨兵的连接来获取的地址。

主节点挂了

通过ip和port连接。

另外,有一些公司自己封装了redis客户端,可以通过哨兵获得及其sles,采用读写分离,读sles,写。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。

联系我们

工作日:9:30-18:30,节假日休息