Perl 5.x 문서에는 클러스터링(..) 구현이 다음 기본 호출 중 하나를 사용하며, 사용할 수 없는 경우 1부터 시작하여 3까지 작업한다고 명시되어 있습니다.
- 무리(2)
- FCNTL(2)
- 자물쇠(3)
그것은 중요하지 않습니다. 그러나 여러분은 NFS에서 Flock(2)을 사용해서는 안 된다는 면책 조항을 눈치챘을 것입니다. 문서에서는 -Ud_flock 플래그를 사용하여 Perl이 클러스터링을 사용하도록 권장합니다(2). Flock(2)(Redhat의) 매뉴얼 페이지에는 NFS 문제에 관한 유사한 면책 조항이 나와 있습니다.
내 질문은 왜냐는 것입니다! ! ! NFS에서 클러스터(2)가 안전하지 않은 이유에 대한 자세한 기사나 설명을 찾을 수 없는 것 같습니다.
나는 Redhat(flock(2) 사용)과 Solaris(fcntl(2) 사용)에서 C와 Perl로 여러 테스트 스크립트를 작성했습니다. Perl이 실제로 fancy(2)와 fcntl(2)을 각각 사용하고 있는지 확인하기 위해 strace/truss를 실행했습니다. 잠금이 존중되지 않는 문제는 재현할 수 없습니다! 무엇을 제공합니까? ?
답변1
나는 당신이 유산 문제에 대해 생각하고 있다고 확신합니다. Perl5 매뉴얼은 1994년에 발표되었으며 단순히 1991년 Perl4 매뉴얼을 편집한 것임을 기억하십시오. 그 당시에는 종종 "악몽"이라고 불리는 파일 시스템이 "곰이 얼마나 잘 뛰어오르는가에 관한 것이 아니라, 곰이 얼마나 잘 뛰어오르느냐에 관한 것"이었다고 말할 수도 있습니다. 놀랍지만 춤을 추는 것뿐입니다.”
1991년 NFS2는 Sun에서 천천히 다른 플랫폼으로 옮겨가고 있었고 상대적으로 거칠었습니다. 보안 모델은 본질적으로 존재하지 않으며(클라이언트 시스템의 루트는 NFS 마운트의 전체 내용을 읽을 수 있음) 잠금(nfs.lockd를 통한)은 실험의 이 측면입니다. 클러스터링 의미론이 서로 다른 두 가지 상호 운용 가능한 구현 간에 제대로 작동할 것이라고 기대하는 것은 어리석은 일입니다. Coax는 당시 주요 이더넷 PHY였으며 많은 네트워크 사용자는 이를 사용하면서 불쾌한 경험을 한 적이 없었습니다.
답변2
이것은 이제 더 이상 사용되지 않습니다. NFS4는 잠금을 지원합니다.계약 내에서(lockd 데몬이나 RPC 콜백 메커니즘이 필요하지 않습니다.) 그리고 Perl flock()
접근 방식은 잘 작동합니다. 우리는 이를 프로덕션에서 사용합니다.
매우 오래된 커널 버전 flock
(시스템 호출)은 NFS에서 무작동으로 구현되었으며 바이트 범위 잠금과 같은 다른 기능을 제대로 지원하지 않았습니다. 히스테리는 여기서 비롯됩니다.
답변3
Lennart Poettering은 최근 Linux 파일 시스템 잠금 동작에 대해 심층적인 연구를 수행했지만 NFS 잠금에 대해 특별히 장밋빛 그림을 그리지는 않습니다(특히 그가 게시물 하단에 링크한 후속 작업).
답변4
Linux-NFS FAQ에서 직접 가져온 또 다른 기사: nfs.sf.net
여러 클라이언트에서 사용되는 파일을 잠그기 위해 클러스터()/BSD 잠금을 사용하려고 하는데 파일이 손상되었습니다. 어떻게요? A: Flock()/BSD 잠금은 2.6.12 이전의 Linux NFS 클라이언트에서만 기본적으로 작동합니다. 파일 잠금이 다른 클라이언트에 표시되도록 하려면 fcntl()/POSIX 잠금을 사용하십시오.
NFS 파일에 대한 액세스를 직렬화하는 몇 가지 방법은 다음과 같습니다.
fcntl()/POSIX 잠금 API를 사용합니다. 이 유형의 잠금은 NLM 프로토콜 또는 NFSv4를 통해 여러 클라이언트에 걸쳐 바이트 범위 잠금을 제공합니다. 별도의 잠금 파일을 사용하고 이에 대한 하드 링크를 만듭니다. creat(2) 매뉴얼 페이지의 O_EXCL 섹션에 있는 설명을 참조하십시오. 초기 2.6 커널까지 Linux NFS 클라이언트에서는 O_EXCL 생성이 원자적이지 않았다는 점은 주목할 가치가 있습니다. 2.6.5보다 높은 커널을 실행하지 않는 한 O_EXCL을 사용하여 여러 NFS 클라이언트 간의 원자적 동작을 생성하고 예상하지 마십시오.
기본적으로 Cluster()/BSD 잠금을 사용하는 Perl에는 알려진 문제가 있습니다. 이로 인해 클러스터/BSD 잠금이 POSIX 잠금처럼 작동할 것으로 예상하는 다른 운영 체제(예: Solaris)에서 이식된 프로그램이 중단될 수 있습니다.
Linux에서는 하드 링크 대신 파일 잠금을 사용하면 서버와 클라이언트 캐시 간 검사점을 추가로 얻을 수 있다는 이점이 있습니다. 파일 잠금이 획득되면 클라이언트는 해당 파일에 대한 페이지 캐시를 플러시하여 후속 읽기가 서버에서 새 데이터를 얻을 수 있도록 합니다. 파일 잠금이 해제되면 해당 클라이언트의 파일에 대한 모든 변경 사항은 잠금이 해제되기 전에 서버로 다시 플러시되므로 파일 잠금을 기다리는 다른 클라이언트가 변경 사항을 볼 수 있습니다.
2.6.12의 NFS 클라이언트는 POSIX 바이트 범위 잠금을 기반으로 하는 BSD 스타일 잠금을 에뮬레이션하여 NFS 파일에 대한 클러스터()/BSD 잠금을 지원합니다. 동일한 가장 메커니즘을 사용하거나 fcntl()/POSIX 잠금을 사용하는 다른 NFS 클라이언트에는 Linux NFS 클라이언트에 표시되는 것과 동일한 잠금이 표시됩니다.
기본 Linux 파일 시스템에서는 POSIX 잠금과 BSD 잠금이 서로 표시되지 않습니다. 따라서 이 에뮬레이션으로 인해 Linux NFS 서버에서 실행되는 애플리케이션은 클라이언트의 애플리케이션이 BSD 스타일을 사용하는지 아니면 POSIX를 사용하는지 여부에 관계없이 NFS 클라이언트가 잠근 파일을 fcntl()/POSIX 잠금으로 잠긴 것처럼 계속 처리합니다. 스타일 잠금. 서버 애플리케이션이 Flock() BSD 잠금을 사용하는 경우 NFS 클라이언트가 사용하는 잠금을 볼 수 없습니다.