문제

저는 때때로 결과를 내놓는 매우 계산 집약적인 과학 작업을 수행하고 있습니다.이 작업은 기본적으로 동일한 것을 여러 번 시뮬레이션하는 것이므로 서로 다른 OS를 사용하는 여러 컴퓨터에 나누어집니다.모든 컴퓨터가 NFS/Samba를 통해 동일한 파일 시스템을 볼 수 있으므로 이러한 모든 인스턴스의 출력을 동일한 파일로 지정하고 싶습니다.제약 조건은 다음과 같습니다.

  1. 안전한 동시 추가를 허용해야 합니다.다른 컴퓨터의 다른 인스턴스가 현재 파일에 추가되는 경우 차단해야 합니다.
  2. 성능은 ~ 아니다 세다.각 인스턴스의 I/O는 분당 몇 바이트에 불과합니다.
  3. 단순함이 중요합니다.이것의 요점은 (순수한 호기심 외에도) 모든 인스턴스가 다른 파일에 기록하고 수동으로 이러한 파일을 병합하는 것을 중단할 수 있다는 것입니다.
  4. 파일 시스템의 세부 사항에 의존해서는 안 됩니다.NFS 또는 Samba 마운트에서 알 수 없는 파일 시스템으로 작업해야 합니다.

중요한 경우를 대비해 내가 사용하는 언어는 D입니다.제가 살펴보니 표준 라이브러리에는 이런 일을 하는 것 같은 것이 아무것도 없습니다.D 관련 답변과 일반 언어에 구애받지 않는 답변 모두 완전히 수용 가능하고 높이 평가됩니다.

도움이 되었습니까?

해결책

NFS를 통해 클라이언트 측 캐싱 및 오래된 데이터에 문제가 있습니다. 이전에 NFS를 통해 작동하기 위해 OS 독립 잠금 모듈을 작성했습니다. [datafile] .lock 파일을 작성한다는 간단한 아이디어는 NFS보다 잘 작동하지 않습니다. 그 주변에서 작업해야 할 기본 아이디어는 잠금 파일 [datafile] .lock을 생성하는 것입니다. 호스트 이름]. [PID]. 이름 변경은 NFS보다 충분히 작동하여 잠금의 독점 성을 보장하는 원자 충분한 작업입니다. 나머지는 기본적으로 잠금을 풀고 잠금 파일을 [datafile] .lock으로 다시 바꾸기 전에 프로세스가 사라지는 경우의 실패 안전, 루프, 오류 확인 및 잠금 검색입니다.

다른 팁

전형적인 솔루션은 잠금 파일 또는 더 정확하게 잠금 디렉토리를 사용하는 것입니다. 모든 일반적인 OSS에서 디렉토리를 만드는 것은 원자 연산이므로 루틴은 다음과 같습니다.

  • 고정 된 위치에 고정 이름이있는 잠금 디렉토리를 작성하십시오.
  • 생성이 실패하면 잠깐만 기다렸다가 다시 시도하십시오 - 성공할 때까지 반복하십시오.
  • 실제 데이터 파일에 데이터를 작성하십시오
  • 잠금 디렉토리를 삭제합니다

이것은 많은 플랫폼에서 수년간 CVS와 같은 응용 프로그램에서 사용되었습니다. 유일한 문제는 앱이 쓰기 중 및 잠금을 제거하기 전에 충돌하는 드문 경우에 발생합니다.

파일과 다른 컴퓨터 사이에있는 간단한 서버를 구축하지 않겠습니까?

그런 다음 데이터 형식을 변경하려면 모든 클라이언트가 아니라 서버 만 수정하면됩니다.

제 생각에는 서버를 구축하는 것이 네트워크 파일 시스템을 사용하는 것보다 훨씬 쉽습니다.

트위스트를 사용하여 파일 잠금

다른 답변에서 언급했듯이 가장 쉬운 방법은 데이터 파일과 동일한 디렉터리에 잠금 파일을 만드는 것입니다.

여러 PC에서 동일한 파일에 액세스할 수 있기를 원하기 때문에 제가 생각할 수 있는 가장 좋은 솔루션은 현재 데이터 파일에 쓰고 있는 컴퓨터의 식별자를 포함하는 것입니다.

따라서 데이터 파일에 쓰는 순서는 다음과 같습니다.

  1. 잠금 파일이 있는지 확인하세요.

  2. 잠금 파일이 있는 경우 해당 콘텐츠에 내 식별자가 있는지 확인하여 내가 그 파일을 소유하고 있는지 확인하세요.
    그렇다면 데이터 파일에 쓴 다음 잠금 파일을 삭제하십시오.
    그렇지 않은 경우에는 잠시 또는 임의의 짧은 시간 동안 기다렸다가 전체 주기를 다시 시도하십시오.

  3. 잠금 파일이 없으면 내 식별자로 파일을 만들고 경쟁 조건을 피하기 위해 전체 주기를 다시 시도합니다(잠금 파일이 실제로 내 것인지 다시 확인).

