首页 > 编程知识 正文

hdfs fsck命令,linux查看io高的进程

时间:2023-05-06 16:35:43 阅读:171189 作者:3082

在传统的UNIX实现中,内核中有缓冲区缓存或页缓存,大多数磁盘I/O都是通过缓冲区完成的。 将数据写入文件时,内核通常会将数据复制到缓冲区之一。 如果缓冲区未满,则不将其放入输出队列。 如果写入操作已满,或者内核需要回收缓冲区以存储其他磁盘块数据,则在将缓冲区放入输出队列并到达队列开头之前,不会进行实际的输入/输出操作。 这种输出方式在被称为延迟写入(delayed write )的Bach [1986]第3章中详细讨论缓冲区缓存]。

延迟写入会减少磁盘的读写次数,但会降低文件内容的更新速度,并且在一段时间内不会将写入文件的数据写入磁盘。 如果系统发生故障,此延迟可能会导致文件更新丢失。 为了确保磁盘上实际文件系统和缓冲区缓存中内容的一致性,UNIX系统提供了三个函数: sync、fsync和fdatasync。

sync函数只将所有更改的块缓冲区放入写入队列并返回,而不等待实际的写入磁盘操作完成。

通常称为update的系统守护进程周期性地调用sync函数,通常每30秒调用一次。 这将确保定期冲洗内核的块缓冲区。 命令sync(1)也调用sync函数。

fsync函数只对在文件描述符filedes中指定的一个文件起作用,它将等待写磁盘操作完成,然后返回。 fsync可用于需要确保已更改的块立即写入磁盘的APP应用程序(如数据库)。

fdatasync函数与fsync类似,但只影响文件的数据部分。 除数据外,fsync还同步更新文件属性。

对于支持事务的数据库,要确保事务成功提交并返回到APP应用层,请在提交事务时记录事务日志(事务所做的更改操作和提交记录)

很简单的问题。 *在nix操作系统中,如何将文件更新成功永久保存到硬盘上?

1 .在write不足且需要fsync的情况下,通常对硬盘(或其他持久性存储)文件的write操作仅更新存储器中的页缓存,脏页立即进入硬盘因为当专用的flusher内核线程满足特定条件时)例如以固定的时间间隔,存储器内的write调用在HDD的I/o完成之前不会返回,所以在write调用后,如果操作系统在HDD同步之前崩溃,则数据会丢失write ()提供的“松散异步语义”,适用于需要保证事务持久性和一致性的数据库程序,虽然这样的时间窗口很小操作系统提供的同步io ) )同步io ) )原语必须保证的fsync功能是确保文件软盘上的所有更改都正确同步到硬盘上。 此调用将被阻止,直到设备报告I/o完成。 PS :以内存映射文件方式进行文件IO时(使用mmap,将文件的page cache直接映射到进程的地址空间,通过写入内存对文件进行修改)用同样的系统调用,修改后的内容保存在硬盘上size_t length,int flags ) msync必须指定要同步的地址区间,这种细粒度控制似乎比fsync更有效,但实际上[Linux]kernel具有非常高效的数据结构

2. fsync的性能问题。 除了与fdatasync同步文件的修改内容(脏页)外,fsync还同步文件的描述信息(包括metadata、size、访问)

时间st_atime & st_mtime等等),因为文件的数据和metadata通常存在硬盘的不同地方,因此fsync至少需要两次IO写操作,fsync的man page这样说:

"Unfortunately fsync() will always initialize two write operations : one for the newly written data and another one in order to update the modification time stored in the inode. If the modification time is not a part of the transaction concept fdatasync() can be used to avoid unnecessary inode disk write operations."

多余的一次IO操作,有多么昂贵呢?根据Wikipedia的数据,当前硬盘驱动的平均寻道时间(Average seek time)大约是3~15ms,7200RPM硬盘的平均旋转延迟(Average rotational latency)大约为4ms,因此一次IO操作的耗时大约为10ms左右。这个数字意味着什么?下文还会提到。

 

Posix同样定义了fdatasync,放宽了同步的语义以提高性能:

1 #include <unistd.h>2 int fdatasync(int fd); fdatasync的功能与fsync类似,但是仅仅在必要的情况下才会同步metadata,因此可以减少一次IO写操作。那么,什么是“必要的情况”呢?根据man page中的解释: "fdatasync does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be corretly handled." 举例来说,文件的尺寸(st_size)如果变化,是需要立即同步的,否则OS一旦崩溃,即使文件的数据部分已同步,由于metadata没有同步,依然读不到修改的内容。而最后访问时间(atime)/修改时间(mtime)是不需要每次都同步的,只要应用程序对这两个时间戳没有苛刻的要求,基本无伤大雅。     PS:open时的参数O_SYNC/O_DSYNC有着和fsync/fdatasync类似的语义:使每次write都会阻塞等待硬盘IO完成。(实际上,Linux对O_SYNC/O_DSYNC做了相同处理,没有满足Posix的要求,而是都实现了fdatasync的语义)相对于fsync/fdatasync,这样的设置不够灵活,应该很少使用。     3. 使用fdatasync优化日志同步 文章开头时已提到,为了满足事务要求,数据库的日志文件是常常需要同步IO的。由于需要同步等待硬盘IO完成,所以事务的提交操作常常十分耗时,成为性能的瓶颈。 在Berkeley DB下,如果开启了AUTO_COMMIT(所有独立的写操作自动具有事务语义)并使用默认的同步级别(日志完全同步到硬盘才返回),写一条记录的耗时大约为5~10ms级别,基本和一次IO操作(10ms)的耗时相同。  我们已经知道,在同步上fsync是低效的。但是如果需要使用fdatasync减少对metadata的更新,则需要确保文件的尺寸在write前后没有发生变化。日志文件天生是追加型(append-only)的,总是在不断增大,似乎很难利用好fdatasync。   且看Berkeley DB是怎样处理日志文件的: 1.每个log文件固定为10MB大小,从1开始编号,名称格式为“log.%010d" 2.每次log文件创建时,先写文件的最后1个page,将log文件扩展为10MB大小 3.向log文件中追加记录时,由于文件的尺寸不发生变化,使用fdatasync可以大大优化写log的效率 4.如果一个log文件写满了,则新建一个log文件,也只有一次同步metadata的开销

 


版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。