本文指的是源代码版本是
我们经常说redis通常是指正常请求处理周期任务。
实际上,有一些很长时间的操作。REDIS是通过专用线程处理的。这里的特殊主题是我们文章的主角。然后我们低头?
截至目前,Redis具有三个背景线程,即:
与Redis的线程模型一样,我画了一张图片,您可以看到:
为了方便起见,我们将连接相关线程的用户称为主线程,否则背景线程。
换句话说,Redis中当前有两个线程(不谈论REDIS 6.0上出现的IO线程);也就是说,主线程和背景线程。
由于以前的一系列文章引入了许多与主线程相关的内容(如果您不清楚,可以找到它),因此本文将主要引入。
在服务器的最后阶段。
其中,BioInit()是背景线程的初始化。
请注意,这里有一个宏定义:
这意味着背景线程,即总共定义了三个背景线程。
此外,还有几个值得解释的参数:
以上所有数组都通过竞标对应,每个设置都代表另一个线程。
然后,我们看到在创建线程时指定了处理方法。
上一个步骤已创建三个线程,在创建时,指定了一种名为BioProcessbackgroundjobs的处理方法。此方法是三个线程的执行主题。根据(数组出价),选择不同的基础处理逻辑:
此方法逻辑本身并不复杂。激活每个线程后,输入执行主题(此方法),然后在悬挂螺纹或终止服务之前通过无限来处理队列中的事件。
您可能已经认真地发现了它。这是一个典型的模型。主线程负责生产任务事件,然后交付到队列;背景线程是我们的消费者,负责从队列中取出任务事件并进行处理。
在生产者消费者模型中,我们需要注意多线程的关键问题,因此我们使用关键变量(相互数量)来控制并发。
上述代码中的表现是:
如前所述,此处使用了典型的模式。每个背景线程都有其相应的事件列表(队列)。当有事件时,它将发送到相应的背景线程队列,而背景线程(如果相应的线程在SleepStatus中处于休眠状态),然后执行。
我画了一张图片以显示其处理过程,您可以看到:
现在,让我们开始追踪源以查看生产者(主线程)提交任务事件。
首先,Redis是一个典型的事件-Type驱动器框架。信息交换基于事件。因此,任务事件也已包装:
并提供了一种统一创建任务事件BiocreateBackgroundJob的方法:
然后,找到通话方:
可以清楚地看出,有以下几个电话:
1)AOF呼叫:
2)懒惰的删除空间:
3)关闭文件:
大型应用系统的正常操作需要协调多方资源。必须处理网络,磁盘,内存,甚至客户特性的需求。每个模块都有自己的长度。
REDIS中的纯记忆操作通常是和谐的,而不是CPU。我们需要一些其他线程来共享主线程的压力,并在这些模块之间进行一些适应性工作。
因此,要独自处理所有内容,它就变成了奢侈品。在redis中出现了一系列背景线程,例如colled_file,aof_fsync和lazy_free,都可以解决这些问题。
这样的处理方法使主线程可以专注于主业务(客户端请求),从而减少了其担忧!
关闭是一个系统调用,用于关闭打开的文件,TCP插座等。
我们知道REDIS提供了AOF和RDB功能,以及复制等机制,以确保服务高度可用。
当然,在此过程中将有一系列操作,例如数据刷,数据传输和数据重写。其中,将有一个临时文件,并有大量空间职业。此大型临时文档的资源发布非常适合使用特殊线程使用特殊线程使用特殊线程。
这种专用线程在redis中调用,让我们看一下源代码中的位置:
当然,此代码仅在稍后添加,主要是为了更方便的监视。
通常,由于功绩之间的速度差异很大,因此操作系统内核具有(内核缓冲区),并且由系统调用(例如写入)编写的数据暂时存在于缓冲区中。
因此,实际磁盘IO操作是从内核缓冲区读取数据,然后执行真实的刷操作操作;通常,根据系统的核心本身,可以使用它。直接执行数据。
FSONC函数仅适用于文件描述指定的文件,并将其返回到磁盘操作的末尾。fsync可以在数据库等应用程序中使用。该应用程序需要确保修改后的块理解写在磁盘上。
REDIS提供了3种类型,其宏定义如下:
在:
在应用程序中,为了提高这些删除操作的执行速度,通常将删除操作直接设置为null,然后通过单独的操作(线程)分开以释放实际占据的内存空间。
当然,Redis中有一些操作,并且删除大物体的操作是。
可以想象,如果应同时执行删除操作的操作,则整个操作的效率将是多么无法控制。例如,我们需要删除一百万级的哈希词典(GB级),并且必须完全释放空间。这次是一般操作!
同时,在REDIS的实施中,将评估特定命令的丢失,以确定它是选择还是。
例如,对于设置,zset,哈希等,在使用lazy_free之前,元素的数量超过了阈值。
当然,如果指定了命令或命令,则将直接通过惯性清除整个数据库。
值得注意的是,惰性删除也会带来一些问题。有关详细信息,您可以查看此问题#1748
本文主要关注Redis的背景线程,主要分析:
参考: