Другим местом кэширования является ядро. Недостатком этого варианта является то, что во всех случаях нужно выполнять системные вызовы, даже в случае успешного обращения к кэш-памяти (файл оказался в кэше). Но преимуществом является то, что файлы остаются в кэше и после завершения процессов. Например, предположим, что двухпроходный компилятор выполняется, как два процесса. Первый проход записывает промежуточный файл, который читается вторым проходом. На рисунке 3.11,в показаниный, что после завершения процесса первого прохода промежуточный файл, наверное, будет находиться в кэше, так что вызов серверу не потребуется.

Третьим вариантом организации кэша есть создания отдельного процесса уровня - кэш-менеджера. Преимущество этого подхода заключается в том, что ядро освобождается от кода файловой системы и тем самым реализуются все достоинства микроядер.

С другой стороны, когда ядро управляет кэшем, оно может динамично решить, сколько памяти выделить для программ, а сколько для кэша. Когда же кэш-менеджер уровня работает на машине с виртуальной памятью, то понятно, что ядро может решить выгрузить некоторые, или даже все страницы кэша на диск, так что для так называемого "попадание в кэш" нужно подкачивания одной или более страниц. Ничего и говорить, что это целиком дискредитирует идею кэширования. Однако, если в системе есть возможность фиксировать некоторые страницы в памяти, то такая парадоксальная ситуация может быть исключена.

Как и везде, нельзя получить что-нибудь, не заплатив то за это. Кэширование на стороне клиента вносит в систему проблему несогласованности данных.

Одним из путей решения проблемы согласования есть использования алгоритма сквозной записи. Когда кэширует элемент (файл или блок) модифицируется, новое значение записывается в кэш и одновременно ссылается на сервер. Теперь другой процесс, который читает этот файл, получает самую последнюю версию.

Один из недостатков алгоритма сквозной записи составляется в том, что он уменьшает интенсивность сетевого обмена только при чтении, при записи интенсивность сетевого обмена та же самая, что и без кэширования. Много разработчиков систем находят это неприемлемым и предлагают такой алгоритм, который использует отложенную запись: вместо того, чтобы выполнять запись на сервер, клиент просто замечает, что файл изменен. Приблизительно каждое 30 секунд все изменения в файлах собираются вместе и отсылаются на сервер за один прием. Одна большая запись обычно более эффективная, чем много маленьких.

Таким шагом в этом направлении есть принятия сессионной семантики, согласно которому запись файла на сервер ведется только после его закрытия. Этот алгоритм называется "записи-по-закрытию". Как мы видели раньше, этот путь приводит к потому, что если две копии одного файла кэшируются на разных машинах и последовательно записываются на сервер, то второй записывается сверх первого. Однако это не так уже неважно, как кажется на первый взгляд. В однопроцессорной системе два процессы могут отворить и читать файл, модифицировать его в своих адресных пространствах, а потом записать его поэтому. Итак, алгоритм "записи-по-закрытию", основанный на сессионной семантике, не намного хуже варианта, уже используемого в однопроцессорной системе.

Целиком отличный подход к проблемы согласования - это использования алгоритма централизованного управления (этот подход отвечает семантике UNIX). Когда файл открыт, машина, которая отворила его, посылает сообщение файловому серверу, чтобы оповестить его об этом факте. Файл-Сервер сохраняет информацию о том, кто отворил какой файл, и о том, открытом ли он для чтения, для записи, или для того й другого. Если файл открыт для чтения, то нет никаких препятствий для разрешения другим процессам отворить его для чтения, но открытие его для записи должно быть запрещено. Аналогично, если некоторый процесс отворил файл для записи, то все другие виды доступа должны быть отвернуты. При закрытии файла также необходимо оповестить файл-сервер для того, чтобы он обновил свои таблицы, которые содержат данные об открытых файлах. Модифицированный файл также может быть выгружен на сервер в такой момент.

Четыре алгоритма управления кэшированием обобщаются таким способом:

1. Сквозная запись. Этот метод эффективный частично, потому что уменьшает интенсивность только операций чтения, а интенсивность операций записи остается неизменной.

2. Отложенная запись. Производительность лучше, но результат чтения кэшированного файла не всегда однозначный.

3. "Записи-по-закрытию". Удовлетворяет сессионной семантике.

4. Централизованное управление. Ненадежен вследствие своей централизованной природы.

Подводя результаты обсуждения проблемы кэширования, нужно отметить, что кэширование на сервере несложно реализуется и почти всегда дает эффект, независимо от того, реализованное кэширование у клиента или нет. Кэширование на сервере не влияет на семантику файловой системы, видимую клиентом. Кэширование у клиента напротив дает увеличение производительности, но увеличивает и сложность семантики.

 

Возможно стоит прочитать: