나도 할 수 있다는 걸 알아Linux 파일 시스템 캐시의 모든 항목 삭제, 그런데 특정 파일 하나만 삭제하는 방법이 있나요? 아니면 파일이 캐시되지 않도록 하시겠습니까? 아니면 프로세스가 작성한 파일을 캐시하지 않도록 지시하시겠습니까?
많은 작은 파일을 읽고 하나의 큰 파일에 쓰는 프로세스가 있습니다. 디스크 검색을 피하기 위해 작은 파일을 캐시에 보관하고 싶고 큰 파일 캐싱에는 관심이 없습니다.
답변1
잠재적인 방법 #1 - F_DROP_CACHES
나는 이 메일 스레드에서 Linux 커널에 대해 제안된 패치를 논의하는 2012년의 방법을 찾았습니다.Re: [RFC 패치] fs: 파일별 삭제 캐시 구현.
발췌Cong> 파일별 삭제 캐싱을 구현하기 위한 초안 패치입니다.
흥미로운. 그러면 프로세스 외부에서 이 작업을 수행할 수 있나요? 저는 시스템 관리자이므로 시스템이 스트레스를 받을 때 성능 문제를 발견하고 찾아 수정하는 것이 제 관점입니다.
Cong> It introduces a new fcntl command F_DROP_CACHES to drop Cong> file caches of a specific file. The reason is that currently Cong> we only have a system-wide drop caches interface, it could Cong> cause system-wide performance down if we drop all page caches Cong> when we actually want to drop the caches of some huge file.
파일이 얼마나 많은 캐시를 사용하는지 어떻게 알 수 있나요? 사용량이 많은 시스템에서 실행될 때 성능에 어떤 영향을 미치나요? 이 패치는 우리에게 무엇을 가져다 주나요? 시스템에 메모리 압박이 가해지면 VM이 캐싱을 포기했어야 했기 때문입니다.
Cong> 다음은 이번 패치에 대한 작은 테스트 사례입니다.
fs/drop_caches.c
이 스레드에는 를 호출 하는 추가 기능을 추가하는 Linux 커널의 여러 파일에 대한 테스트 사례와 실제 패치가 포함되어 있습니다 . 이 기능은 drop_pagecache_file(struct file *filp)
프런트엔드 도구를 통해 명령을 통해 액세스할 수 있습니다 . 이 예에서는 다음 함수를 호출합니다.fnctl.c
F_DROP_CACHES
file_drop_caches(filp, arg);
특정 파일과 관련된 모든 캐시 삭제를 처리합니다. 문서에서 include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
그러면 이것을 사용할 수 있나요?
이 패치가 주요 Linux 커널 코드 저장소에 포함되었다는 증거를 찾지 못했기 때문에 이 옵션은 Linux 커널을 직접 다시 컴파일하려는 경우에만 사용할 수 있는 것 같습니다.
가능한 접근법 #2 - dd 사용
같은 스레드에서 다른 사용자는 dd
.
시험을 받다이것은 유용한 기능입니다. 아직 제공되지 않았지만
다음은 패치의 예입니다.POSIX_FADV_DONTNEED
? 이 기능은 다음에 추가되었습니다.GNU dd (8.11) 1년 전.
전체 파일의 캐시를 삭제하는 것이 좋습니다
$ dd if=ifile iflag=nocache count=0
전체 파일이 캐시에서 삭제되었는지 확인하십시오.
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
일부 파일의 캐시 삭제
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
미리 읽기 캐시를 사용하여 데이터만 전송
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
이것을 테스트하는 방법을 100% 확신할 수는 없지만 다음 방법을 알아냈습니다.
100MB 파일 만들기
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
파일 액세스 사용량 추적
fatrace
$ sudo fatrace | grep sample.txt
실행
top
하면 메모리 사용량을 모니터링하여 사용 가능한 양을 확인할 수 있습니다.$ top
파일을 열고 현재 사용 가능한 메모리 양을 확인합니다.
fatrace
이 파일을 주의 깊게 살펴보시기 바랍니다sample.txt
.$ cat sample.txt > /dev/null
메모리에서 파일을 삭제하고 현재 사용 가능한 메모리 양을 확인합니다. 출력을 참고하십시오
fatrace
.$ sudo dd of=/home/saml/tst/162600/sample.txt \ oflag=nocache conv=notrunc,fdatasync count=0
예
제1터미널:$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s
$ ls -l sample.txt
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
제2터미널:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
제3터미널:
$ sudo fatrace | grep sample.txt
이제 파일을 열고 sample.txt
RAM 크기를 확인하십시오. 제1터미널에서.
$ cat sample.txt > /dev/null
제2터미널:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
fatrace
터미널 #3의 출력을 참고하세요.
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
이제 터미널 #4의 RAM에서 파일을 삭제합니다.
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
fatrace
터미널 #2의 출력을 참고하세요.
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
터미널 #3의 RAM을 확인하세요.
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
따라서 RAM의 파일이 소비하는 모든 것이 해제된 것처럼 보입니다.
잠재적 접근 방식 #3 - python-fadvise
[pyadvise][4]
@frostchutz의 의견 덕분에 위의 방법보다 더 간단한 인터페이스를 제공하는 Python Script라는 또 다른 도구가 있습니다 dd
. 스크립트는 동일한 posix_fadvise(2)
인터페이스를 사용합니다.
$ sudo pyadvise --help
Usage:
pyadvise [options] [FILE]..
Options:
-h, --help show this help message and exit
-w, --willneed The specified files will be accessed in the near future
-s, --sequential The application expects to access the specified files
sequentially (with lower offsets read before higher ones)
-d, --dontneed The specified files will not be accessed in the near
future
-r, --random The specified files will be accessed in random order
-o, --noreuse The specified files will be accessed only once. Under
Linux, this operation is a no-op; see contrib/copyfileobj-
fadvise.py in the python-fadvise source tree for an
example on how to achieve approximately the same effect
-n, --normal Indicates that the application has no advice to give about
its access pattern for the specified files. If no advice
is given for an open file, this is the default assumption
-v, --verbose Explain what is being done
위의 테스트를 반복하고 pyadvise
다음을 사용 하면 dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
.dd
답변2
O_DIRECT
@geekosaur의 답변을 확장하면 LD_PRELOAD와 여기 절차를 사용하여 강제로 적용할 수 있습니다.http://aighi.blogspot.com/2007/04/how-to-bypass-buffer-cache-in-linux.html
이 코드는 O_DIRECT
모든 파일에 작동합니다. 그러나 strncmp 논리를 더 추가하면 __do_wrap_open
O_DIRECT를 선택적으로 적용할 수 있습니다 .
면책 조항: 나는 이것을 테스트하지 않았습니다.
답변3
이 플래그를 사용하여 단일 파일을 열 수 있습니다 O_DIRECT
( 참조 man 2 open
) — 읽기노트해당 맨페이지 섹션을 주의 깊게 읽고 자신도 원하는지/필요한지 고려하십시오 O_SYNC
.
답변4
파일이 항상 O_SYNC를 사용하도록 하려면 확장 속성에 표시하면 됩니다 chattr +S $file
.
남자 채팅:
"S" 속성이 설정된 파일이 수정되면 변경 사항이 디스크에 동기적으로 기록됩니다. 이는 파일 하위 집합에 적용되는 "동기화" 마운트 옵션과 동일합니다.
O_SYNC는 데이터 + 메타데이터를 강제로 디스크 버퍼에 기록하지만 여전히 페이지 캐시를 통과합니다. O_DIRECT는 페이지 캐싱을 우회합니다.
그러나 O_DIRECT로 열면 성능에 해로운 영향을 미칠 수 있으며, 단지 큰 파일을 추가하는 경우에는 차이가 미미할 수 있습니다. 그러나 대용량 파일을 임의의 위치에 덮어쓰는 경우 O_DIRECT는 캐시에 있다는 점을 고려하더라도 성능에 큰 영향을 미치고 일부 작은 읽기 파일을 캐시에서 제거할 수 있습니다.
작은 파일을 모두 저장할 수 있는 메모리가 있다면 다른 방법으로 이 문제를 해결할 수 있습니다. 작은 파일이 항상 메모리에 있는지 확인한 다음 해당 파일을 다음 위치에 복사하는 것이 좋습니다.임시 파일 시스템:
tmpfs는 모든 것을 내부 커널 캐시에 저장하고 포함된 파일을 수용할 수 있도록 확장 및 축소합니다.