过期键删除策略

对于过期键值的删除有三种常见的做法

  1. 定时删除。为每一个过期的键创建一个定时器,过期立刻删除。

    优点:及时删除过期键值,释放内存空间

    缺点:如果过期键值较多时,在删除过期键值上占用的CPU较多,而在内存充足的情况下,过期键值其实是不必急着删除的,应该优先把CPU用在处理客户端请求上
  2. 惰性删除。当访问键的时候判断这个键是否已过期,过期就删除。

    优点:对CPU占用最少,不会在删除其他过期的键上花费时间

    缺点:不能及时删除键,释放内存。如果一个过期的键永远没有被访问,那么这个键就不会被删除,无用的垃圾数据会堆积在内存中,造成内存泄露
  3. 定期删除。每隔一段时间遍历一遍所有设置了过期时间的键,删除已过期键。

    优点:相对定时删除,占用的CPU时间更少,相对惰性删除,在执行频率设置合理的情况下也能及时删除过期键,释放内存

    缺点:频率很难设置,设置的过于频繁会退化成定时删除,设置的执行间隔太长,会导致过期键不能及时删除

Redis采用了惰性删除和定期删除,可以在合理使用CPU时间和避免浪费内存空间上取得平衡。另外在定期删除策略上也做了优化,每次执行定期删除会有最大执行时间限制,如果达到时间上限还没执行完会记录当前位置并停止处理,下次从纪录点继续执行

持久化

Redis是内存数据库,当Redis进程退出后,保存在内存中的数据就会丢失。为了解决这个问题,Redis提供了RDB跟AOF两种方式,将数据库状态进行持久化到磁盘中

RDB

RDB文件保存了Redis在某个时间点上的数据库状态,类似于快照,可以使用RDB文件将Redis数据恢复。Redis提供了两个命令生成RDB文件,分别是SAVE跟BGSAVE,区别是SAVE是由服务器进程直接执行,会阻塞服务器,BGSAVE是由子线程执行保存,不会阻塞服务器。

Redis默认设置了多个保存条件,900秒内对数据库修改1次、300秒内对数据库修改10次、60秒内对数据库修改10000次,服务器中有一个周期性执行的serverCron默认每隔100毫秒执行一次,在serverCron执行时检查只要其中任何一个条件得到满足就会执行BGSAVE命令自动保存。

AOF

除了RDB外,Redis还提供了AOF持久化功能,区别于RDB是通过直接保存数据库键值,AOF是通过保存服务器执行的写命令来记录数据库状态。当服务器的AOF功能打开的时候,每当服务器进行写操作,都会有对应的写命令记录在AOF的缓冲区中,缓冲区中的数据会根据配置持久化到文件中,目前AOF提供三种持久化的选项,分别是always(将缓冲区所有内容写入并同步到文件)、erverysec(每秒将缓冲区内容写入到文件)、no(由操作系统控制何时同步)



使用AOF还原数据库状态流程

AOF重写

前面讲到,AOF文件是具体执行的写命令记录,随着执行命令的次数越来越多,AOF文件内容会越来越大,为了解决这个问题,Redis提供了AOF文件重写的功能。通过这个功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含冗余命令。实现原理是从数据库中读取键当前的值,然后用生成一条命令去代替之前记录这个键值的多条命令。

例如:

实际执行命令
sadd animals "cat"
sadd animals "dog" "panda" "tiger"
srem animal "cat"
sadd animals "lion" "cat" 重写后保存命令
sadd animals "dog" "panda" "tiger" "lion" "cat"

另外AOF重写一般是使用子线程在后台执行,在重写期间服务器仍然继续处理客户端的请求。在重写期间,如果服务端处理的请求导致现有的数据库内容被修改,就会导致服务器当前的数据库状态与重写后的AOF文件保存的数据库状态不一致



为了解决这个问题,Redis服务器中设置了AOF重写缓冲区,会将AOF重写期间执行的写命令追加到AOF重写缓冲区中,等子线程重写完成后,再将缓冲区内容追加到AOF文件末尾,保持数据库状态一致

