暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

聊聊内核的数据同步

429


作者时间QQ技术交流群
perrynzhou@gmail.com2022/01/19672152841


内核中同步、交换、回收简要说明
  • 同步、换出、回收三个操作的最小的单位是以页帧为单位,并且和磁盘文件系统操作紧密相关。比如一些针对文件的page缓存进行修改时候在一定时候需要把数据刷到后端的磁盘文件系统,这过程就是同步;进程的堆、栈、匿名映射区通过交换把这些数据换出到交换文件中,这个就是交换(换出),当这些数据再次需要访问时候,就从交换文件中读取加载到内存中;回收操作涉及到物理页的使用问题,比如一个文件的两个dirty page数据flush到磁盘文件系统后,这个2个page回收到buddy系统已备侯勇。

  • 同步更加注重进程修改文件后,对应文件的page cache被修改,为了保证一致性问题,让page cache中文件数据和磁盘文件系统中相同,用page cache中修改的数据去更新磁盘文件系统文件内容,这个过程就是回写。


内核中dirty page同步机制演变
  • 基于pdflush:pdflush的职责是把内存中的脏页flush到后端的物理磁盘,pdflush的线程数通过/proc/sys/vm/nr_pdflush_threads
    进行调整,通常pdflush线程数在2~8个之间。如果后端出现很多对的物理磁盘,pfliush机制是否存在很严重的锁竞争?其次如果后端磁盘出现大量的IO操作,内存每个物理磁盘对应的数据都更改非常多,对应的内存中脏page达到了一定的阈值,此时pdflush刷新数据到磁盘是否能处理过来?这些问题都值得考虑,因为pflush负责了所有的page cache中的脏页管理。



  • 基于多线程的队列的writeback:linux 3.2开始采用bdi_writeback机制,废弃了pdflush机制采用bid-writeback机制是为每个磁盘创建一个线程,专门负责整个磁盘的脏页的刷新,从而实现每个磁盘的数据刷新到磁盘,可以提高IO的处理性能,在bdi-writeback机制中一个bdi-writeback内核线程和多个flush x:内核线程并发执行。内核中会常驻一个bid-default线程(该线程是有bdi_fork_thread函数负责创建),bdi-default线程负责为每个bdi设备创建flush x:y线程(x:y 对应设备的主设备号/次设备号)。该线程会定时唤醒,检查全局链表中bdi_list队列中是否存在dirty 的page需要刷新到磁盘,如果存在并且flush x:y 线程还没有被创建,则bdi-default负责创建flush x:y线程这对该磁盘数据进行回写;与之对应的bdi-default线程检测某flush x:y 线程长时间处于闲置状态就将其线程销毁。bid_write机制使得每个块设备都分配对应的flush x:y的内核刷脏页线程,使得回写IO流在每个物理磁盘之间独立,从而提高IO的性能



  • 基于cmwq队列的writeback:bdi-writeback机制线程管理是由回写模块自行管理,从linux 3.13开始内核中的cmwq工作队列的并发度非常高,并且性能也很高,bdi-wwriteback机制中不在自己管回写线程,而是统一使用cmwq工作队列里的kworker线程负责回写,基于cmwq工作队列机制中,每个磁盘对应一个线程的流程没有变化,只是负责刷新脏 page到磁盘的的过程发生变化了。




内核中dirty page同步策略
  • 定时方式:这种方式是定时发出回写工作激活回写线程,定时的时间间隔通过/proc/sys/vm/dirtywriteback_centisecs
    ,默认是1/100秒。这种方式并不是每次flush所有的脏页,而是page的变脏时间超过/proc/sys/vm/dirty_expire_centisecs
    的时间的脏页(这个默认是1/100秒).变脏时间是以文件的inode->dirty_when
    为基准。


[perrynzhou@CentOS8-Dev ~]$ uname -r
4.18.0-348.2.1.el8_5.x86_64
[perrynzhou@CentOS8-Dev ~]$ cat /proc/sys/vm/dirty_writeback_centisecs
500
[perrynzhou@CentOS8-Dev ~]$ cat /proc/sys/vm/dirty_expire_centisecs
3000
  • 物理内存不足:当分配物理页帧发现内存不足,这时候并不是flush所有的dirty page,而是每次flush 1024个page到物理磁盘,然后回收内存的page占用空间,直到释放的空闲页满足需求为止.

  • 脏页达到一定比例:当回写脏page过程中,发现脏page占系统内存的比例超过/proc/sys/vm/dirty_background_ratio
    时候,write系统调用会触发回写任务将脏poage回写,直到脏page比例低于/proc/sys/vm/dirty_background_ratio
    ,这个过程中write系统触发后立即返回,会触发后的脏page是由kworker线程
    负责;当内核中脏的page超过系统内存的/proc/sys/vm/dirty_ratio
    时候,write系也会触发将脏page回写到磁盘,这时候write系统调用会阻塞
    ,主动回写脏页,等到kworker
    完成flush脏page到磁盘,直到脏page对于/prc/sys/vm/dirty_ratio


[perrynzhou@CentOS8-Dev ~]$ uname -r
4.18.0-348.2.1.el8_5.x86_64
[perrynzhou@CentOS8-Dev ~]$ cat /proc/sys/vm/dirty_background_ratio
10
[perrynzhou@CentOS8-Dev ~]$ cat /proc/sys/vm/dirty_ratio
30


文章转载自存储内核技术交流,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论