Redis探寻之路 - 服务器策略

本文详细介绍了Redis的复制机制(包括旧版同步和新版psync),部分重同步的实现,Sentinel的高可用解决方案,以及Redis集群、发布与订阅和过期删除策略。还探讨了哨兵在主节点故障情况下的应用和Redis集群的动态扩展能力。
摘要由CSDN通过智能技术生成

第十五章 复制

用户可以通过slaveof命令或设置slaveof属性,让一个服务器去复制另一个服务器。

15.1 旧版复制

旧版复制:分为同步(sync)和命令传播

缺陷:执行bgsave非常耗资源 ,发送RDB文件给从服务器非常消耗网络资源,接收RDB文件时会使从服务器阻塞。

15.3 新版复制功能

psync代替sync,psync具有完整重同步和部分重同步

完整重同步:处理初次复制的情况,主服务创建并发送RDB文件,以及向从服务器发送保存在缓冲区中的写命令。

部分重同步:当从服务器与主服务器断开连接并重新连接后,主服务器向从服务器发送在这期间执行的写命令。

15.4 部分重同步的实现

主服务器每次向从服务器传播N个字节的数据时,主服务器的复制偏移量加上N,从服务器接收到数据时,从服务器的复制偏移量也加上N。通过比对服务器的复制偏移量很容易知道主从服务器是否处于一致状态。

复制积压缓冲区:

复制积压缓冲区是由主服务器维护一个固定长度先进先出(FIFO)队列,默认1MB大小

当从服务器重新连上主服务器时,从服务器会ton过psync命令将自己的复制偏移量发送诶主服务器,,主服务器根据这个复制偏移量来决定对服务器执行哪种同步操作

  • 如果offset偏移量之后的数据仍然存在在复制缓冲区中,则主服务器对从服务器进行部分重同步操作

  • 如果offset偏移量之后数据不存在在复制缓冲区中,则主服务器对从服务器进行完整重同步操作

服务器运行ID

部分重同步还会用到服务器ID,这里保存和传递主服务器ID,从服务器的ID与主服务器的ID相同,则连接正确,可以进行部分重同步操作

15.5 PSYNC命令的实现

PSYNC的调用方法:

  • 如果从服务器之前没有经过任何一次复制或者执行过slaveof no one命令,那么从服务器在开始一次新的复制时向主服务器发送PSYNC ? -1命令,主动请求主服务器进行完整重同步

  • 如果从服务器已经复制过主服务器,则从服务器向主服务器发送PSYNC <runid> <offset>

  • 如果主服务器返回+CONTINUE恢复,则表示主服务器将于从服务器执行部分重同步操作

15.6 复制的实现

  • 设置主服务器的地址和端口 slaveof 127.0.0.01 6379 客户端返回ok

  • 建立套接字连接,创建连向主服务器的套接字连接

  • 从服务器称为主服务器的客户端后,会先向主服务器发送一个PING命令(检查读写状态是否正常,检查主服务器是否能正常处理请求)

  • 身份验证: 从服务器是否设置masterauth 主服务器是否设置requirepass

  • 发送端口信息: 从服务器向主服务器发送端口信息

  • 同步 :从服务器向主服务器发送PSYNC命令,执行同步操作,并将自己的数据库更新至主数据库当前所处的状态

  • 命令传播:完成同步后,主服务器只要一直将自己执行的写命令发送给从服务器,就可以保证主从服务器的一致性了

15.7 心跳检测

在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令

REPLCONF ACK <replication_offset>(从服务器当前偏移量)

作用:检测主从服务器的连接状态 辅助实现min-slaves 检测命令丢失

根据发送的偏移量检测到没有实现主从服务器的一致性

第十六章 Sentinel

Sentinel是Redis的高可用的解决方案。Sentinel系统负责监视一个主服务器和它的多个从服务器,当主服务器宕机,就自动将某个从服务器升级为主服务器。

当server1的下线时长超过用户设定的下线时长时,Sentinel系统就会对server1执行故障转移操作。

  • 首先,Sentinel系统挑选某个从服务器作为主服务器

  • 之后,Sentinel系统会向所有从服务器发送新的复制指令,让它们变成新的主服务器的才能服务器

  • 已下线的主服务器重新连接后,会重新变为从服务器

16.1 启动并初始化Sentinel

初始化服务器:

Sentinel本质是特殊模式下的Redis服务器,相当于初始化一个普通的redis服务器。初始化普通服务器通过载入RDB文件或者AOF文件来还原数据库状态,Sentinel不适用数据库,所以初始化时就不用载入RDB文件或AOF文件。

初始化Sentinel状态的masters属性,创建连向主服务器的网络连接,获取主服务器的信息,获取从服务器的信息。

默认情况下,Sentinel会议每两秒一次的频率向服务器发送信息

16.5 Sentinel还会接收来自主服务器和从服务器的频道信息

多监视同一个服务器的多个sentinel来说,一个sentinel发送的信息会被其它sentinel接收到。

当一个sentinel接收到一条信息后,会根据SentinelID检查,如果不是自己的Sentinel发送的,将根据信息的参数对主服务器的实例结构做更新。即更新sentinel字典当中的相关信息。

检测下线状态:

默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例发送ping命令,来判断实例是否在线。

当Sentinel讲一个主服务器判断为主观下线后,为了确认这个服务器是否真的下线,会向其它sentinel咨询是否该服务器已经下线,sentinel就会将从服务器判定为客观下线,并对主服务器执行故障转移操作。

16.8 选举领头Sentinel

当一个服务器被判定为客观下线后,监视这个主服务器的各个sentinel会进行协商,选举出一个领头的sentinel,并由领头sentinel对下线服务器执行故障转移操作。

sentinel设置领头sentinel的规则是先到先得,在给定时间内有超过一般sentinel将某个sentinel设置

