Linux 파일 시스템 캐시에서 특정 파일을 삭제 하시겠습니까?


23

Linux 파일 시스템 캐시에서 모든 것을 삭제할 수 있지만 특정 파일을 하나만 삭제하는 방법이 있습니까? 아니면 파일이 캐시되는 것을 방지합니까? 아니면 프로세스가 작성하는 파일을 캐시하지 않도록 지시합니까?

작은 파일을 많이 읽고 큰 파일을 쓰는 프로세스가 있습니다. 디스크 검색을 피하기 위해 작은 파일을 캐시에 보관하고 싶습니다. 큰 파일을 캐싱하는 데 신경 쓰지 않습니다.


1
현상금과 관련하여 제목 질문에 특히 관심 이 있습니다. 처음에 파일 을 가져 오는 것을 방지하는 대신 캐시에서 특정 파일을 삭제합니다 .
Gilles 'SO- 악마 그만해

답변:


21

잠재적 인 방법 # 1-F_DROP_CACHES

이 메일 스레드에서 Re : [RFC Patch] fs : implement per-file drop caches 라는 제목의 Linux 커널에 대해 제안 된 방법을 2012 년부터 발견했습니다 .

발췌

Cong> 이것은 파일 당 삭제 캐시를 구현하는 초안 패치입니다.

흥미 롭군 프로세스 외부에서이 작업을 수행 할 수 있습니까? 저는 SysAdmin이므로 POV는 시스템에 압력이 가해 졌을 때 성능 문제를 발견하고 수정하는 데 있습니다.

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> 아래는이 패치에 대한 작은 테스트 사례입니다.

이 스레드에는 Linux 커널 내의 여러 파일에 대한 테스트 케이스와 실제 패치가 모두 포함되어 있으며 fs/drop_caches.c라는 추가 기능을 추가합니다 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않습니까? 이 기능은 1 년 전에 GNU dd (8.11) 에 추가되었습니다 .

해당 패치의 예는 다음과 같습니다.
  • 전체 파일에 대해 캐시를 삭제하도록 조언

     $ 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 % 긍정적이지 않았지만 다음과 같은 접근법을 생각해 냈습니다.

  1. 100MB 파일 만들기

    $ dd if=/dev/urandom of=sample.txt bs=100M count=1
    
  2. 다음을 사용하여 파일 액세스 추적 fatrace

    $ sudo fatrace | grep sample.txt
    
  3. 실행 top우리는 메모리 사용량, 무료 노트 양을 모니터링 할 수 있습니다.

    $ top
    
  4. 파일을 열고 사용 가능한 메모리 양을 확인하십시오. fatrace파일에 유의 하십시오 sample.txt.

    $ cat sample.txt > /dev/null
    
  5. 메모리에서 파일을 삭제하십시오. 이제 사용 가능한 메모리 양을 확인하십시오. 의 출력에 유의하십시오 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.txtRAM 크기를 확인하십시오. 터미널 # 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

@frostchutz의 의견 덕분에 [pyadvise][4]위의 dd방법 보다 훨씬 간단한 인터페이스를 제공하는 Python 스크립트라는 또 다른 도구가 있습니다. 이 스크립트는 동일한 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

내가 사용했던 이전과 동일하게 사용되는 RAM의 감소가 나타났습니다 dd.


dd나를 위해 작동합니다. 나는 더 명백한 명령에서 똑같은 chris-lamb.co.uk/projects/python-fadvise로 끝났습니다 .
frostschutz

@frostschutz-매우 시원합니다. Gilles가 채팅에서이 작업을 수행하는 방법을 아는 사람이 있는지 물을 때까지 나는 이것을 듣지 못했습니다. python-fadvise훨씬 쉽다는 것을 보여주는 예제를 추가했습니다 dd.
slm

파이썬 스크립트에 대한 링크는 질문의 본문으로 이동해야합니다. 주석은 추적없이 사라질 수 있습니다. 최악의 편집 내용은 여전히 ​​기록에 남아 있습니다. 그러나 Google 검색은 쉽게 찾을 수 있으므로 큰 도움이되지 않습니다.
Faheem Mitha

심지어 sudo없이 작동하는 것처럼 보이므로 파일을 볼 수있는 사람 (쓰기 권한이 없어도)은 캐시를 삭제할 수 있습니다. 흥미로운 일입니다.
frostschutz

