Сеть кэшей в squid метро

Материал из Bryansk Linux Users Group.

Перейти к: навигация, поиск

Содержание

Вступление

Итак у нас есть сквид (squid), пара друзей, горячее желание разобраться теоретически и практически в вопросах кэширования.

Что даст сеть кэшей?

squid умеет не только вытаскивать из инета разные объекты и отдавать их запросившему клиенту, но и «спрашивать» у других кэшей о наличии такого объекта, и если другой кэш пошарив у себя запрошенное найдёт – он может поделиться. Такая кооперация – крайне полезная вещь. Дело даже не в экономии траффика – когда интернет был меньше и статичнее, эффективность кэшей была 10-20%, с ростом интернета и ростом динамического контента выигрыш в 2% можно считать весьма неплохим. Дело в том, что зачастую кроме «узкого» интернет-канала в наличии более скоростные каналы, и тут можно реально получить выигрыш по скорости: получить контент через 56..128К из инета, или часть контента получить по 512-1024К? А может и 10/100Мегабитам...

Как выглядит иерархия кэшей

Связей в иерархии всего 2: parent/child(родитель/ребёнок) и sibling(сосед). Братские кэши спрашивают друг у друга объекты, но «не настаивают» если объект не найден и вытаскивают его самостоятельно. Родительский кэш подразумевает что дочерний кэш не в состоянии получить объект самостоятельно и предоставляет дочернему кэшу объект в любом случае, даже если придётся взять его с оригинального сайта. Более подробно узнаём на сайте www.squid-cache.org в разделе FAQ:

What is the Squid cache resolution algorithm?

Send ICP queries to all appropriate siblings
Wait for all replies to arrive with a configurable timeout (the default is two seconds).
Begin fetching the object upon receipt of the first HIT reply, or
Fetch the object from the first parent which replied with MISS (subject to weighting values), or
Fetch the object from the source

The algorithm is somewhat more complicated when firewalls are involved.

The single_parent_bypass directive can be used to skip the ICP queries if the only appropriate 
sibling is a parent cache (i.e., if there's only one place you'd fetch the object from, why 
bother querying?)

Переведу своими словами. Алгоритм действия кэшей в иерархии такой. Получив запрос от клиента, squid отсылает ICP запросы всем кэшам, помеченным как братские (sibling) и ждёт в течении некоего таймаута (по умолчанию 2 сек) ответа. Словив первый же HIT (попадание, т.е. у «брата» есть такой объект), кэш забирает с ответившего «брата» искомый объект. Если в братских кэшах ничего не найдено, то объект забирается у первого парента, ответившего MISS («промах, но сейчас скачаю»), если таких нет, то объект забирается с источника.

Рассмотрим две «чистые» модели.

Модель parent/child

Parent/child идеальна для модели головной офис/филиал или провайдер/абонент. Провайдер запускает кэш, абонент (например небольшая фирма) запускает свой кэш, и прописывает в squid.conf дочернего кэша:

cache_peer cache.megaprovider.kz parent 3128 3130

(где cache.megaprovider.kz – имя или ip родительского кэша,
parent – его роль для нас,
3128 – порт на котором родительский кэш слушает клиентов по tcp,
3130 – порт на котором родительский кэш слушает кэши по icp (udp))
Теперь перед тем как вытащить объект, наш кэш обратиться к родительскому, и тот вытащит его для нас, ну а если не вытащит, то только тогда мы сами заберём его из первоисточника. Директива

never_direct allow all

запрещает такой ход событий и наш кэш никуда не полезет: если в родительском (-ских) кэше(ах) объекта не найдено, клиент получит сообщение что объект не найден. Подробнее о применении never_direct и always_direct


Настройки Parent/child:

Parent
включить icp (порт, отличный от нуля), разрешить child в acl (icp_access allow XXX).
Child
включить icp, cache_peer <parent_cache_ip> parent <port http> <port icp> <options>

Модель sibling/sibling

Во второй модели мы пишем в нашем конфиг-файле squid.conf:

cache_peer good.friend.ru sibling 3128 3130

Теперь наш кэш будет спрашивать у соседа про наличие объектов. И тот нам будет отвечать. Если такого рода запросы от нас разрешены у него.

Настройки sibling/sibling:

Sibling1
включить icp (порт, отличный от нуля), разрешить acl
icp_access allow <sibling2>
Sibling2
включить icp, разрешить acl (icp_access allow <sibling1>).

О доброй воле и безопасности

Казалось бы и всё. Но тут начинаются тонкости. Например, вы договорились с админом кэша №2 что прописываете друг друга как sibling. Но он, почесав задумчиво затылок прописывает вас как parent-а. Что произойдёт? Ничего особенного кроме как то, что ваш кеш будет обслуживать sibling2 как родного. Т.е. если у вас чего-то нет, вы для него это вытащите из интернета. Если это не входит в ваши планы, надо думать как с этим бороться. Как узнать, какую роль назначили вашему кэшу? А никак. Да это и не нужно. Потому что есть волшебная директива miss_access. Добавляем miss_access deny siblings (где в acl siblings перечислены все братские кэши). Можно конечно сделать и miss_access deny all но под запрет попадёт «всё что движется», включая ваш клиентский броузер. Который сможет получать только то, что есть в кэше :) Перед всеобщим запретом надо сделать miss_access allow clients, да и всеобщее deny all точнее будет заменить на deny !clients.

Теперь всё.

"Больной вопрос": актуальность объектов в кэшах

Теперь о грустном. Дело в том, что забирая объекты из кэша соседа мы не знаем, насколько агрессивна его политика кэширования. Может статься что этот объект у него болтается уже месяц – это может быть актуальный объект, а может быть уже и не особо :)

Ещё проблема - неоднозначность: ICP запрос может иметь только 2 варианта ответа – HIT или MISS. А HTTP запрос может иметь гораздо больше вариантов: например оригинальный сервер ответил 304 Not modifyed. Это не совсем HIT потому что требуется посылка дополнительных данных и не совсем MISS так как актуальный объект всё таки в кэше. Как предлагают решать эту проблему разработчики?

Make sure all members have the same refresh_rules parameters.

Do not use miss_access at all. Promise your sibling cache administrator that your cache is properly 
configured and that you will not abuse their generosity. The sibling cache administrator can check 
his log files to make sure you are keeping your word.

If neither of these is realistic, then the sibling relationship should not exist.


Решения проблем актуальности объектов в кэшах

Т.е. метод первый: использовать одинаковые параметры обновления объектов. (Реализуемо? Вполне)

Метод второй – не использовать директиву miss_access. Пообещать друг другу что всё будет настроено по-честному, и проверять по логам. (Ха!)

Метод третий – не использовать отношения sibling вообще (При этих строкам мы сворачиваем пару кукишей и показываем воображаемым разработчикам).

На этом их советы заканчиваются, и я позволю себе выдвинуть версию, что если нам директивами always_direct тянуть все объекты типа *.html напрямую, а всё остальное из кешей, это будет разумно и решит бОльшую часть проблемы. html документ всегда актуален, и если в актуальном html есть ссылки на картинки, то это либо какие-нибудь баннеры/счётчики, актуальность которых нам редко нужна, либо заведомо актуальная графика. То же и файловыми ссылками.

Теперь ваши замечания и... практика... практика... практика...

Оригинал статьи на AltForum-е (может устареть).

Личные инструменты