主从复制

Redis的复制功能分为同步和命令传播两个操作:

  • 同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态
  • 命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态

这个复制功能对于初次复制来讲能够很好地完成任务,但是对于断线后重复制来说,有可能从服务器跟主服务器数据只发生了几次变化甚至完全一致,但这个复制却要重新全量的覆盖一遍从服务器,效率非常低。为此Redis在2.8版本后开始,改进了复制功能,适用PSYNC命令代替SYNC命令。

完整重同步和部分重同步

PSYNC命令分为完整重同步和部分重同步两种操作

  • 完整重同步:完整重同步的执行步骤和SYNC命令的执行步骤基本一样,它们都是通过让主服务器创建并发送RDB文件,以及向从服务器发送保存在缓冲区里面的写命令来进行同步
  • 部分重同步:用于处理断线后重复制情况:当从服务器在断线后重新连接主服务器时,主服务器将一部分最近传播的写命令保存在复制积压缓冲区中,如果从服务器的复制偏移量之后的数据仍然存在复制积压缓冲区中,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态



哨兵Sentinel

哨兵对redis服务器集群的监听



主观下线:Sentinel对redis服务节点默认每秒发送心跳检测节点是否在线,但Redis实例连续向Sentinel返回无效回复,该Sentinel节点会将实例标记为主观下线状态。

客观下线:当Sentinel将一个主服务器判断为主观下线之后,为了确认这个主服务器是否真的下线了,它会向同样监视这一主服务器的其它Sentinel进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。当Sentinel从其他Sentinel那里接收到足够数量的已下线判断后,Sentinel就会将主服务判定为客观下线,并对主服务执行故障转移。

执行者选举

Sentinel确认主服务已经客观下线后,会要求其他Sentinel节点将自己设为执行故障转移的节点,其他节点采用抢占的方式,只接受第一个到达的抢占请求,并返回当前节点认可的执行节点ID,通过统计,可以得到最终过半数胜出的领头Sentinel执行故障转移

故障转移

在选举产生出领头Sentinel之后,领头Sentinel将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:

  1. 在已下线主服务器属下的所有从服务器中,挑选出一个从服务器,并将其转换为主服务器
  2. 让已下线主服务器属下的所有从服务器改为复制新的主服务器
  3. 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器

选择新的主服务器流程

  1. 筛选出在线的从服务器
  2. 根据从服务器的优先级,对从服务器进行排序,选择优先级最高从服务器
  3. 同最高优先级的从服务器,选择复制偏移量最大的从服务器(保存着最新数据)
  4. 以上都相同时,选择服务器运行ID最小的从服务器

Redis设计的更多相关文章

  1. Redis设计与实现(一~五整合版)【搬运】

    Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...

  2. 《Redis设计与实现》读书笔记

    <Redis设计与实现>读书笔记 很喜欢这本书的创作过程,以开源的方式,托管到Git上进行创作: 作者通读了Redis源码,并分享了详细的带注释的源码,让学习Redis的朋友轻松不少: 阅 ...

  3. 重读redis设计与实现

    重读了一遍redis设计与实现,这次收获也不错,把之前还有些疑惑的点:redis跳跃表的原理.redis持久化的方法.redis复制.redis sentinel.redis集群等,都重新熟悉了一遍, ...

  4. 如何使用redis设计关系数据库

    目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...

  5. 《Redis设计与实现》

    <Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...

  6. 《Redis设计与实现》阅读笔记(一)--Redis学习

    Redis学习资料与过程记录 在实习中经常会用到很多Redis,对Redis有了一些模糊的了解,总觉得隔靴搔痒的不痛快,所以决定开始深入的了解Redis,也作为我实习期间的目标. 这篇只是为了占个位置 ...

  7. Redis设计与实现读后感

    看了一下时间,现在是2018年8月22日14:28,看完最后一页内容之后,我简短的停留了一下,任思绪翻飞. redis设计与实现大概看了有12天左右,12天前,我的心里很乱,整个人都处于一种焦虑不安的 ...

  8. 180713-Spring之借助Redis设计访问计数器之扩展篇

    之前写了一篇博文,简单的介绍了下如何利用Redis配合Spring搭建一个web的访问计数器,之前的内容比较初级,现在考虑对其进行扩展,新增访问者记录 记录当前站点的总访问人数(根据Ip或则设备号) ...

  9. 180626-Spring之借助Redis设计一个简单访问计数器

    文章链接:https://liuyueyi.github.io/hexblog/2018/06/26/180626-Spring之借助Redis设计一个简单访问计数器/ Spring之借助Redis设 ...

  10. 【Redis】四、Redis设计原理及相关问题

    (六)Redis设计原理及相关问题   通过前面关于Redis五种数据类型.相关高级特性以及一些简单示例的使用,对Redis的使用和主要的用途应该有所掌握,但是还有一些原理性的问题我们在本部分做一个探 ...

