Представьте себе приложение, которое открывает файл на сетевом сервере для чтения и записи и записывает в файл 128-байтовые записи. Без оппортунистической блокировки каждая запись размером 128 байт потребует передачи данных по сети. Использование oplock позволяет локально кэшировать файл на клиентской системе и объединять несколько операций записи в одну, которая приводит к передаче данных по сети. Например, предположим, что клиент использует буферы размером 4096 и последовательно записывает в файл по 128 байт. Первый буфер будет содержать данные 32 операций записи (4096/128 = 32), и все данные 32 записей будут переданы по сети одним запросом на запись в файл. Если операция записи не может быть кэширова- на, по сети будет передаваться 32 операции записи (а не одна, как при кэшировании). Сокращение количества операций записи с 32 до одной приводит к значительному снижению нагрузки на сеть и существенному повышению производительности.
Вторым назначением оппортунистической блокировки является расширение условий, при которых подобная блокировка возможна. При использовании oplock можно увеличить эффективность кэширования. Расширение условий, при которых возможна оппортунистическая блокировка, предоставляет несколько дополнительных преимуществ. Предположим, что экземпляр приложения открывает файл (на сетевом сервере) для чтения и записи. При этом запрашивается и предоставляется оппортунистическая блокировка. Программный код клиента может кэшировать операции записи в файле. Предположим, что другой экземпляр того же приложения запущен на другом клиенте. Одним из выходов из подобной ситуации будет снятие оппортунистической блокировки и использование сетевого ввода-вывода для передачи запросов на запись в файл от обоих приложений. Еще одним способом будет снятие оппортунистической блокировки в тот момент, когда второй экземпляр приложения попытается выполнить операцию записи. Очень часто приложения вообще не выполняют операции записи.
При изменении условий сервер отправляет уведомление клиенту о снятии оппортунистической блокировки. В качестве примера ситуации, когда сервер отправляет уведомление о снятии оппортунистической блокировки, можно указать запрос на доступ к файлу или запись данных в файл другим клиентом. Сервер обеспечивает очистку данных состояния сервера (включая закрытие сеанса клиента), если клиент не отвечает на запрос о снятии оппортунистической блокировки. Клиент запрашивает oplock только в случае необходимости; например, если приложение запрашивает открытие файла для эксклюзивного доступа, запрос оппортунистической блокировки просто не имеет смысла.
Оппортунистические блокировки реализуются в трех вариантах:
Рис. 3.3. Последовательность операций при эксклюзивной оппортунистической блокировке
эксклюзивная оппортунистическая блокировка;
пакетная оппортунистическая блокировка;
оппортунистическая блокировка второго уровня.
Далее эти сценарии описываются более подробно.
Этот вариант блокировки запрашивается мини-перенаправителем CIFS, когда приложение открывает файл для чтения или записи. Сервер предоставляет оппортунистическую блокировку, если файл еще не открыт другим клиентом. Последовательность операций показана на рис. 3.3.
Для начала первый клиент отправляет запрос на открытие файла, запрашивая эксклюзивную оппортунистическую блокировку. Сервер выполняет необходимую проверку и предоставляет ее. Первый клиент начинает кэширование файла, выполняя операции упреждающего чтения и отложенной записи. Через некоторое время другой клиент, например клиент 2 (на рис. 3.3 не показан), отправляет серверу запрос на открытие того же файла. Сервер
отмечает, что клиент 1 владеет эксклюзивной оппортунистической блокировкой для запрошенного файла, и отправляет уведомление о снятии блокировки клиенту 1. Клиент 1 очищает буферы данных, отправляя необходимые запросы на запись и на блокировку файла. Как только данные состояния файла будут записаны, клиент 1 сообщает серверу, что обработка уведомления о снятии оппортунистической блокировки завершена. На этом этапе сервер отправляет ответ клиенту 2, позволяя ему открыть файл. Клиент 1 продолжает работу с файлом, не проводя при этом локального кэширования. В данном случае предполагается, что клиент 1 открыл файл в режиме, допускающем открытие файла другими клиентами.