다른 시스템에서 파일(때때로 특정 크기)을 쓰는 NFS 마운트가 있고 이제 새 파일을 폴링하고 있습니다. 스크립트를 사용하여 파일을 처리하려면 파일이 완전히 완료될 때까지 기다려야 합니다. 나는 이러한 파일이나 이름을 쓰는 과정을 통제하지 않습니다.
fusionr 및 lsof가 내 로컬 시스템을 검사하는 것 같지만 다른 시스템이 NFS 마운트에 쓰는 경우 이를 올바르게 처리하지 않습니다. v3인 경우 파일 이벤트를 들을 수 있다고 믿지 않으며(그러나 v4도 들을 수 있습니까?) 파일 크기가 더 이상 커지지 않을 때까지 잠시 기다릴 필요가 없습니다(그리고 네트워크가 확장되지 않기를 기도합니다). 틀렸음), 그렇게 할 수 있는 방법이 있는지 모르겠습니다. 로컬에서 파일 핸들을 찾는 것처럼 무결성이 보장됩니다. 해결책이 있나요? 그렇지 않다면 NFSv4에 대한 솔루션이 있습니까?
답변1
nfsv3은 상태 비저장이므로 해당 상태를 보장할 방법이 없습니다. 하지만 NLM(Network Lockout Manager)이 양쪽에서 실행되고 있어야 합니다.
nfsv4에는 잠금 작업 열기/읽기/쓰기/잠금/닫기가 있으며 OPEN CLOSE 상태를 유지합니다. 가능하면 nfsv4로 변경해야 합니다.
답변2
이상적인 솔루션은 보낸 사람이 .tmp
임시 접미사( )를 사용하여 파일을 NFS 공유에 배치하고 복사가 완료된 후에만 이름을 바꾸는 것입니다.
# Sender
# There are better ways of writing this code; it's just an illustration
#
if cp /from/source/data.xml /to/nfs/share/data.xml.tmp
then
# copy succeeded; rename
mv -f /to/nfs/share/data.xml.tmp /to/nfs/share/data.xml
fi
NFS에서도 이름 바꾸기는 원자적으로 이루어지므로 수신자가 접미사가 붙은 파일을 무시하는 한 .tmp
다른 모든 파일( data.xml
이 예에서는)은 수신자에게 즉시 NFS 공유에 완전히 표시됩니다.
그러나 불행하게도 당신은 발신자를 통제할 수 없다고 설명합니다.
이 경우 파일이 완전히 전송되었는지 보장하기 위해 실제로 수행할 수 있는 작업은 많지 않습니다. 다양한 옵션에는 데이터에서 END 태그(전송되는 데이터에 특정한 태그, 리터럴 "END" 문자열일 필요는 없음) 찾기 또는 파일을 처리하기 전에 파일 구문 분석 시도가 포함됩니다. 다음은 XML 파일을 확인하는 예입니다.
# XML validation
if xmlstarlet validate /to/nfs/share/data.xml
then
# An XML file validated so it must be complete
...
fi
몇 분 동안 변경되지 않은 파일만 고려하는 메서드에 이것을 추가하면 작동하는 솔루션을 얻을 수 있습니다.
find /to/nfs/share -type f -mmin +5 -name '*.xml' -print0 |
while IFS= read -d '' file
do
if validate-the-file "$file"
then
process-the-file "$file"
rm -f "$file"
fi
done
또는
find /to/nfs/share -type f -mmin +5 -name '*.xml' -exec sh -c '
for file in "$@"
do
process-the-file "$file"
rm -f "$file"
done
' _ {} +