네트워크 서버 폴더를 모니터링하는 System.IO.FileSystemWatcher - 성능 고려 사항

StackOverflow https://stackoverflow.com/questions/151804

문제

네트워크 서버의 폴더 트리에서 변경 사항을 확인하고 싶습니다.파일은 모두 특정 확장자를 가지고 있습니다.트리에는 폴더가 200개 정도 있고, 제가 보고 있는 확장자를 가진 파일이 1200개 정도 있습니다.

서버에서 실행할 서비스를 작성할 수 없으므로(제한 없음!) 솔루션은 클라이언트에 대해 로컬이어야 합니다.적시성은 특별히 중요하지 않습니다.알림이 1분 이상 지연되는 것을 감수할 수 있습니다.생성, 삭제, 이름 바꾸기 및 변경을 지켜보고 있습니다.

.NET System.IO.fileSystemWatcher를 사용하면 서버에 많은 부하가 발생합니까?

감시되는 폴더/파일 수를 줄이기 위해 별도의 감시자를 10명으로 구성하는 것은 어떻습니까?(700개의 폴더에서 200개, 총 5500개의 파일에서 1200개로 감소) 네트워크 트래픽이 더 적은 대신 더 많습니까?내 생각은 감시된 파일을 1개의 트리 아래에 넣기 위해 서버를 개편하는 것입니다.항상 이 옵션이 있는 것은 아니므로 관찰자 팀이 있습니다.

다른 해결책은 FSW가 서버에 과도한 로드를 생성하는지 또는 여러 가지 SysAdmin 유형의 이유로 작동하지 않는지 정기적으로 확인하는 것이라고 가정합니다.

이를 수행하는 더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

