面试redis之两大金刚,你懂吗

news2024/9/24 9:20:27

前言

Redis持久化,一个老掉牙的问题,但是面试官就是喜欢问。这也是我们学Redis必会的一个知识点。Redis作为内存数据库,它工作时,数据都保存在内存里,这也是它为什么很快的一个原因。但存到内存里肯定是有丢数据的风险,所以Redis是有设计持久化的。Redis持久化分为两种:RDB和AOF。

图片

RDB持久化

RDB(Redis DataBase),是redis默认的存储方式,RDB持久化其实就是将内存的数据直接做了一份快照到磁盘上。触发RDB持久化的方式有:

  • 符合配置的快照保存规则(配置文件里save开头的配置);

  • 执行save或者bgsave命令;

  • 执行flushall命令;

  • 执行主从复制操作 (第一次)。

配置文件redis.conf中,save开头的配置为RDB持久化相关配置。具体解释如下:

  • save “” 表示关闭rdb持久化;
  • save 3600 1 表示每1小时至少有1个key改变,就触发一次持久化可以写多个条件 ;
  • save 3600 1 300 100 60 10000 这里定义了三个策略,它们相互之间为或的关系。

图片

RDB文件生成过程

我们以bgsave为例子来看下Redis生成RDB文件的大致过程是怎样的。

int rdbSaveBackground(char *filename, rdbSaveInfo *rsi) {
    pid_t childpid;
    long long start;

 // 如果已经存在aof重写子进程以及rdb生成子进程则直接返回错误
    if (server.aof_child_pid != -1 || server.rdb_child_pid != -1) return C_ERR;
    ...
    // fork子进程进行RDB文件生成
    if ((childpid = fork()) == 0) {
        ...
        // 生成RDB文件
        retval = rdbSave(filename,rsi);
        if (retval == C_OK) {
            size_t private_dirty = zmalloc_get_private_dirty(-1);

            if (private_dirty) {
                serverLog(LL_NOTICE,
                    "RDB: %zu MB of memory used by copy-on-write",
                    private_dirty/(1024*1024));
            }

            server.child_info_data.cow_size = private_dirty;
            // 通知父进程RDB文件生成完毕
            sendChildInfo(CHILD_INFO_TYPE_RDB);
        }
        //子进程退出
        exitFromChild((retval == C_OK) ? 0 : 1);
    } else {
       //父进程业务逻辑
        ...
    }
    return C_OK; 
}

(1)Redis主进程首先判断当前是否存在已经在执行的aof重写子进程以及rdb文件生成子进程,如果存在的话则直接进行返回。为什么要进行这样的判断呢?主要还是从服务器性能方面进行考量,如果服务器有多个子线程在进行RDB持久化操作,那么必定会对磁盘造成比较大的IO压力,如果服务器中还部署了其他服务甚至会影响其他服务的正常运行。

(2)Redis主进程fork子进程进行RDB文件生成操作,在fork的过程中,此时的Redis主进程是阻塞的,不能响应客户端请求,子进程fork完成之后可以继续响应客户端请求。

(3)fork出来的子进程遍历内存数据进行RDB文件生成操作。

(4)如果此时客户端的请求需要修改缓存数据,那么如上面fork子进程的原理,通过COW机制,操作系统会开辟新的内存空间给Redis主进程进行新的缓存数据写入。

(5)子进程快照数据生成完成之后,替换原来老的RDB文件。

图片

RDB触发时机

Redis主要支持两种持久化操作来生成RDB文件,分别是save、bsave命令方式手动生成以及在配置文件中配置时间间隔自动进行RDB文件生成。

手动命令触发

客户端连接到redis之后我们可以通过save以及bsave命令进行RDB文件的立即创建,两者的区别如下:

save:通过主线程触发,会阻塞Redis业务,如果内存数据比较多的话,会导致长时间不能响应外部请求;

客户端执行bsave命令进行RDB持久化,Redis主线程会fork子线程出来进行RDB文件持久化操作,这样避免了主线程的阻塞即便正在持久化操作依然可以响应外部数据缓存请求。

不过这里值得注意的是,虽然fork子进程之后不会阻塞主进程,但是在fork的过程中会阻塞主进程,尤其是在内存数据比较大的时候,阻塞主进程的时间会更长。

配置自动触发

另外在Redis的配置文件redis.conf中,我们可以配置按照一定的时间间隔来进行RDB持久化操作。如下配置:

save 900 1
save 300 10
save 60 10000

其他的触发RDB文件生成的操作这里不再赘述了,像从节点执行全量数据同步的时候,也会触发主节点生成RDB文件发送给从节点。

AOF持久化

