BIO即background I/O service,后台I/O服务,是redis的aof持久化后台服务。
redis把阻塞的同步I/O操作交给后台I/O服务来完成:close和fsync。
close加入BIO的原因
1.如果fd是特定文件描述符的最后一份拷贝,那么文件描述符相关的资源会被释放。
2.如果fd是最后一个引用文件描述符的,并且文件描述符之前已经使用unlink进行删除,那么文件会被删除。
资源释放和文件删除是非常慢的,会阻塞服务器
fsync加入BIO的原因
把内存中修改的文件数据同步到磁盘。调用者将被阻塞至磁盘报告同步完成。
BIO的设计
目前有两种任务:fsync和close。每种任务一个队列和一个线程。
// 存放工作的队列
static list *bio_jobs[REDIS_BIO_NUM_OPS];
// 记录每种类型 job 队列里有多少 job 等待执行
static unsigned long long bio_pending[REDIS_BIO_NUM_OPS];
//初始化后台服务,启动后台线程
void bioInit(void)
//创建后台任务
void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3) 
//处理后台任务,后台线程启动函数
void *bioProcessBackgroundJobs(void *arg)
{
    //当任务数为0的时候,调用pthread_cond_wait等待通知
    //任务数不为0的时候,从队列取任务并处理
        // 执行任务,type即线程启动的入参,每个后台线程处理一种任务
        if (type == REDIS_BIO_CLOSE_FILE) {
            close((long)job->arg1);
        } else if (type == REDIS_BIO_AOF_FSYNC) {
            aof_fsync((long)job->arg1);
        } else {
            redisPanic("Wrong job type in bioProcessBackgroundJobs().");
        }
}
BIO的结构

