[IO系统]10 缓存写回机制

       Linux IO系统的脏页写入的到磁盘,主要由以下情况来触发:

1. 内存不足或内存空间紧张,需要通过回写脏页来回收内存;

2. 脏页已经更新了较长时间,时间上已经到了临界值,需要及时回写保持内存和磁盘上数据一致性;

3. 第三方英语或命令主动触发脏页回刷到磁盘;

4. write操作时balance回写要求。

 

1.1   脏页太多,强制回刷

       当linux系统内存压力就大时,就会对系统的每个压力大的zone进程内存回收,内存回收主要是针对匿名页和文件页进行的。

       在page cache创建过程,经常使用free_more_memory函数调用wakeup_flusher_threads来唤醒回写线程进行内存回收。

/*
 * Kick thewriteback threads then try to free up some ZONE_NORMAL memory.
 */
static void free_more_memory(void)
{
    structzone *zone;
    int nid;
    /* 启动回刷线程,要求至少回收1024个page,回收原因 Freemore memory */
    wakeup_flusher_threads(1024,WB_REASON_FREE_MORE_MEM);
    yield();
     /* 遍历node,尝试通过直接回收page来达到要求 */
    for_each_online_node(nid){
        (void)first_zones_zonelist(node_zonelist(nid,GFP_NOFS),
                        gfp_zone(GFP_NOFS),NULL,
                        &zone);
        if(zone)
            try_to_free_pages(node_zonelist(nid,GFP_NOFS), 0,
                        GFP_NOFS,NULL);
    }
}

 

1.2     定时回写

       内核在启动的时候会进行页回写机制初始化:start_kernel-> page_writeback_init,在page_writeback_init初始化dom->period_timer定时器:

void __init page_writeback_init(void)
{
    BUG_ON(wb_domain_init(&global_wb_domain,GFP_KERNEL));
 
    writeback_set_ratelimit();
    register_cpu_notifier(&ratelimit_nb);
}

       超时时间是dirty_writeback_centisecs,单位是0.01秒,可以通过/proc/sys/vm/dirty_writeback_centisecs调节。wb_timer的触发函数是wb_timer_fn,最终是通过wb_workfn实现。

 

1.3     主动触发回写

       外界触发式,主要是调用sync等函数,来触发实现。参考文档《linux 同步IO: syncfsyncfdatasync

主要调用

static int __sync_filesystem(struct super_block*sb, int wait)
{
    if (wait)
        sync_inodes_sb(sb);
    else
        writeback_inodes_sb(sb,WB_REASON_SYNC); /* writeback回写机制 */
 
    if(sb->s_op->sync_fs)
        sb->s_op->sync_fs(sb,wait);
    return__sync_blockdev(sb->s_bdev, wait);
}
 

1.4     读写状态检查触发回写

       用户态使用WRITE函数写文件时也有可能要刷新脏页,generic_perform_write函数会在将写的内存页标记为脏之后,根据条件刷新磁盘以平衡当前脏页比率,参看balance_dirty_pages_ratelimited函数。

       balance_dirty_pages_ratelimited函数通过ratelimit_pages调节刷新(调用balance_dirty_pages函数)的次数,每ratelimit_pages次调用才会刷新一次,具体刷新过程看balance_dirty_pages函数。

       balance_dirty_page函数走进一个死循环,通过get_dirty_limits获取dirty_background_ratio和dirty_ratio对应的内存页数值,判断,如果脏页大于dirty_thresh,则调用writeback_inodes开始刷缓存到磁盘,如果一次没有将脏页比率刷到dirty_ratio之下,则用blk_congestion_wait阻塞写,然后反复循环,直到比率降低到dirty_ratio;当比率低于dirty_ratio之后,但脏页比率大于dirty_background_ratio,则用pdflush_operation启用background_writeout,pdflush_operation是非阻塞函数,唤醒pdflush后直接返回,background_writeout在有pdflush调用。

       如此可知:WRITE写的时候,缓存超过dirty_ratio,则会阻塞写操作,回刷脏页,直到缓存低于dirty_ratio;如果缓存高于background_writeout,则会在写操作时,唤醒回写进程刷脏页,不阻塞写操作。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux 缓存机制是指Linux操作系统文件系统和磁盘I/O进行缓存的一种机制。它通过将磁盘上的数据缓存在内存中,加快访问速度,提高系统性能。 Linux缓存机制主要有以下几个方面: 1. 页面缓存(Page Cache):Linux使用页面缓存来加速对文件的读取和写入。当应用程序读取文件时,文件的内容会被缓存在页面缓存中,下次再读取相同的文件时,可以直接从缓存中获取数据,避免了频繁的磁盘访问。对于写入操作,页面缓存会将数据暂时保存在内存中,延迟写入磁盘,提高写入效率。 2. 直接IO(Direct IO):直接IO是一种绕过页面缓存直接进行磁盘读写的方式。当应用程序使用直接IO进行数据读写时,数据不会被缓存在页面缓存中,而是直接读写磁盘。直接IO适用于对大文件进行随机访问或者需要避免页面缓存带来的性能开销的场景。 3. 写回Write-back)和写入(Write-through):Linux的页面缓存采用写回和写入两种方式来处理数据的写入。写回方式表示数据先被写入页面缓存,然后再由操作系统决定何时将数据写入磁盘;写入方式表示数据同时被写入页面缓存和磁盘。写回方式可以提高写入性能,但也增加了数据丢失的风险。 4. 文件同步(File Sync):Linux提供了sync命令和fsync系统调用来进行文件同步操作。文件同步会强制将页面缓存中的数据立即写入磁盘,确保数据的持久化存储。文件同步可以用于保证数据的一致性,但也会带来性能上的开销。 总之,Linux的缓存机制通过使用页面缓存、直接IO写回等方式,提高了文件系统和磁盘I/O的性能,并在性能和数据一致性方面做出了权衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoungerChina

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值