AOF(Append Only File)持久化,是其将Reids执行过的所有写指令记录下来,保存到日志里,类似MySQL的bin-log。默认配置文件里该持久化方式是关闭的,需要将配置修改为:

appendonly yes

由于AOF是将Redis服务的写操作日志写到日志文件里,当写操作非常频繁时,那么它对磁盘也会造成很大的压力。所以,AOF的磁盘数据落地(fsync函数)也有三个策略:

Always:表示只要有写入就会调用fsync函数;

Everysec:表示每秒调用fsync函数一次;

No:表示不调用fscyn函数,完全跟着系统走;

图片

建议选择everysec,比较保守一些。

AOF重写

AOF文件如果不做干预,它会一直增涨,直到将你的磁盘写满。好在Redis给AOF提供了重写机制。我们可以直接执行如下命令,进行AOF重写:

bgrewriteaof;

执行完该命令后,AOF文件会根据已经持久化的RDB文件和现有AOF文件重新整理,它会把无用的写日志清空,最终达到瘦身目的。

当然,AOF还有一个重写的配置,两个参数:

参数说明
auto-aof-rewrite-min-sizeAOF文件必须要不低于这个尺寸时才会触发重写,后面的每次重写就不会根据这个变量了(根据上一次重写完成之后的大小)。此变量仅初始化启动redis有效
auto-aof-rewrite-percentage如果该数值定义为80,则表示当AOF文件增长的尺寸超过上次大小(AOF文件上次重写后的大小会被记录下来)百分80时就会触发重写操作

RDB和AOF如何选

在实际生产环境中,根据数据量、应用对数据的安全要求、预算限制等不同情况,会有各种各样的持久化策略。

如,完全不使用任何持久化、使用RDB持久化或AOF持久化的一种,或同时开启快照持久化和AOF持久化等。此外,持久化的选择必须与Redis的主从策略一起考虑,因为主从复制与持久化同样具有数据备份的功能,而且主机Master和从机Slave可以独立的选择持久化方案。

如果Redis中的数据完全丢弃也没有关系(如Redis完全用作DB层数据的cache),那么无论是单机,还是主从架构,都可以不进行任何持久化。

在单机环境下(对于个人开发者,这种情况可能比较常见),如果可以接受十几分钟或更多的数据丢失,选择RDB持久化对Redis的性能更加有利,如果只能接受秒级别的数据丢失,应该选择AOF。

但在多数情况下,我们都会配置主从环境,Slave的存在既可以实现数据的热备,也可以进行读写分离分担Redis读请求,以及在Master宕掉后继续提供服务。在这种情况下,一种可行的做法是:

  • Master:完全关闭持久化,这样可以让Master的性能达到最好;
  • Slave:关闭RDB持久化,开启AOF(如果对数据安全要求不高,开启RDB持久化关闭AOF也可以),并定时对持久化文件进行备份(如备份到其他文件夹,并标记好备份的时间)。然后关闭AOF的自动重写,然后添加定时任务,在每天Redis闲时(如凌晨12点)调用bgrewriteaof。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/452460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么我们能判断声音的远近

想象一下,当我们走在路上时,听到了头顶的鸟儿在树梢间的叫声,即使无法透过浓密的树叶看见它,也可以大致知道鸟儿的距离。此时身后传来由远到近自行车铃铛声,我们并不需要回过头去看,便为它让开了道路。这些…

查找文件路径——whereis、which、locate、find命令

目录标题 whereis命令——通过环境变量查找所有文件(包括可执行文件)which命令——查找系统命令文件与whereis命令区别 locate命令——全局搜索find命令(全盘搜索)find命令中的参数及作用按照文件名搜索按照文件大小搜索按照修改时…

离散数学-考纲版-02-谓词

文章目录 2. 谓词参考2.1 命题2.1 个体谓词和量词2.1.1 个体2.1.2 谓词2.1.3 量词引入个体域符号化量词真值确定谓词符号化举例示例一示例二示例三示例四 2.3谓词合式公式2.3.1 四类符号2.3.2 项2.3.3 合式公式 2.4 自由变元与约束变元2.4.1 定义2.4.2 判定2.4.3 两个规则2.4.4…

【京东】商品详情页+商品列表数据采集

作为国内最大的电商平台之一,京东数据采集具有多个维度。 有人需要采集商品信息,包括品类、品牌、产品名、价格、销量等字段,以了解商品销售状况、热门商品属性,进行市场扩大和重要决策; 有人需要采集产品评论&…

Android OpenGL 渲染相机预览画面显示体系