1
os.posix_fadvise()지금은 파이썬의 표준 libray에.
kawing-chiu


2

O_DIRECT플래그를 사용하여 개별 파일을 열 수 있습니다 (참조 man 2 open) — 해당 맨 페이지 의 참고 섹션을주의 깊게 읽고 원하는지 여부도 고려하십시오 O_SYNC.


1
글쎄, 내 프로세스는 cat이며 오히려 다시 쓰지 않을 것입니다. :) 명령 줄 도구 나 /proc/sys손잡이를 원했습니다.
Jay Hacker

2
그보다 더 나쁜 것은, 당신이 정말로 리디렉션을 사용하고 있다는 것을 의미한다고 생각하므로 프로세스는 쉘입니다. 나는 open플래그를 제외하고 이것을 제어하는 ​​파일 당 방법을 모른다 . 실제로 프로그램을 작성해야합니다. ( OS 버퍼링이 아닌 버퍼링 cat -u만 비활성화합니다 stdio.)
geekosaur

-2

파일이 항상 O_SYNC를 사용하도록하려면 확장 된 속성에서 파일을 다음과 같이 표시 할 수 있습니다 chattr +S $file.

남자 chattr :

'S'속성이 설정된 파일이 수정되면 변경 사항이 디스크에 동 기적으로 기록됩니다. 이는 파일의 서브 세트에 적용되는 'sync'마운트 옵션과 동일합니다.

O_SYNC는 data + metadata를 디스크 버퍼에 기록하지만 여전히 페이지 캐시를 통과합니다. O_DIRECT는 페이지 캐시를 무시합니다.

그러나 O_DIRECT로 파일을 여는 것은 성능에 해를 끼칠 수 있습니다. 큰 파일이 추가되면 차이가 작을 수 있습니다. 그러나 큰 파일이 임의의 위치에 다시 쓰여지면 O_DIRECT는 캐시에 파일이 있으면 작은 읽기 파일 중 일부를 캐시에서 제거 할 수 있다는 점을 고려하더라도 성능에 큰 타격을 줄 것입니다.

작은 파일을 모두 보관하는 램이 있다면 다른 방법으로 문제에 접근 할 수 있습니다. 작은 파일이 항상 램에 있는지 확인한 다음 tmpfs 에 복사하는 것이 좋습니다 .

tmpfs는 커널 내부 캐시에 모든 것을 넣고 포함 된 파일을 수용하기 위해 커지거나 줄어 듭니다.


chattr +S같은 것이 아니다 O_DIRECT, 그것은 같은 것입니다 O_SYNC. O_DIRECT원인은 읽기 ,없이 보장, 버퍼링되지 쓰기 (이 질문에 대해 무엇이다) 캐시 할 수 없습니다. 쓰기O_SYNC 만 버퍼링하지 않습니다.
Gilles 'SO- 악마 그만해

@Gilles 맞습니다. 질문을 읽고 이전에했던 것처럼 디스크로 데이터를 플러시하는 것에 대해 생각했습니다. 또 다른 미묘하지만이 경우 O_DIRECT와 O_SYNC의 차이점은 중요합니다 .O_DIRECT는 페이지 캐시를 무시하지만 O_SYNC는 데이터와 메타 데이터를 강제로 디스크로 플러시하지만 페이지 캐시와 읽기 속도를 높이기 위해 유지됩니다. 잘못된 확인을 유지하지 않도록 답변에서 O_SYNC에 대한 O_DIRECT를 변경해야합니까?
Jorge Nerín

이 질문은 캐시에서 작성된 큰 파일을 유지하는 방법에 대해 묻습니다. O_DIRECT로 파일을 여는 것이 성능에 해를 끼칠 것이라고 생각하고 큰 파일이 추가되면 차이가 작을 수 있습니다. 그러나 큰 파일이 임의의 장소에서 다시 쓰여지면 O_DIRECT는 작은 읽기 파일 중 일부를 캐시에서 제거 할 수 있다는 점을 고려하더라도 성능에 큰 타격을 줄 것입니다.
Jorge Nerín

변경 O_DIRECT하는 O_SYNC당신의 대답은 내부적으로 일관성 만들 것,하지만 여전히 잘못된 질문을 고려.
Gilles 'SO- 악마 중지
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.