大佬教程收集整理的这篇文章主要介绍了如何使用 os.posix_fadvise 防止 Linux 上的文件缓存?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个脚本,它通常在整个块设备上运行,如果读取的每个块都被缓存,它将驱逐其他应用程序正在使用的数据。为了防止这种情况发生,我添加了对使用 @H_144_3@mmap(2) 和 posix_fadvise(2) 的支持,逻辑如下:
指示不再需要块的函数:
def advise_dont_need(fd,offset,length):
"""
Announce that data in a particular LOCATIOn is no longer needed.
Arguments:
- fd (int): file descriptor.
- offset (int): Beginning of the unneeded data.
- length (int): Length of the unneeded data.
"""
# Todo: macOS support
if hasattr(os,"posix_fadvise"):
# posix_fadvise(2) states that "If the application requires that data
# be consIDered for discarding,then offset and len must be
# page-aligned." When this code aligns the offset and length,the
# advised area is wIDened under the presumption it is better to discard
# more memory than needed than to leak it which Could cause resource
# issues.
# If the offset is unaligned,extend it toWARD 0 to align it and adjust
# the length to compensate for the change.
aligned_offset = offset - offset % PAGE_SIZE
length += offset - aligned_offset
offset = aligned_offset
# If the length is unaligned,wIDen it to align it.
length -= length % -PAGE_SIZE
os.posix_fadvise(fd,length,os.POSIX_FADV_DONTNEED)
读取文件的逻辑:
with open(path,"rb",buffering=0) as file,\
Progressbar("Reading file") as progress,timer() as read_loop:
size = file_size(filE)
if mmap_file:
# At the time of this wriTing,mmap.mmap in cpython uses
# st_size to determine the size of a file which will not
# work with every file type which is why file size
# autodetection (size=0) cAnnot be used here.
fd = file.fileno()
vIEw = mmap.mmap(fd,size,prot=mmap.pROT_READ)
try:
while writer.error is None and hash_queue.error is None:
# Skip offsets that are already in the block map.
if offset in blocks:
while offset in blocks:
if mmap_file:
advise_dont_need(fd,BLOCK_SIZE)
offset += BLOCK_SIZE
if not mmap_file:
file.seek(offset)
if mmap_file:
block = vIEw[offset:offset + BLOCK_SIZE]
advise_dont_need(fd,len(block))
else:
block = file.read(BLOCK_SIZE)
if not block:
break
bytes_read += len(block)
while hash_queue.error is None:
try:
hash_queue.put((offset,block),timeout=0.1)
offset += len(block)
progress.update(offset / sizE)
break
except queue.Full:
pass
finally:
if mmap_file:
vIEw.close()
当我运行脚本并监控 free -h
的输出时,我可以看到缓冲区缓存使用量增加,尽管有这种逻辑。是我的逻辑不正确,还是 posix_fadvise(2) 就是这样的结果——建议与授权?
以下是一些日志,显示了在 BLOCK_SIZE 设置为 1048576 的脚本执行结束时的长度和偏移量值:
offset=107296587776; length=1048576
offset=107297636352; length=1048576
offset=107298684928; length=1048576
offset=107299733504; length=1048576
offset=107300782080; length=1048576
offset=107301830656; length=1048576
offset=107302879232; length=1048576
offset=107303927808; length=1048576
offset=107304976384; length=0
您的脚本会导致应用程序数据被逐出并不完全准确。 posix_fadvise 的用法也不是这样解释的。 Linux 缓冲区和页面缓存的工作方式比这要复杂一些。
一、术语:
缓冲区缓存 - 用于原始块设备访问,通常在文件系统之外。单位是块。测试这些的好方法是 dd if=/dev/...(在块设备上)of=/dev/null。随着时间的推移多次这样做 (1) 应该会显着减少第二次和以后的时间。
页面缓存 - 用于基于文件系统的访问,单位传统上是完整的页面,由 inode 索引,因此每个文件只维护一个副本。测试这些的好方法是 cp 或 cat 或对大文件的任何访问,同样,随着时间的推移多次(1)应该显示时间减少和页面缓存使用增加(但对于同一文件不超过一次)
Linux 将尝试最大化两个缓存的使用。查看使用情况的常用方法是通过“free(1)”:
[localhost ~]$ free
@R_388_10586@l used free shared buff/cache available
Mem: 3995408 633820 2241896 5820 1119692 3106196
Swap: 2138108 422408 1715700
这里的缓冲区缓存是单独考虑的,不计为“已使用”,因为“已使用”是针对进程的。如果您确实需要进程/应用程序的内存,则优先考虑并清除 buff/缓存。您可以通过对 malloc/memset 执行一个简单的程序并观察缓存大小缩小(到最低限度,即几兆字节)来测试这一点。其他版本的free用来显示+/-缓存,更清晰)
应用程序内存使用:由匿名内存(malloc(3) 等的总和)和文件映射内存(MAP_FILE 上的 mmap(2))组成。但是,后者算作文件缓存内存,而不是应用程序内存。只要此类文件映射内存是干净的(只读或尚未修改),就可以安全地逐出它。但是前者(匿名),如果需要驱逐,只能去swap(因为它没有后备文件)。
您使用的 posix_fadvise(2) 确实是建议。但是如果有足够的空闲内存,你的建议将是无效的——你说你不需要它,但实际上你确实读取了偏移量——所以 Linux 将缓存文件数据:有足够的内存来满足它,你可能最终会再次使用它,那么为什么不缓存它呢?它不应该导致任何匿名内存的驱逐或显着的内存压力 - 如果您的数据在缓存中找到,它会节省几个数量级的时间(保存它会将 I/O 保存到磁盘/闪存,这是 O(1000 +) 时间慢了。
另一种看待这个问题的方式:DONTNEED 的 posix_fadvise 通常是当有一个巨大的文件时,但你说你只会访问它的某些部分,所以你告诉系统 - 不要缓存某些范围我不会使用。一旦您确实使用它们,建议就无关紧要。
顺便说一句,您也可以直接将 madvise(2) 用于 mmap(2) ed 区域,使用 MADV_DONTNEED 等
以上是大佬教程为你收集整理的如何使用 os.posix_fadvise 防止 Linux 上的文件缓存?全部内容,希望文章能够帮你解决如何使用 os.posix_fadvise 防止 Linux 上的文件缓存?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。