서버 로드 관점에서 볼 때 IO.파일 시스템 감시자 설명하는 시나리오의 원격 변경 알림은 아마도 가장 효율적인 방법일 것입니다.그것은 첫 번째 변경 알림 찾기 그리고 ReadDirectoryChangesW Win32 API는 내부적으로 작동하여 최적화된 방식으로 네트워크 리디렉터와 통신합니다(표준 Windows 네트워킹 가정:타사 리디렉터를 사용하고 필요한 기능을 지원하지 않으면 모든 것이 전혀 작동하지 않습니다..NET 래퍼는 또한 비동기 I/O와 모든 것을 사용하여 최대 효율성을 더욱 보장합니다.

이 솔루션의 유일한 문제점은 그다지 안정적이지 않다는 것입니다.일시적으로 끊어지는 네트워크 연결을 처리해야 하는 것(IO.FileSystemWatcher가 이 경우 처리할 수 있는 오류 이벤트를 발생시키므로 큰 문제는 아님)을 처리하는 것 외에 기본 메커니즘에는 몇 가지 근본적인 제한이 있습니다.Win32 API 함수에 대한 MSDN 설명서에서:

  • ReadDirectoryChangesW 버퍼 길이가 64KB보다 크고 애플리케이션이 네트워크를 통해 디렉터리를 모니터링하는 경우 ERROR_INVALID_PARAMETER로 인해 실패합니다.이는 기본 파일 공유 프로토콜의 패킷 크기 제한으로 인해 발생합니다.

  • 전화 시 알림이 반환되지 않을 수 있습니다. 첫 번째 변경 알림 찾기 원격 파일 시스템의 경우

다시 말해서:부하가 높거나(큰 버퍼가 필요한 경우) 더 나쁘게는 지정되지 않은 무작위 상황에서는 예상한 알림을 받지 못할 수도 있습니다.이는 로컬 파일 시스템 감시자에게도 문제가 되지만 네트워크에서는 훨씬 더 큰 문제입니다. SO에 대한 또 다른 질문 API에 내재된 안정성 문제를 좀 더 자세히 설명합니다.

파일 시스템 감시자를 사용할 때 애플리케이션은 이러한 제한 사항을 처리할 수 있어야 합니다.예를 들어:

  • 찾고 있는 파일에 시퀀스 번호가 있는 경우 알림을 받은 마지막 시퀀스 번호를 저장하면 향후 알림에서 '간격'을 찾아 알림을 받지 못한 파일을 처리할 수 있습니다.

  • 알림을 받으면 항상 전체 디렉터리 검사를 수행하세요.이것은 정말 나쁘게 들릴 수도 있지만 스캔은 이벤트 중심이므로 여전히 멍청한 폴링보다 훨씬 더 효율적입니다.또한 단일 디렉터리에 있는 총 파일 수와 검색할 디렉터리 수를 1,000개 미만으로 유지하는 한 이 작업이 성능에 미치는 영향은 어쨌든 매우 최소화됩니다.

여러 리스너를 설정하는 것은 가능한 한 피해야 하는 것입니다.어쨌든 이렇게 하면 일이 공평하게 될 거야 더 적은 믿을 수 있는...

어쨌든, 만약 당신이 절대적으로 가지다 파일 시스템 감시자를 사용하려면 제한 사항을 알고 있고 수정/생성된 모든 파일에 대해 1:1 알림을 기대하지 않는 한 문제 없이 작동할 수 있습니다.

따라서 다른 옵션이 있는 경우(본질적으로 파일을 작성하는 프로세스가 비파일 시스템 기반 방식으로 알림을 받도록 하는 것입니다.일반적인 RPC 방법은 개선될 것입니다...), 이는 신뢰성 관점에서 확실히 살펴볼 가치가 있습니다.

다른 팁

C#의 파일 시스템 감시자를 여러 번 사용했습니다. 내가 처음으로 사용했을 때, 나는 주로 변화를보고 한 스레드의 변화를 처리하고 있다는 사실 때문에 그들이 일을 멈추는 데 문제가있었습니다.

그러나 이제 변경 사항을 대기열로 밀고 다른 스레드에서 대기열을 처리합니다. 이것은 내가 원래 가지고있는 문제를 해결하는 것 같습니다. 문제의 경우 여러 시청자가 동일한 대기열에 밀어 넣을 수 있습니다.

그러나 나는 당신의 종류의 문제로 이것을 사용하지 않았습니다.

내 경험상 FSW는 높은 네트워크 트래픽을 생성하지 않습니다. 그러나 성능 문제가있는 경우 여러 시청자를 사용하여 폴더가 적은 폴더로 나누는 접근 방식이 합리적으로 들립니다.

네트워크 드라이브에서 FSW에 큰 문제가 있었지만 파일 삭제는 항상 오류 이벤트를 던졌습니다. 솔루션을 찾지 못했기 때문에 주변에 방법이 있으면 FSW를 사용하지 않습니다 ...

그만큼 MSDN 문서가 나타납니다 FileSystemWatcher 구성 요소를 사용하여 네트워크에서 파일 시스템 변경 사항을 볼 수 있습니다. 운전하다.

또한 Watcher 구성 요소는 변경 사항을 대상 드라이브를 주기적으로 심문하는 대신 파일 시스템 변경 알림을 듣는다는 것을 나타냅니다.

네트워크 트래픽의 양은 전적으로 네트워크 드라이브의 내용이 변경 될 것으로 예상되는 양에 달려 있습니다. FSW 구성 요소는 네트워크 트래픽 수준에 추가되지 않습니다.

Watcher는 100% 신뢰할 수 있는 것으로 보입니다. Watcher 개체의 버퍼 크기를 살펴보세요.수천 개의 파일 업데이트를 테스트했는데 손실된 것은 하나도 없습니다.

멀티 스레드 접근 방식을 사용하는 것이 좋습니다. 트리거는 파일 감시자입니다.감지된 각 파일 변경에 대해 스레드를 시작할 수 있습니다.감시자는 오버플로의 가능성이 줄어들면서 훨씬 빠르게 처리 할 수 ​​있습니다.(비동기 스레드 사용)

System.io.filesystemWatcher를 언젠가 사용한 후. 너무 빨리 오는 이벤트를 처리하기에 충분히 안정적이지 않습니다. 파일의 100% 읽기를 보장합니다. 간단한 디렉토리 방법을 사용하여 파일을 검색합니다. 읽은 후 즉시 파일을 다른 폴더로 복사하십시오. 파일을 읽는 동안 추가되는 새 파일에서 격리하려면.

타이머는 폴더를 정기적으로 읽는 데 사용됩니다. 이미 읽은 파일을 아카이브 폴더에 복사하면 다시 읽지 않도록해야합니다. 후속 읽기는 항상 새로운 파일입니다.

var fileNames = Directory.GetFiles(srcFolder);
foreach (string fileName in fileNames)
{
   string[] lines = File.ReadAllLines(fileName);
}

FSW와 컴퓨터가 모니터링되는 컴퓨터 사이에 어떤 종류의 활성 상태 나 통신이 있다고 생각하지 않을 것입니다. 다시 말해, FSW는 파일을 확인하기 위해 네트워크 된 OS를 핑하지 않습니다.

메시지 나 이벤트가 있다고 상상할 것입니다 변경 사항이 발생하면 네트워크 FSW로 올라 오거나 전송됩니다.

그러나 이것은 모두 추측입니다. :)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top