Redis设计
过期键删除策略
对于过期键值的删除有三种常见的做法
- 定时删除。为每一个过期的键创建一个定时器,过期立刻删除。
优点:及时删除过期键值,释放内存空间
缺点:如果过期键值较多时,在删除过期键值上占用的CPU较多,而在内存充足的情况下,过期键值其实是不必急着删除的,应该优先把CPU用在处理客户端请求上 - 惰性删除。当访问键的时候判断这个键是否已过期,过期就删除。
优点:对CPU占用最少,不会在删除其他过期的键上花费时间
缺点:不能及时删除键,释放内存。如果一个过期的键永远没有被访问,那么这个键就不会被删除,无用的垃圾数据会堆积在内存中,造成内存泄露 - 定期删除。每隔一段时间遍历一遍所有设置了过期时间的键,删除已过期键。
优点:相对定时删除,占用的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将对已下线的主服务器执行故障转移操作,该操作包含以下三个步骤:
- 在已下线主服务器属下的所有从服务器中,挑选出一个从服务器,并将其转换为主服务器
- 让已下线主服务器属下的所有从服务器改为复制新的主服务器
- 将已下线主服务器设置为新的主服务器的从服务器,当这个旧的主服务器重新上线时,它就会成为新的主服务器的从服务器

选择新的主服务器流程
- 筛选出在线的从服务器
- 根据从服务器的优先级,对从服务器进行排序,选择优先级最高从服务器
- 同最高优先级的从服务器,选择复制偏移量最大的从服务器(保存着最新数据)
- 以上都相同时,选择服务器运行ID最小的从服务器
Redis设计的更多相关文章
- Redis设计与实现(一~五整合版)【搬运】
Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...
- 《Redis设计与实现》读书笔记
<Redis设计与实现>读书笔记 很喜欢这本书的创作过程,以开源的方式,托管到Git上进行创作: 作者通读了Redis源码,并分享了详细的带注释的源码,让学习Redis的朋友轻松不少: 阅 ...
- 重读redis设计与实现
重读了一遍redis设计与实现,这次收获也不错,把之前还有些疑惑的点:redis跳跃表的原理.redis持久化的方法.redis复制.redis sentinel.redis集群等,都重新熟悉了一遍, ...
- 如何使用redis设计关系数据库
目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...
- 《Redis设计与实现》
<Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...
- 《Redis设计与实现》阅读笔记(一)--Redis学习
Redis学习资料与过程记录 在实习中经常会用到很多Redis,对Redis有了一些模糊的了解,总觉得隔靴搔痒的不痛快,所以决定开始深入的了解Redis,也作为我实习期间的目标. 这篇只是为了占个位置 ...
- Redis设计与实现读后感
看了一下时间,现在是2018年8月22日14:28,看完最后一页内容之后,我简短的停留了一下,任思绪翻飞. redis设计与实现大概看了有12天左右,12天前,我的心里很乱,整个人都处于一种焦虑不安的 ...
- 180713-Spring之借助Redis设计访问计数器之扩展篇
之前写了一篇博文,简单的介绍了下如何利用Redis配合Spring搭建一个web的访问计数器,之前的内容比较初级,现在考虑对其进行扩展,新增访问者记录 记录当前站点的总访问人数(根据Ip或则设备号) ...
- 180626-Spring之借助Redis设计一个简单访问计数器
文章链接:https://liuyueyi.github.io/hexblog/2018/06/26/180626-Spring之借助Redis设计一个简单访问计数器/ Spring之借助Redis设 ...
- 【Redis】四、Redis设计原理及相关问题
(六)Redis设计原理及相关问题 通过前面关于Redis五种数据类型.相关高级特性以及一些简单示例的使用,对Redis的使用和主要的用途应该有所掌握,但是还有一些原理性的问题我们在本部分做一个探 ...
随机推荐
- Awesome GPT 来了!
大家好!我是韩老师. GPT, ChatGPT, OpenAI, LLM(大语言模型)等等技术的出现与应用,改变了许多的行业和人. 长期来看,类 GPT 的技术会对整个世界有着持续的改变. 我们几乎每 ...
- python pyinstaller库
简要 pyinstaller模块主要用于python代码打包成exe程序直接使用,这样在其它电脑上即使没有python环境也是可以运行的. 用法 一.安装 pyinstaller属于第三方库,因此在使 ...
- Python 使用类和实例
使用类和实例 直接修改实例的属性 编写方法以特定的方式进行修改 # 案例: class Car(): '''一次模拟汽车的简单尝试''' def __init__(self,make,model,ye ...
- SSH客户端常用工具SecureCRT操作
目录 1.1 SecureCRT工具介绍 1.2 SecureCRT工具安装 1.3配置SecureCRT连接Linux主机 1.4调整SecureCRT终端显示和回滚缓冲区大小 1.5调整字体及光标 ...
- Git&GitHub简介与入手(二)
四.GitHub 1.建账号,仓库 https://github.com/ 用邮箱在官网注册: 增加远程库的地址取别名为origin,push为推送,fetch为取回: 2.推送操作 将本地当前所在 ...
- 2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1、a2、…、an, 小美每次操作可以选其中的一台机器,假设选的是第i台, 那小美可以将其变成
2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1.a2.-.an, 小美每次操作可以选其中的一台机器,假设选的是第i台, 那小美可以将其变成 ...
- 2020-12-06:mysql中,多个索引会有多份数据吗?
福哥答案2020-12-06: 数据不会有多份,索引有几个就有几份.聚簇索引存数据和索引,非聚簇索引存索引,聚簇索引只有一个,非聚簇索引可以有多个.
- 2021-03-23:给定一个正整数组成的无序数组arr,给定一个正整数值K,找到arr的所有子数组里,哪个子数组的累加和等于K并且是长度最大的。返回其长度。
2021-03-23:给定一个正整数组成的无序数组arr,给定一个正整数值K,找到arr的所有子数组里,哪个子数组的累加和等于K并且是长度最大的.返回其长度. 福大大 答案2021-03-23: 双指 ...
- golang技术栈常见网址
go所有,包含goadmin golang标准库文档 golang修养之路 Golang Profiling: 关于 pprof go问题 go语言设计与实现 go.mod解析 proto3 prot ...
- 2021-05-08:给定两个非负数组x和hp,长度都是N,再给定一个正数range。x有序,x[i]表示i号怪兽在x轴上的位置;hp[i]表示i号怪兽的血量 。range表示法师如果站在x位置,用A
2021-05-08:给定两个非负数组x和hp,长度都是N,再给定一个正数range.x有序,x[i]表示i号怪兽在x轴上的位置:hp[i]表示i号怪兽的血量 .range表示法师如果站在x位置,用A ...