Redis后台任务有哪些
Redis后台任务
为了有更好的性能表现,redis对于一些比较耗时的操作会异步执行,不阻塞线上请求。文章从源码(redis7.0)来看,aof、rdb文件的关闭,aof文件的刷盘以及部分内存释放会采用异步方式,在后台线程中执行。接下来我们看下这些具体的任务以及后台任务的具体实现。
Redis后台任务类型
在源码中的bio.h bio.c文件是redis后台线程任务的实现逻辑,包含以下三类任务:
/* Background job opcodes */
#define BIO_CLOSE_FILE 0 /* Deferred close(2) syscall. */
#define BIO_AOF_FSYNC 1 /* Deferred AOF fsync. */
#define BIO_LAZY_FREE 2 /* Deferred objects freeing. */
#define BIO_NUM_OPS 3
- 关闭文件,包括socket、数据文件的关闭。redis中主要是aof和rdb文件的close。
- 刷盘,内容由内存到磁盘的过程,通常是异步写的,首先会写入page cahe,刷盘就是将修改的数据从page cache同步到磁盘。
- 释放内存。
实现思路
三类异步任务对应三个任务队列,分别不同的函数进行任务提交,任务队列是一个list,每个list对应一个消费线程。
void bioCreateCloseJob(int fd, int need_fsync);
提交异步关闭任务void bioCreateFsyncJob(int fd);
提交异步刷盘任务void bioCreateLazyFreeJob(lazy_free_fn free_fn, int arg_count, ...);
提交异步释放任务
源码分析
初始化
在启动初始化完成后,main函数会调用InitServerLast
做一些系统准备完毕后的其他初始化工作,其中就包括后台线程任务初始化初void bioInit(void);
。
- 初始化每个线程用到的互斥锁、信号量、消费队列(bio_jobs)和队列长度(bio_pending)
- 计算线程栈大小
- 初始化每个线程,线程句柄函数
bioProcessBackgroundJobs
,每个线程会先进行设置名称(redis_set_thread_title)、绑核(redisSetCpuAffinity)、设置信号(pthread_sigmask),然后进入while(1)循环执行。
/* Initialize the background system, spawning the thread. */
void bioInit(void) {pthread_attr_t attr;pthread_t thread;size_t stacksize;int j;/* Initialization of state vars and objects */for (j = 0; j < BIO_NUM_OPS; j++) {pthread_mutex_init(&bio_mutex[j],NULL);pthread_cond_init(&bio_newjob_cond[j],NULL);pthread_cond_init(&bio_step_cond[j],NULL);bio_jobs[j] = listCreate();bio_pending[j] = 0;}/* Set the stack size as by default it may be small in some system */pthread_attr_init(&attr);pthread_attr_getstacksize(&attr,&stacksize);if (!stacksize) stacksize = 1; /* The world is full of Solaris Fixes */while (stacksize < REDIS_THREAD_STACK_SIZE) stacksize *= 2;pthread_attr_setstacksize(&attr, stacksize);/* Ready to spawn our threads. We use the single argument the thread* function accepts in order to pass the job ID the thread is* responsible of. */for (j = 0; j < BIO_NUM_OPS; j++) {void *arg = (void*)(unsigned long) j;if (pthread_create(&thread,&attr,bioProcessBackgroundJobs,arg) != 0) {serverLog(LL_WARNING,"Fatal: Can't initialize Background Jobs.");exit(1);}bio_threads[j] = thread;}
}
线程任务
每个线程的执行的函数都是同一个,在这个函数中根据不同的函数入参进行区别。
- 首先是等待该线程对应的队列非空
- 非空时从任务队列中取出头节点任务 ln->value
- 根据不同的type类型分别执行刷盘、关闭文件、异步释放等操作
- 执行完毕后删除节点。这里有个细节是广播bio_step_cond,是为了释放查询待执行任务数时加的锁(查询进来时,刚好有任务在执行,此时等待这个任务执行完毕)。
while(1) {listNode *ln;/* The loop always starts with the lock hold. */if (listLength(bio_jobs[type]) == 0) {pthread_cond_wait(&bio_newjob_cond[type],&bio_mutex[type]);continue;}/* Pop the job from the queue. */ln = listFirst(bio_jobs[type]);job = ln->value;/* It is now possible to unlock the background system as we know have* a stand alone job structure to process.*/pthread_mutex_unlock(&bio_mutex[type]);/* Process the job accordingly to its type. */if (type == BIO_CLOSE_FILE) {if (job->fd_args.need_fsync) {redis_fsync(job->fd_args.fd);}close(job->fd_args.fd);} else if (type == BIO_AOF_FSYNC) {/* The fd may be closed by main thread and reused for another* socket, pipe, or file. We just ignore these errno because* aof fsync did not really fail. */if (redis_fsync(job->fd_args.fd) == -1 &&errno != EBADF && errno != EINVAL){int last_status;atomicGet(server.aof_bio_fsync_status,last_status);atomicSet(server.aof_bio_fsync_status,C_ERR);atomicSet(server.aof_bio_fsync_errno,errno);if (last_status == C_OK) {serverLog(LL_WARNING,"Fail to fsync the AOF file: %s",strerror(errno));}} else {atomicSet(server.aof_bio_fsync_status,C_OK);}} else if (type == BIO_LAZY_FREE) {job->free_args.free_fn(job->free_args.free_args);} else {serverPanic("Wrong job type in bioProcessBackgroundJobs().");}zfree(job);/* Lock again before reiterating the loop, if there are no longer* jobs to process we'll block again in pthread_cond_wait(). */pthread_mutex_lock(&bio_mutex[type]);listDelNode(bio_jobs[type],ln);bio_pending[type]--;/* Unblock threads blocked on bioWaitStepOfType() if any. */pthread_cond_broadcast(&bio_step_cond[type]);}
提交任务
任务提交比较简单,通过上述三个Create接口实例化一个bio_job 然后追加到对应的list尾部。
bio_job使用了union,对于close和刷盘来说使用fd_args, 对于异步释放来说使用free_args。
typedef union bio_job {/* Job specific arguments.*/struct {int fd; /* Fd for file based background jobs */unsigned need_fsync:1; /* A flag to indicate that a fsync is required before* the file is closed. */} fd_args;struct {lazy_free_fn *free_fn; /* Function that will free the provided arguments */void *free_args[]; /* List of arguments to be passed to the free function */} free_args;
} bio_job;
总结
redis 针对大文件关闭、大内存释放、刷盘这些操作,分别使用对应的后台线程防止其阻塞线上请求,保证线上请求的高性能。其实现方式比较清晰,每种后台任务对应一个链表实现的消费队列和一个后台线程作为消费者,前台请求只需要通过提交函数向队列中追加待执行任务即可。实现清晰、简洁,也有一些细节,例如后台线程要屏蔽 watchdog, 这里不再深究。
相关文章:
Redis后台任务有哪些
Redis后台任务 为了有更好的性能表现,redis对于一些比较耗时的操作会异步执行,不阻塞线上请求。文章从源码(redis7.0)来看,aof、rdb文件的关闭,aof文件的刷盘以及部分内存释放会采用异步方式,在后台线程中执行。接下来…...
TPair<TKey, TValue> 键值对
在 Delphi(或更准确地说是 Object Pascal,Delphi 的编程语言)中,TList<T> 是泛型列表的一个实现,其中 T 是列表中元素的类型。TPair<TKey, TValue> 是一个包含两个元素的记录(record࿰…...
【杂谈】城市规划教育的危与机
城市规划教育的危与机 (赵燕菁 原文为作者在 第21届中国城市规划学科发展论坛上的发言,有删减和改动)如有侵权,立即删除 过去几年,尤其是从2022年后房地产市场的下行开始,中国的城市规划陷入前所未有的危…...
金融工程--pine-script 入门
背景 脚本基本组成 指标 常见的趋势类指标:均线类(MAs)、支撑/压力位(Support/Resistance)、趋势线(Trend Lines)、趋势通道(Trend Channels)、一目均衡表(Ichimoku)和 艾略特波浪(ElliotWave)。 均线指标 策略 策略种类 在TradingView上,有许多交易…...
Vue3 跨标签页或跨窗口通信
在 Vue 应用中,跨标签页或跨窗口的通信通常涉及到两个或多个浏览器标签页之间的信息共享。由于每个标签页或窗口都是独立的 JavaScript 执行环境,它们不能直接通过 Vue 或其他 JavaScript 库来直接相互通信。但是,有一些方法可以实现这种跨标…...
Ollama: 使用Langchain的OllamaFunctions
1. 引言 Function call Langchain的Ollama 的实验性包装器OllamaFunctions,提供与 OpenAI Functions 相同的 API。因为网络的原因,OpenAI Functions不一定能访问,但如果能通过Ollama部署的本地模型实现相关的函数调用,还是有很好…...
java质数的判断 C语言指针变量的使用
1. public static void main(String[] args) {Scanner scnew Scanner(System.in);System.out.println("请输入一个值");int num sc.nextInt();boolean flagtrue;for (int i2;i<num;i){if (num%i0){flagfalse;break;}}if (flag){System.out.println(num"是一…...
TensorFlow面试整理-TensorFlow 数据处理
在 TensorFlow 中,数据处理是构建和训练深度学习模型的重要环节。高效地管理、预处理和增强数据可以显著提高模型的训练效率和性能。TensorFlow 提供了强大的 tf.data API 来帮助处理各种数据集。下面是 TensorFlow 数据处理的详细介绍: 1. tf.data.Dataset API tf.data API …...
vue路由的基本使用
vue路由的基本使用 vue-router简介一、路由配置和使用1、安装2、创建路由实例2、在组件中引用路由 router-view ,如APP根组件中直接引用:3、最后还需要把路由挂载到APP实例中,在main.js中注册路由: 二、路由重定向与别名三、声明式导航1、传统…...
数据结构分类
数据结构(data structure)是计算机存储、组织数据的方式,是带有结构特性的数据元素的集合。是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合。这种“结构”指的是数据元素之间存在的关系,分为逻辑结构和存储…...
【STM32】 TCP/IP通信协议--LwIP介绍
LwIP(Lightweight IP)是一个轻量级的TCP/IP协议栈,专为嵌入式系统设计,以较小的资源消耗实现完整的网络功能。本文将详细介绍LwIP的基本概念、特点、与TCP/IP的区别以及如何在STM32上使用LwIP实现TCP/IP通信。 1. LwIP的定义和设…...
一些面试题整理
第一章、基础 以下是对上述10道面试题的参考答案: 一、Java语言及性能调优 答案: 线程安全问题是指多个线程同时访问共享资源时可能出现的数据不一致或错误的情况。例如,多个线程同时对一个共享变量进行写操作,如果没有适当的同…...
端口号和ip地址一样吗?区别是什么
在网络通信的世界里,端口号和IP地址是两个不可或缺的概念,它们各自扮演着独特的角色,共同维系着数据在网络中的有序传输。然而,对于许多初学者而言,这两者往往容易被混淆,认为它们是同一事物的不同表述。那…...
深入探讨全流量回溯分析与网络性能监控系统
AnaTraf 网络性能监控系统NPM | 全流量回溯分析 | 网络故障排除工具 随着数据量的急剧增加,传统的网络监控手段面临诸多挑战。在此背景下,全流量回溯分析和网络性能监控系统成为了保障网络正常运作的重要工具。本文将围绕这两个关键词,探讨它…...
python机器人编程——一种3D骨架动画逆解算法的启示(上)
目录 一、前言二、fabrik 算法三、python实现结论PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关文章资源 一、前言 我们用blender等3D动画软件时,会用到骨骼的动画,通过逆向IK动力学…...
Flutter开发者必备面试问题与答案02
Flutter开发者必备面试问题与答案02 视频 https://youtu.be/XYSxTb0iA9I https://www.bilibili.com/video/BV1Zk2dYyEBr/ 前言 原文 Flutter 完整面试问题及答案02 本文是 flutter 面试问题的第二讲,高频问答 10 题。 正文 11. PageRoute 是什么? …...
拥抱真实:深度思考之路,行动力的源泉
在纷繁复杂的现代社会,人们往往被表象迷惑,忙碌于各种事务之中,却很少停下来进行深度思考。这种忙碌往往是表面的、无效的,因为它缺乏对自我和目标的深刻理解与追求。提升行动力,避免假勤奋,关键在于深度思…...
【Python爬虫实战】深入理解Python异步编程:从协程基础到高效爬虫实现
#1024程序员节|征文# 🌈个人主页:易辰君-CSDN博客 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、异步 (一)核心概念 (二)…...
OpenCV图像处理方法:腐蚀操作
腐蚀操作 前提 图像数据为二值的(黑/白) 作用 去掉图片中字上的毛刺 显示图片 读取一个图像文件,并在一个窗口中显示它。用户可以查看这个图像,直到按下任意键,然后程序会关闭显示图像的窗口 # cv2是OpenCV库的P…...
PG数据库之流复制详解
一、流复制的定义 PostgreSQL流复制(Streaming Replication)是一种数据复制技术,它允许实时传输数据更改,从而在主服务器和一个或多个备用服务器之间保持数据同步。流复制是PostgreSQL数据库管理系统(DBMS)…...
Python酷库之旅-第三方库Pandas(174)
目录 一、用法精讲 801、pandas.Categorical类 801-1、语法 801-2、参数 801-3、功能 801-4、返回值 801-5、说明 801-6、用法 801-6-1、数据准备 801-6-2、代码示例 801-6-3、结果输出 802、pandas.Categorical.from_codes方法 802-1、语法 802-2、参数 802-3、…...
【Linux网络】基于TCP的全连接队列与文件、套接字、内核之间的关系
W...Y的主页 😊 代码仓库管理💕 前言:之前我们已经学习了TCP传输协议,而无论是TCP还是UDP都是使用socket套接字进行网络传输的,而TCP的socket是比UDP复杂的,当时我们学习TCPsocket编程时使用listen函数进行…...
IDE(集成开发环境)
IDE(集成开发环境)是软件开发过程中不可或缺的工具,它集成了代码编写功能、分析功能、编译器、调试器等开发工具,旨在提高开发效率。不同的IDE支持不同的语言和框架,下面是一些通用的IDE使用技巧和插件推荐,…...
一键导入Excel到阿里云PolarDB-MySQL版
今天,我将分享如何一键导入Excel到阿里云PolarDB-MySQL版数据库。 准备数据 这里,我们准备了一张excel表格如下: 连接到阿里云PolarDB 打开的卢导表,点击新建连接-选择阿里云PolarDB-MySQL版。如果你还没有这个工具,…...
Oracle有哪些版本
目录 Oracle 1(1979年) Oracle 2(1983年) Oracle 7(1992年) Oracle 8i(1999年) Oracle 9i(2001年) Oracle 10g(2004年) Oracle 11g(2007年) Oracle 12c(2013年) Oracle 18c(2018年) Oracle 19c(2019年) Oracle 21c(2023年) Oracle 23ai(202…...
先来先服务(FCFS,First-Come, First-Served)调度算法
有利于CPU繁忙作业的原因 充分利用CPU资源: 当一个CPU繁忙型的作业到达后,它会立即被执行,并且在没有其他作业等待的情况下,可以一直占用CPU直到完成。这使得CPU能够持续地执行作业,最大化利用CPU资源。 减少上下文切换…...
Windows操作系统忘记密码怎么办 这个方法屡试不爽 还不来试一下
Windows操作系统重置密码的操作步骤如下: 本方法适用于Windows Server 2008R2及其之后的操作系统。 第一步:从Windows 2008R2之后的操作系统光盘启动到安装界面,一直下一步到磁盘分区界面,按shiftF10调出cmd命令行界面。 第二步&…...
基于java的山区环境监督管理系统(源码+定制+开发)环境数据可视化、环境数据监测、 环境保护管理 、污染防治监测系统 大数据分析
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
jQuery Mobile 表单输入
jQuery Mobile 表单输入 引言 在移动设备上,表单输入是用户与移动应用交互的重要方式。jQuery Mobile 是一个基于 jQuery 的移动设备友好的开发框架,它提供了丰富的组件和工具来帮助开发者创建响应式和交互式的移动界面。本文将详细介绍如何使用 jQuery Mobile 来创建和定制…...
IoC详解
共有两类注解类型可以实现: 1. 类注解:Controller、Service、Repository、Component、Configuration. 2. 方法注解:Bean. 类注解 Controller(控制器存储) 使⽤Controller存储bean的代码如下所⽰: Con…...
汕头网站制作推荐/下载百度2024最新版
一、概率论基础 (一)概率与直观 (二)常见概率分布 (三)Sigmoid/Logistic函数的引入 二、统计量 (一)期望/方差/协方差/相关系数 (二)独立与不相关 三、大数定…...
电子商务网站建设合同/搜索引擎优化方案
mockjs的简介: 使用mockjs可以事先模拟数据,前提是和后端约定好了数据接口,怎样的数据。使用mock就可以生成你要的数据了,从而实现开发时前后端分离。 其主要功能是: 基于数据模板生成模拟数据。 基于HTML模板生成模…...
如何修改网站后台地址/最新国际新闻50条简短
目录 0 报错内容 1 原因分析 2 解决方法 0 报错内容 建表可以成功,查询映射表的时候报错。具体如下: 1 原因分析 根本原因:hive on hbase 中默认限制字段的字符数是4000 对于4000个字符,hive Metastore中SERDE_PARAMS表中PAR…...
党建类网站如何建设/劳动局免费培训电工
1. 首先下载microsoft installer clean up进行卸载操作。 2. 之后安装可能遇到如下问题:安装Sql Server 2008 R2 企业版出现错误提示无法继续安装,错误提示为: Could not open key: UNKNOWN\Components\7ABFE44842C12B390AF18C3B9B1A1EE8\000…...
淄博网络营销网站/域名批量查询注册
近年来,随着科技的快速发展,人工智能不断进入我们的视野中。作为人工智能的核心技术,机器学习和深度学习也变得越来越火。一时间,它们几乎成为了每个人都在谈论的话题。那么,机器学习和深度学习到底是什么,…...
59网一起做网站/广告公司主要做什么
三个栈实现最大队列 用三个栈 s1 s2 s3 实现队列。 push:在队尾插入一个元素。pop:删除并返回队头元素,若没有元素则返回 -1。max_value:返回整个队列中最大的元素,要求时间复杂度 O(1)O(1)O(1)。 可以直接使用操作…...