OpenGL能进行高效得渲染图形图像,并支持各种复杂的特效和动画。 而在 Android 当中,运用的是OpenGL ES,它是OpenGL的一个轻量级版本,专门用于在移动设备、游戏控制台、嵌入式系统等嵌入式环境中使用。 它可以做相机滤镜或者图片…

基于html+css的图片展示31

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

yield用法理解,配有代码块和解析

包含 yield 关键字的函数,是一个生成器 yield和return的区别 1、return是返回return关键字的值,被调用一次就返回一次,return只能放在一个函数代码块的最后面,运行到return的时候,就结束循环,结束这个函数…

IO、存储、硬盘、文件系统相关常识

目录 IO 文件系统 存储 存储这些数据的硬盘 IO io分为io设备和io接口, 我们日常生活中的打印机, 固态硬盘等都是io设备. IO(Input-Output)是指计算机中输入输出的相关操作,包括数据的读取、存储、传输和显示等。存储是指将数据保存在计算…

美国肝素钠专用树脂,医药肝素钠提取工艺专用树脂

具有控制孔径的大孔强碱性Ⅰ型阴离子交换树脂 Tulsimer A-72 MP 是一款具有便于颜色和有机物去除的控制孔径的,专门开发的大孔强碱性Ⅰ型阴离子交换树脂。 Tulsimer A-72 MP专门应用于去除COD以及其他有机物等。 Tulsimer A-72 MP 由于其本身的大孔特性而显示出…

电巢携手中国自动化学会:计算机能有感情史了

4月22日,为了促进模式识别、数据挖掘和计算机视觉等相关领域从业者进一步了解领域内最新发展动态与前沿技术进展,由中国自动化学会主办,中国自动化学会模式识别与机器智能(CAA-PRMI)专委会、中国计算机学会&#xff08…

Python OpenCV 蓝图:6~7

原文:OpenCV with Python Blueprints 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 计算机视觉 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 当别人说你没有底线的时候,你最好真…

【Cartopy基础入门】如何更好的确定边界显示

原文作者:我辈理想 版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。 Cartopy基础入门 【Cartopy基础入门】Cartopy的安装 【Cartopy基础入门】Geojson数据的加载 【Cartopy基础入门】如何更好的确定边界显示 文章目录 Ca…

苯酚吸附树脂

苯酚作为一种重要的化工原料,主要用于生产酚醛树脂,双酚A,己内酰胺,壬基酚,水杨酸等,此外还可以做溶剂,试剂盒消毒剂等,在合成纤维,合成橡胶,塑料&#xff0c…

我国采矿采石设备制造行业发展现状与部分产品市场分析

一、行业基本概述 采矿采石设备制造,指地下或露天,用于对金属、煤炭、石油、化工等各种矿石或建筑用石的开采设备制造,以及矿石筛选、分类、分离、洗选、轧碎或类似加工工艺使用的专用机械的制造。 根据观研报告网发布的《 中国采矿采石设备…

5年测试总结,自动化测试DevOps-CICD持续集成流程设计...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 测试进阶&#xf…

JS对Json数组进行抽取 获取key: “value“

这篇文章不是拿key或value 是抽取需要的 key: “value” 【必须是单一数组 若是多组数据需要for循环】 // row 是json串 !!! 一、我有一个单一的json【row】 只要 id 和 appStatus 且分开成新数组 let list [];for (var key in row) {var temp {}if (key "id") {…

MyBatis-Plus多数据源dynamic-datasource解决多线程情境下数据源切换失效问题

前言:项目中使用MyBatis-Plus多数据源dynamic-datasource,完成多数据源的切换;但是在并发场景下,我们会发现线程会一直访问默认数据源(配置的Master数据),并没有访问我们在上一步切换后的数据源…

如何把电脑文件备份?本指南很详细

概述:当文件发生丢失的时候,如果我们有备份,直接进行还原就可以了。可见备份的重要性。如何把电脑文件备份?本文将为大家详细介绍。 一、为什么要备份文件 我们在电脑上面会保存很多文件,有的文件是很重要的&#xf…

基于vfw的局域网语音聊天室系统源码论文

语音视频聊天 UDP套接字的运用 在实现语音视频聊天时,采用的是基于UDP套接字的点对点模式,而UDP面向的是无连接的数据服务,其套接字的使用如图10所示。 图10 UDP套接字的使用 视频的捕获 利用VFW接口,视频捕获可以分为以下几个步骤: 建立视频采集窗口…

如何把数据库中的数据显示到页面

主要内容:使用JDBC访问数据库中数据(Java Web数据可视化案例) 文章目录 前期准备:案例:第一步:创建数据库及数据第二步:编写实体类第三步:编写Dao类第四步:编写Servlet代…