파일 캐싱

기본적으로 Windows는 디스크에서 읽거나 디스크에 쓴 파일 데이터를 캐시합니다. 이는 읽기 작업이 실제 디스크가 아닌 시스템 파일 캐시라고 하는 시스템 메모리 영역의 파일 데이터를 읽는 것을 의미합니다. 마찬가지로, 쓰기 작업은 디스크가 아닌 시스템 파일 캐시에 파일 데이터를 쓰며, 이 유형의 캐시를 나중 쓰기 캐시라고 합니다. 캐싱은 파일 개체 단위로 관리됩니다.

캐싱은 캐시 관리자의 지시에 따라 발생하며 Windows 실행되는 동안 지속적으로 작동합니다. 시스템 파일 캐시의 파일 데이터는 운영 체제에 의해 결정되는 간격으로 디스크에 기록되며, 이전에 해당 파일 데이터에서 사용한 메모리가 해제됩니다. 이를 캐시 플러시 라고 합니다. 캐시가 플러시될 때까지 파일에 대한 데이터 쓰기를 지연하고 캐시에 보관하는 정책을 지연 쓰기라고 하며 캐시 관리자가 결정된 시간 간격으로 트리거합니다. 파일 데이터 블록이 플러시되는 시간은 데이터가 캐시에 저장되어 있었던 총 기간과 읽기 작업에서 데이터에 마지막으로 액세스한 이후 경과한 기간을 부분적으로 고려하여 결정됩니다. 이렇게 하면 자주 읽는 파일 데이터는 시스템 파일 캐시에 최대한 오래 남아 있습니다.

이 파일 데이터 캐싱 프로세스는 다음 그림에 나와 있습니다.

file data caching process

이전 그림의 단색 화살표로 표시된 것처럼, 파일 읽기 작업 중 캐시 관리자가 처음 요청할 때 256KB의 데이터 영역이 시스템 주소 공간의 256KB 캐시 "슬롯"으로 읽혀집니다. 그러면 사용자 모드 프로세스에서는 이 슬롯의 데이터를 자체 주소 공간에 복사합니다. 이 프로세스는 데이터 액세스를 마치면 프로세스 주소 공간과 시스템 캐시 사이의 점선 화살표처럼 변경된 데이터를 시스템 캐시의 동일한 슬롯에 다시 기록합니다. 캐시 관리자가 특정 시간 동안 데이터가 더 이상 필요하지 않음을 확인하면 시스템 캐시와 디스크 사이의 점선 화살표에 표시된 것처럼 변경된 데이터를 디스크의 파일에 다시 씁니다.

파일 데이터 캐싱에서 제공하는 I/O 성능 향상의 양은 읽거나 쓰는 파일 데이터 블록의 크기에 따라 달라집니다. 파일 데이터의 큰 블록을 읽고 쓰는 경우 I/O 작업을 완료하려면 디스크 읽기 및 쓰기가 필요할 가능성이 높습니다. 이러한 종류의 I/O 작업이 증가함에 따라 I/O 성능이 점점 더 저하될 것입니다.

이러한 경우 캐싱을 해제할 수 있습니다. 이 작업은 createFiledwFlagsAndAttributes 매개 변수에 대한 값으로 FILE_FLAG_NO_BUFFERING 전달하여 파일이 열릴 때 수행됩니다. 캐싱을 사용하지 않도록 설정하면 모든 읽기 및 쓰기 작업이 실제 디스크에 직접 액세스합니다. 그러나 파일 메타데이터는 여전히 캐시될 수 있습니다. 메타데이터를 디스크에 플러시하려면 FlushFileBuffers 함수를 사용합니다.

플러시가 발생하는 빈도는 시스템 성능과 시스템 안정성의 균형을 맞추는 중요한 고려 사항입니다. 시스템이 캐시를 너무 자주 플러시하는 경우 플러시하는 대규모 쓰기 작업 수가 발생하면 시스템 성능이 크게 저하됩니다. 시스템이 충분히 자주 플러시되지 않으면 시스템 메모리가 캐시에 의해 고갈되거나 갑작스런 시스템 오류(예: 컴퓨터 전원 손실)가 플러시 전에 발생할 가능성이 더 큽니다. 후자의 경우 캐시된 데이터가 손실됩니다.

적절한 양의 플러시가 발생하도록 캐시 관리자는 지연 기록기라는 프로세스를 매초 생성합니다. 지연 기록기 프로세스는 최근에 디스크에 기록되도록 플러시되지 않은 페이지의 8분의 1을 큐에 대기합니다. 최적의 시스템 성능을 위해 플러시되는 데이터의 양을 지속적으로 다시 평가하고, 더 많은 데이터를 작성해야 하는 경우 더 많은 데이터를 큐에 추가합니다. 지연 기록기는 임시 파일을 플러시하지 않습니다. 애플리케이션 또는 시스템에서 삭제할 것이라는 가정이 있기 때문입니다.

바이러스 검사 소프트웨어와 같은 일부 애플리케이션에서는 쓰기 작업을 디스크에 즉시 플러시해야 합니다. Windows 쓰기 캐싱을 통해 이 기능을 제공합니다. 프로세스는 CreateFile에 대한 호출에 FILE_FLAG_WRITE_THROUGH 플래그를 전달하여 특정 I/O 작업에 대한 쓰기 처리 캐싱을 사용하도록 설정합니다. 쓰기 통과 캐싱을 사용하도록 설정하면 데이터는 여전히 캐시에 기록되지만 캐시 관리자는 지연 기록기를 사용하여 지연을 발생시키지 않고 데이터를 디스크에 즉시 씁니다. 또한 프로세스는 FlushFileBuffers 함수를 호출하여 연 파일의 플러시를 강제 적용할 수 있습니다.

파일 시스템 메타데이터는 항상 캐시됩니다. 따라서 메타데이터 변경 내용을 디스크에 저장하려면 파일을 플러시하거나 FILE_FLAG_WRITE_THROUGH 사용하여 열어야 합니다.