기회 잠금 예제
다음 예제는 기회 잠금이 만들어지고 손상됨에 따른 데이터 및 SMB 메시지 이동을 보여 줍니다. 클라이언트는 파일 데이터뿐만 아니라 파일 특성 데이터도 캐시할 수 있습니다.
또한 이 예제들은 클라이언트 애플리케이션이 원격 서버에 기회 잠금을 요청하는 상황에 기반합니다. 이 프로세스들은 네트워크 리디렉터 및 원격 서버에 의해 자동으로 시작됩니다. 클라이언트 애플리케이션 또는 애플리케이션의 직접적인 개입은 없습니다. 이 예제들에서 설명하는 프로세스는 로컬 클라이언트 애플리케이션이 로컬 파일 시스템에서 기회 잠금을 직접 요청하는 상황으로 일반화될 수 있으며, 네트워크를 통해 데이터를 교환하지 않는다는 점을 제외하고는 일반화할 수 있습니다.
수준 1 기회 잠금
다음 다이어그램은 파일에 대한 수준 1 기회 잠금의 네트워크 트래픽 보기를 보여줍니다. 화살표는 데이터 이동 방향(있는 경우)을 나타냅니다.
이벤트 | 클라이언트 X | 서버 | 클라이언트 Y |
---|---|---|---|
1 | 파일을 열고 수준 1 잠금을 요청합니다 ==> | ||
2 | <== 수준 1 기회 잠금을 부여합니다 | ||
3 | 읽기, 쓰기 및 기타 작업을 수행합니다 ==> | ||
4 | <== 파일을 열도록 요청합니다 | ||
5 | <== 기회 잠금을 끊습니다 | ||
6 | 미리 읽기 데이터를 삭제합니다 | ||
7 | 데이터를 씁니다 ==> | ||
8 | "close" 또는 "done" 메시지를 보냅니다 ==> | ||
9 | 열린 작업에 문제 없음 ==> | ||
10 | 읽기, 쓰기 및 기타 작업을 수행합니다 ==> | <== 읽기, 쓰기 및 기타 작업을 수행합니다 |
이벤트 1에서 클라이언트 X는 파일을 열고 열기 작업의 일부로 파일에 대한 수준 1 기회 잠금을 요청합니다. 이벤트 2에서 서버는 다른 클라이언트에 열려 있는 파일이 없으므로 수준 1 잠금을 부여합니다. 클라이언트는 이벤트 3에서 일반적인 방식으로 파일에 액세스합니다.
이벤트 4에서 클라이언트 Y는 파일을 열려고 시도하고 기회 잠금을 요청합니다. 서버가 클라이언트 X에 파일이 열려 있는 것을 확인합니다. 클라이언트 X가 모든 쓰기 데이터를 플러시하고 파일에 대한 읽기 캐시를 포기하는 동안 서버는 Y의 요청을 무시합니다.
서버는 X에게 기회 잠금, 이벤트 5를 중단하는 SMB 메시지를 전송하여 X를 강제로 정리합니다. 클라이언트 X는 모든 미리 읽기 데이터를 ‘자동으로’ 삭제합니다. 즉, 이 프로세스는 네트워크 트래픽을 발생시키지 않습니다. 이벤트 7에서 클라이언트 X는 캐시된 쓰기 데이터를 서버에 씁니다. 클라이언트 X가 캐시된 데이터를 서버에 쓰는 작업을 완료하면 클라이언트 X는 이벤트 8에서 서버에 "닫기" 또는 "완료" 메시지를 보냅니다.
클라이언트 X가 서버에 쓰기 캐시를 플러시하거나 파일을 닫았다는 알림을 받은 후 서버는 이벤트 9에서 클라이언트 Y에 대한 파일을 열 수 있습니다. 이제 서버에 동일한 파일이 열려 있는 두 개의 클라이언트가 있으므로 두 클라이언트 모두에 기회 잠금을 부여하지 않습니다. 두 클라이언트 모두 파일에서 읽기를 계속하며, 하나 또는 둘 다 파일에 쓰지 않습니다.
일괄 처리 기회 잠금
다음 다이어그램은 일괄 처리 기회 잠금의 네트워크 트래픽 보기를 보여줍니다. 화살표는 데이터 이동 방향(있는 경우)을 나타냅니다.
이벤트 | 클라이언트 X | 서버 | 클라이언트 Y |
---|---|---|---|
1 | 파일을 열고 일괄 처리 잠금을 요청합니다 ==> | ||
2 | <== 일괄 처리 기회 잠금 부여 | ||
3 | 파일을 읽습니다 ==> | ||
4 | <== 데이터를 보냅니다 | ||
5 | 파일을 닫습니다. | ||
6 | 파일을 엽니다. | ||
7 | 데이터를 검색합니다 | ||
8 | 데이터를 읽습니다 ==> | ||
9 | <== 데이터를 보냅니다 | ||
10 | 파일을 닫습니다. | ||
11 | <== 파일을 엽니다 | ||
12 | <== 기회 잠금을 끊습니다 | ||
13 | 파일을 닫습니다 ==> | ||
14 | 열린 작업에 문제 없음 ==> | ||
15 | <== 읽기, 쓰기 및 기타 작업을 수행합니다 |
일괄 처리 기회 잠금에서 클라이언트 X는 파일을 열고(이벤트 1), 서버는 이벤트 2에서 클라이언트 X에 일괄 잠금을 부여합니다. 클라이언트 X는 데이터를 읽으려고 시도하고(이벤트 3), 서버는 데이터로 응답합니다(이벤트 4).
이벤트 5는 작업에서 일괄 처리 기회 잠금을 보여줍니다. 클라이언트 X의 애플리케이션은 파일을 닫습니다. 그러나 네트워크 리디렉터는 닫기 작업을 필터링하고 닫기 메시지를 전송하지 않으므로 ‘자동’ 닫기를 수행합니다. 클라이언트 X가 파일에 대한 단독 소유권을 가지므로 네트워크 리디렉터가 이 작업을 수행할 수 있습니다. 나중에 이벤트 6에서 애플리케이션이 파일을 다시 엽니다. 다시 말하지만, 네트워크를 통해 데이터가 흐르지 않습니다. 서버에 관한 한 이 클라이언트는 이벤트 2 이후 파일을 열어 두었습니다.
이벤트 7, 8, 9는 일반적인 네트워크 트래픽 과정을 보여 줍니다. 이벤트 10에서는 또 다른 자동 닫기가 발생합니다.
이벤트 11에서 클라이언트 Y는 파일을 열려고 시도합니다. 서버의 파일 보기는 클라이언트 X의 애플리케이션이 닫았음에도 불구하고 클라이언트 X가 열어 두었다는 것입니다. 따라서 서버는 클라이언트 X에 기회 잠금을 중단하는 메시지를 보냅니다. 클라이언트 X는 이제 네트워크를 통해 닫기 메시지를 보냅니다(이벤트 13). 서버가 클라이언트 Y를 위해 파일을 열 때 이벤트 14가 이어집니다. 클라이언트 X의 애플리케이션이 파일을 닫았으므로 해당 파일의 서버로 또는 서버에서 더 이상 파일이 전송되지 않습니다. 클라이언트 Y는 이벤트 15에서 평소와 같이 데이터 전송을 시작합니다.
클라이언트 X가 이벤트 2에서 파일에 대한 잠금을 부여하고 이벤트 13에서 마지막으로 닫는 사이에는 애플리케이션 열기 및 닫기 작업을 수행했음에도 불구하고 클라이언트가 캐시한 모든 파일 데이터가 유효합니다. 그러나 기회 잠금이 끊어진 후에는 캐시된 데이터를 유효한 것으로 간주할 수 없습니다.
필터 기회 잠금
다음 다이어그램은 필터 기회 잠금의 네트워크 트래픽 보기를 보여줍니다. 화살표는 데이터 이동 방향(있는 경우)을 나타냅니다.
이벤트 | 클라이언트 X | 서버 | 클라이언트 Y |
---|---|---|---|
1 | 액세스 권한 없이 파일을 엽니다 ==> | ||
2 | <== 파일을 엽니다 | ||
3 | 필터 잠금을 요청합니다==> | ||
4 | <== 잠금을 부여합니다 | ||
5 | 읽기 위해 파일을 엽니다 ==> | ||
6 | <== 파일을 다시 엽니다 | ||
7 | 읽기 핸들을 사용하여 데이터를 읽습니다 ==> | ||
8 | <== 데이터를 보냅니다 | ||
9 | <== 데이터를 보냅니다 | ||
10 | <== 데이터를 보냅니다 | ||
11 | <== 파일을 엽니다 | ||
12 | 파일을 엽니다 ==> | ||
13 | <== 필터 잠금을 요청합니다 | ||
14 | 필터 잠금을 거부합니다==> | ||
15 | <== 데이터를 읽습니다 | ||
16 | 데이터를 보냅니다 ==> | ||
17 | (캐시된) 데이터를 읽습니다 | ||
18 | 파일을 닫습니다 ==> | ||
19 | <== 파일을 닫습니다 |
필터 기회 잠금에서 클라이언트 X는 파일을 열고(이벤트 1) 서버는 이벤트 2에서 응답합니다. 그런 다음 이벤트 3에서 클라이언트가 필터 기회 잠금을 요청하고, 이벤트 4에서 서버가 기회 잠금을 부여합니다. 그런 다음 이벤트 5에서 클라이언트 X가 읽기 위해 파일을 다시 열고, 이벤트 6에서 서버가 응답합니다. 그리고 클라이언트는 서버가 데이터로 응답하는(이벤트 8) 데이터를 읽으려고 시도합니다.
이벤트 9는 작업 시의 필터 기회 잠금을 보여줍니다. 서버는 클라이언트보다 먼저 읽고 클라이언트가 요청하지 않았더라도 네트워크를 통해 데이터를 보냅니다. 클라이언트는 데이터를 캐시합니다. 또한 이벤트 10에서 서버는 향후의 데이터 요청을 예상하고 클라이언트가 캐시할 파일의 다른 부분을 전송합니다.
이벤트 11 및 12에서 다른 클라이언트 Y가 파일을 엽니다. 또한 클라이언트 Y는 필터 기회 잠금을 요청합니다. 이벤트 14에서 서버가 이를 거부합니다. 이벤트 15에서 클라이언트 Y는 서버가 이벤트 16에서 보내는 데이터를 요청합니다. 이 중 어느 것도 클라이언트 X에 영향을 미치지 않습니다. 언제든지 다른 클라이언트가 읽기 액세스를 위해 이 파일을 열 수 있습니다. 다른 클라이언트는 클라이언트 X의 필터 잠금에 영향을 주지 않습니다.
이벤트 17은 클라이언트 X가 데이터를 읽는 모습을 보여줍니다. 그러나 서버가 이미 데이터를 전송했으며 클라이언트가 데이터를 캐시했으므로 네트워크를 통과하는 트래픽이 없습니다.
이 예제에서 클라이언트 X는 파일의 모든 데이터를 읽으려고 시도하지 않으므로 이벤트 9와 10으로 표시된 미리 읽기는 ‘낭비’됩니다. 즉, 데이터는 실제로 사용되지 않습니다. 미리 읽기가 애플리케이션을 가속화했기 때문에 이는 허용 가능한 손실입니다.
이벤트 18에서 클라이언트 X는 파일을 닫습니다. 클라이언트의 네트워크 리디렉터가 캐시된 데이터를 중단합니다. 서버가 파일을 닫습니다.