식별자와 함께 잠금 파일에 타임스탬프를 기록하고 해당 타임스탬프가 지정된 시간 초과 값보다 오래된지 확인합니다.
타임스탬프가 너무 오래된 경우 잠금 파일이 오래되었다고 가정하고 데이터 파일에 쓰는 PC 중 하나가 충돌했거나 연결이 끊어졌을 수 있으므로 삭제하세요.

또 다른 솔루션

데이터 파일의 형식을 제어하는 ​​경우 파일이 잠겨 있는지 여부를 기록하기 위해 파일 시작 부분에 구조를 예약할 수 있습니다.
이 목적으로 바이트를 예약한다면 예를 들어 다음과 같이 가정할 수 있습니다. 00 이는 데이터 파일이 잠겨 있지 않으며 다른 값이 현재 파일에 쓰고 있는 컴퓨터의 식별자를 나타냄을 의미합니다.

NFS 관련 문제

알겠습니다. Jiri Klouda가 올바르게 지적했기 때문에 몇 가지를 추가하겠습니다. NFS는 클라이언트 측 캐싱을 사용합니다. 그러면 실제 잠금 파일이 결정되지 않은 상태가 됩니다.

이 문제를 해결하는 몇 가지 방법:

  • 다음을 사용하여 NFS 디렉터리를 마운트합니다. noac 또는 sync 옵션.이는 쉽지만 클라이언트와 서버 간의 데이터 일관성을 완전히 보장하지는 않으므로 귀하의 경우에는 문제가 없을 수 있지만 여전히 문제가 있을 수 있습니다.

  • 다음을 사용하여 잠금 파일이나 데이터 파일을 엽니다. O_DIRECT, O_SYNC 또는 O_DSYNC 속성.이는 캐싱을 완전히 비활성화해야 합니다.
    이렇게 하면 성능이 저하되지만 일관성은 보장됩니다.

  • 5월 사용할 수 있다 flock() 데이터 파일을 잠그려고 하지만 구현이 불확실하므로 특정 OS가 실제로 NFS 잠금 서비스를 사용하는지 확인해야 합니다.그렇지 않으면 전혀 아무것도 할 수 없습니다.
    데이터 파일이 잠겨 있으면 다른 클라이언트가 쓰기 위해 파일을 여는 데 실패합니다.
    아, 그렇습니다. SMB 공유에서는 작동하지 않는 것 같으니 그냥 잊어버리는 것이 가장 좋습니다.

  • NFS를 사용하지 말고 대신 Samba를 사용하십시오.~이있다 주제에 대한 좋은 기사 그리고 NFS가 사용 시나리오에 대한 최선의 대답이 아닌 이유를 알아보세요.
    또한 이 문서에서는 파일을 잠그는 다양한 방법을 찾을 수 있습니다.

  • Jiri의 솔루션도 좋은 솔루션입니다.

기본적으로 작업을 단순하게 유지하려면 여러 시스템에서 공유되고 자주 업데이트되는 파일에 NFS를 사용하지 마십시오.

뭔가 다른 것

소규모 데이터베이스 서버를 사용하여 데이터를 NFS/SMB 잠금 문제에 저장하고 우회하거나 현재 다중 데이터 파일 시스템을 유지하고 결과를 연결하는 작은 유틸리티를 작성하십시오.
이는 여전히 문제에 대한 가장 안전하고 간단한 해결책일 수 있습니다.

나는 D를 모르지만, 나는 mutex 파일을 사용하여 Jobe가 작동 할 수 있습니다. 유용한 의사 코드는 다음과 같습니다.

do {
  // Try to create a new file to use as mutex.
  // If it's already created, it will throw some kind of error.
  mutex = create_file_for_writing('lock_file');
} while (mutex == null);

// Open your log file and write results
log_file = open_file_for_reading('the_log_file');
write(log_file, data);
close_file(log_file);

close_file(mutex);
// Free mutex and allow other processes to create the same file.
delete_file(mutex); 

따라서 모든 프로세스는 MUTEX 파일을 만들려고하지만 승리하는 사람 만 계속할 수 있습니다. 출력을 작성하면 다른 프로세스가 동일한 작업을 수행 할 수 있도록 뮤트를 닫고 삭제하십시오.

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