파일 캐싱

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

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

다음 그림에서는 이 파일 데이터 캐싱 프로세스를 보여 줍니다.

파일 데이터 캐싱 프로세스

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

파일 데이터 캐싱이 제공하는 I/O 성능 향상 정도는 읽거나 쓰는 파일 데이터 블록의 크기에 따라 달라집니다. 큰 파일 데이터 블록을 읽고 쓰는 경우 I/O 작업을 완료하기 위해 디스크 읽기 및 쓰기가 필요할 가능성이 높습니다. 이러한 종류의 I/O 작업이 많아질수록 I/O 성능이 점점 더 손상될 것입니다.

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

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

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

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

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