为领头sentinel,则选举成功。

16.9 故障转移

选举领头sentinel成功后就可以进行故障转移了

故障转移步骤(如上)

选举出新的主服务器:

领头sentinel在所有从服务器中挑选出一个状态良好、数据完整的从服务器,然后向这个从服务器发送slaveof no one命令,将这个从服务器转换为主服务器

挑选新的主服务器规则:删除列表中下线和5秒内无回复的的从服务器,之后选出优先级最高的,若优先级相同则选出复制偏移量最高的

修改从服务器的复制目标

将旧的主服务器变为从服务器

第十七章 集群

Reids集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能。

17.1 节点

一个redis集群由多个节点组成。cluster meet让node节点与指定ip和端口号的节点进行握手,那么就会将指定ip和端口号的节点添加到当前node节点的集群当中。

一个节点就是一个运行在集群模式下的服务器,Redis服务器会在启动时根据cluster-enabled配置选项是否为yesy来决定是否开启服务器的集群模式。

集群数据结构:

clusterNode结构保存了一个节点的当前状态,每个节点都保存这一个clusterState结构,记录了在当前节点的视角下,集群目前所处的状态

17.2 槽指派

reids集群通过分片方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这16384个槽的其中一个,集群中的每个节点都可以处理0个或最多16384个槽。

当数据库中的16384个槽都在被处理,则集群处于上线状态,如果有任何一个槽没有被处理,那么集群处于下线状态。

记录节点的槽指派信息:

slots数组,slots[i]为0,表示该节点不负责处理槽i+1,slots[i]为1,表示该节点负责处理槽i+1

一个节点除了会将自己负责处理的槽记录在clusterNode 结构的slots属性和numslots 属性之外,它还会将自己的slots数组通过消息发送给集群中的其他节点,以此来告知其他节点我负责处理哪些槽。

记录集群的所有槽指派信息:

通过slots[i]的值就可以看到第几个槽被指派给了哪个节点或是否被指派

17.3 在集群中执行命令

在对数据库中的16384个槽都进行指派之后,集群就会进入上线状态,这时客户端就可以向集群中的节点发送数据命令了。

当客户端向节点发送命令时,节点会计算出命令要处理的键值对在哪个槽,并检查这个槽是否为委派给自己处理:

  • 这个槽被委派给了当前节点,则执行指令

  • 这个槽没有被委派给当前节点,当前节点向客户端返回一个MOVED错误,转至正确节点,再次发送要执行的命令。

CRC16(key)计算键属于哪个槽

节点还会通clusterState结构中的跳跃表来保存槽和键之间的关系

每当节点王数据库中添加一个新的键值对时,节点就会将这个键以及键的槽号关联到slots_to_keys跳跃表。

17.4 重新分片

Redis集群的重新分片可以将任意数量已经派给某个节点的槽改为指派给另外一个节点。

17.5 ASK错误

在重新分配期间,被迁移槽的一部分键值对保存在源节点里,而另一部分键值对保存在目标节点里。当客户端向源节点发送一个与数据库键有关的命令,并且命令要处理的数据库键恰好就属于正在被迁移到额槽时:

  • 源节点会在自己的数据库里找指定的键,如果找到的话,就吉接执行客户端发送的命令。

  • 相反地,如果源节点没能在自己的数据库里面找到指定的键,那么这个键有可能已经被迁移到了目标节点,源节点将向客户端返回一个ASK错误,指引客户端转向正在导人槽的目标节点,并再次发送之前想要执行的命令。

17.6 复制与故障转移

redis集权中的节点分为主节点和从节点,主节点用于处理槽,而从节点用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求。

设置从节点

故障检测:每个节点都定期向集群中其它节点发送PINg消息,以此来检测对方是否在线

故障转移:

选举新的主节点:与sentinel方法类似,都是基于raft算法实现的

17.7 消息

集群中的各个节点通过发送和接收消息来进行通信,称发送消息的为发送者,接收消息的为接收者。

节点发送的消息:

meeet、ping、pong、fall、publish

第十八章 发布与订阅

Redis的发布与订阅功能由PUBLISH、SUBSCRIBE、PSUBSCRIBE等命令组成。

通过执行SUBSCRIBE命令,客户端可以订阅一个或多个频道,从而成为这些频道的订阅者( subscriber ):每当有其他客户端向被订阅的频道发送消息( message)时,频道的所有订阅者都会收到这条消息。

18.1 频道的订阅与退订

SUBSCRIBE命令

18.2 模式的订阅与退订

18.3 发送消息

redis集群动态扩容和收缩?

redis专题:redis集群的动态扩容缩容,水平扩展_redis动态扩容_知识分子_的博客-CSDN博客

扩容:先检查原始节点是否正常,再进行节点的增加,节点增加后进行哈希槽的重分配

收缩:.......

redis的过期删除策略:

Redis 的过期策略都有哪些?_redis过期策略_littleAsuna的博客-CSDN博客

定期删除+惰性删除

定期删除不是每隔多少秒就遍历所有设置过期时间的key,而是每隔一段时间随机抽取一些key来检查。然后再进行惰性删除,访问时发现该key过期了才进行删除。惰性删除会漏掉很多key,导致大量key堆积在内存中,导致了redis内存耗尽(当已用内存超过maxmemory),则需要走内存淘汰机制

redis 内存淘汰机制有以下几个: • noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了。 • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。 • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。 • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)。 • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。 • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。

集群和哨兵的应用场景:cluster解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器上(具体表现为将槽全部分配到多个节点上,实现动态扩容和收缩),着眼于高可用,提高并发量。哨兵是单个的主服务器,写的性能有限,而集群是多个主节点和从节点。哨兵主要解决主节点宕机下线的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值