随机推荐

  1. 图计算引擎分析--GridGraph

    作者:京东科技 李永萍 GridGraph:Large-Scale Graph Processing on a Single Machine Using 2-Level Hierarchical Pa ...

  2. 搭建CTF动态靶场

    前言 本文借鉴文章:https://www.yuque.com/dengfenglai-esbap/kb/mc4k41?#xOxNG 在此基础上修改了一点(照着原来的做没成功),感谢这位师傅给的资源. ...

  3. 一文搞懂JavaScript数组的特性

    前言 数组是几乎所有编程语言的基础语法,JavaScript因为语法特性,之前缺少一些集合类对象,对数组的使用就会更多一些,因此我们更需要理解数组知识. 然而大部分人对数组都已经非常熟悉了,所以本文将 ...

  4. Django笔记二十九之中间件介绍

    本文首发于公众号:Hunter后端 原文链接:Django笔记二十九之中间件介绍 这一节介绍一下 Django 的中间件. 关于中间件,官方文档的解释为:中间件是一个嵌入 Django 系统的 req ...

  5. 保姆级教程:用GPU云主机搭建AI大语言模型并用Flask封装成API,实现用户与模型对话

    导读 在当今的人工智能时代,大型AI模型已成为获得人工智能应用程序的关键.但是,这些巨大的模型需要庞大的计算资源和存储空间,因此搭建这些模型并对它们进行交互需要强大的计算能力,这通常需要使用云计算服务 ...

  6. 第一章:PyTorch 入门

    第一章:PyTorch 入门 1.1 Pytorch 简介 1.1.1 PyTorch的由来 1.1.2 Torch是什么? 1.1.3 重新介绍 PyTorch 1.1.4 对比PyTorch和Te ...

  7. 【Python基础】变量的作用域与global、nonlocal

    在 Python 中,变量的作用域指的是变量可以被访问的范围.Python 中的变量作用域有两种: 局部作用域:变量在函数函数内部的时候,只能在函数内部使用.这样的变量被称为局部变量. 如果在函数内部 ...

  8. 2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词。 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor

    2023-04-17:设计一个包含一些单词的特殊词典,并能够通过前缀和后缀来检索单词. 实现 WordFilter 类: WordFilter(string[] words) 使用词典中的单词 wor ...

  9. 2022-12-09:上升的温度。以下的数据输出2和4,2015-01-02 的温度比前一天高(10 -> 25),2015-01-04 的温度比前一天高(20 -> 30),sql语句如何写? DR

    2022-12-09:上升的温度.以下的数据输出2和4,2015-01-02 的温度比前一天高(10 -> 25),2015-01-04 的温度比前一天高(20 -> 30),sql语句如 ...

  10. 2022-09-07:给你一个由正整数组成的数组 nums 。 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数。 例如,序列 [4,6,16] 的最大公约数是 2 。 数组的一个

    2022-09-07:给你一个由正整数组成的数组 nums . 数字序列的 最大公约数 定义为序列中所有整数的共有约数中的最大整数. 例如,序列 [4,6,16] 的最大公约数是 2 . 数组的一个 ...