단일 노드의 여러 프로세스가 일부 코드를 동시에 실행하지 않도록 하기 위해 일부 원자성 명령(예: ln
또는 mkdir
) 을 기반으로 권고 잠금을 구현하거나 flock
.
여러 프로세스가 특정 코드를 비동시적으로 실행하는지 확인하는 방법많은 종류의노드(즉, 네트워크에서 실행 중인 인스턴스가 하나만 허용됨)? Linux에서 bash 또는 python 스크립트를 통해 이 작업을 수행하고 싶습니다.
NFS 잠금이나 Redis를 사용할 수 있다는 것을 알고 있지만 이러한 복잡성 오버헤드를 겪고 싶지 않습니다. 공개 키 기반 SSH를 사용할 수 있습니다. 나는 잠금 관리자 역할을 하는 추가 머신의 오버헤드를 원하지 않습니다. 이상적으로는 관리자가 노드 중 하나를 잠금 관리자로 지정할 필요가 없습니다. 쿼럼에 대해 걱정할 필요가 없습니다. 노드에 연결할 수 없게 되면 계속할 필요가 없습니다.
이상적으로는 다음과 같이 모든 노드에서 하나의 명령을 호출할 수 있습니다.
distlock --lock --nodes=nodeA,nodeB,nodeC --resource=resourceX || error "can't lock"
...
distlock --unlock --nodes=nodeA,nodeB,nodeC --resource=resourceX
지금까지 (생각과 인터넷 검색을 통해) 내가 생각해낸 최선의 방법은 각 노드에 대해 다음 프로세스를 따르는 것입니다.
- 구성 파일에서 노드 목록을 읽습니다. (파일은 수동으로 생성되어 모든 노드에 복사됩니다.)
- 잠금 관리자 노드가 노드 목록에서 알파벳순으로 첫 번째 노드인지 확인하세요.
- 현재 실행 중인 스크립트 인스턴스인 경우예결정된 잠금 관리자 노드에서 일반적인 방법으로 로컬 잠금 파일을 생성합니다(잠금 파일에는 pid가 포함되어 있음).
- 현재 실행 중인 스크립트 인스턴스가아니요식별된 잠금 관리자 노드에서 다음을 수행합니다.
ssh
특정 잠금 관리자 노드로 포크 (예:coproc
bash 사용)- 잠금 파일을 생성하고...
- 표준 입력(메인 스크립트에서 감지됨)에서 텍스트 한 줄을 읽도록 하여(메인 스크립트가 아직 보내지 않았기 때문에 아직 수신하지 않음) pid 파일이 오래되지 않도록 유지합니다. 결정된 잠금 관리 노드의 모습)
- 내가 보호하고 싶은 코드를 실행해 보세요
- 잠금을 해제합니다(잠금이 로컬인 경우 잠금 파일을 삭제하거나 위의 텍스트 줄을 분기된 SSH에 보내고 종료될 때까지 기다림).
이는 내 요구 사항을 충족합니다. 여러 노드가 위 코드를 병렬로 실행하면 정확히 하나의 노드가 성공적으로 잠기고 네트워크 연결이 실패하면 다른 노드가 잠기지 않습니다. 그러면 하나의 노드(사용자 정의된 잠금 관리자)가 계속 작동할 수 있습니다. 다른 노드는 그렇게 할 수 없습니다(즉, 클러스터는 반 브레인 상태가 되지만 분할 브레인 상태는 아닙니다).
그러나 저는 간단하고 스크립트하기 쉬운 도구를 사용하여 보다 우아한 대안 솔루션에 대한 아이디어를 다른 사람들에게 요청하고 싶습니다.