BIO技术应用和优化
aof有三种持久化方案
1。内核同步,交给内核去缓存的数据到磁盘,大约30s一次。
2.每秒同步,这是作者推荐的同步方案,和内核同步几乎一样快。
3.每次都同步,性能极差,作者都恨不得删掉这个功能。
fsync放在单独线程处理存在的问题
fsync线程的使用和主线程的write存在冲突,在fsync进行的时候,write将被阻塞,fsync期间write不能执行,直到fsync完成。
redis中实现了一种优化
部分代码
void flushAppendOnlyFile(int force) {
    // 策略为每秒 FSYNC 
    if (server.aof_fsync == AOF_FSYNC_EVERYSEC)
        // 是否有 SYNC 正在后台进行?
        sync_in_progress = bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC) != 0;
    // 每秒 fsync ,并且强制写入为假
    if (server.aof_fsync == AOF_FSYNC_EVERYSEC && !force) {
         * 如果后台仍在执行 FSYNC ,那么我们可以延迟写操作一两秒
         * (如果强制执行 write 的话,服务器主线程将阻塞在 write 上面)
         */
        if (sync_in_progress) {
            // 有 fsync 正在后台进行 。。。
             * 如果后台还有 fsync 在执行,并且 write 已经推迟 >= 2 秒
             * 那么执行写操作(write 将被阻塞)
             */
    //write写入缓冲区
    nwritten = write(server.aof_fd,server.aof_buf,sdslen(server.aof_buf));
优化方案
当aof同步方式为每秒同步时,主线程的write进行优化,如果执行write时fsync服务正在同步中,那么推迟write的时间,最多推迟两秒,如果等待两秒后fsync仍在同步,执行强制write操作,主线程将阻塞等待write完成。
fsync服务线程和bgsave以及bgrewriteaof子进程的冲突
这时候不应该执行fsync
    if (server.aof_no_fsync_on_rewrite &&
        (server.aof_child_pid != -1 || server.rdb_child_pid != -1))
            return;
作者关于fsync服务线程的博客

redis BIO详解的更多相关文章

  1. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  2. CentOS7/RHEL7安装Redis步骤详解

    CentOS7/RHEL7安装Redis步骤详解 CentOS7/RHEL7安装Redis还是头一次测试安装了,因为centos7升级之后与centos6有比较大的区别了,下面我们就一起来看看Cent ...

  3. Redis协议详解

    smark Beetle可靠.高性能的.Net Socket Tcp通讯组件 支持flash amf3,protobuf,Silverlight,windows phone Redis协议详解 由于前 ...

  4. Redis学习——详解Redis配置文件(三)

    一.Redis脚本简介 在我们介绍Redis的配置文件之前,我们先来说一下Redis安装完成后生成的几个可执行文件: redis-server .redis-cli .redis-benchmark ...

  5. Redis:默认配置文件redis.conf详解

    转: Redis:默认配置文件redis.conf详解 # Redis配置文件样例 # Note on units: when memory size is needed, it is possibl ...

  6. Python操作redis学习系列之(集合)set,redis set详解 (六)

    # -*- coding: utf-8 -*- import redis r = redis.Redis(host=") 1. Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合 ...

  7. Redis配置文件redis.conf详解

    一.Redis配置文件redis.conf详解 # Note on units: when memory size is needed, it is possible to specifiy # it ...

  8. [转]使用python来操作redis用法详解

    转自:使用python来操作redis用法详解 class CommRedisBase(): def __init__(self): REDIS_CONF = {} connection_pool = ...

  9. linux离线部署redis及redis.conf详解

    一.离线部署redis 由于博主部署的虚拟机没有网络也没有gcc编译器,所以就寻找具备gcc编译器的编译环境把redis编译安装好,Copy Redis安装目录文件夹到目标虚拟机的目录下.copy时r ...

随机推荐

  1. 01 c++常见面试题总结

    https://www.cnblogs.com/yjd_hycf_space/p/7495640.html   C++常见的面试题 http://c.tedu.cn/workplace/217749. ...

  2. nyoj112-指数运算

    指数运算时间限制:600 ms  |  内存限制:65535 KB难度:2描述写一个程序实现指数运算 X^N.(1<X<10,0<N<20)输入输入包含多行数据 每行数据是两个 ...

  3. [Ynoi2015]此时此刻的光辉

    题目大意: 给定一个序列,每次询问一段区间的数的乘积的约数个数. 解题思路: 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐 ...

  4. elementUI 图片上传限制上传图片的宽高

    文件上传,需当上传的文件类型为图片的时候,需要限制图片的宽高. 此处采用了new Promise异步加载的方式,等图片上传加载完成后, 页面代码: <el-form-item label=&qu ...

  5. eclipsephp的环境设置

    因需要研究开发opencart的插件模块,需要一套开发php的环境.这类程序就环境配置就够折腾吐血.自认为最简单的方法: 1.下载easyphp安装,这个玩意简单快捷傻瓜.米是5.38: 2.去ecl ...

  6. 【*2000】【2018-2019 ICPC, NEERC, Southern Subregional Contest C 】Cloud Computing

    [链接] 我是链接,点我呀:) [题意] [题解] 我们可以很容易知道区间的每个位置有哪些安排可以用. 显然 我们优先用那些花费的钱比较少的租用cpu方案. 但一个方案可供租用的cpu有限. 我们可以 ...

  7. 转载 - 跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题

    出处:http://www.cnblogs.com/grenet/p/3145800.html 精确覆盖问题的定义:给定一个由0-1组成的矩阵,是否能找到一个行的集合,使得集合中每一列都恰好包含一个1 ...

  8. UVA The Tower of Babylon

    The Tower of Babylon Perhaps you have heard of the legend of the Tower of Babylon. Nowadays many det ...

  9. 基于Dynamic Proxy技术的方法AOP拦截器开发

    在面向对象编程中,会用到大量的类,并且会多次调用类中的方法.有时可能需要对这些方法的调用进行一些控制.如在权限管理中,一些用户没有执行某些方法的权限.又如在日志系统中,在某个方法执行完后,将其执行的结 ...

  10. spring之注解(一)概述

    Spring的核心是依赖注入(DI),而依赖注入的基础是依赖信息的配置.这些配置称之为元数据. 在之前的的学习中.一直採用的是基于xml的配置,这些元数据配置在spring内部被注冊成为BeanDef ...