Идеальная настройка Varnish & Nginx для обеспечения согласованности кэша в нескольких экземплярах

Ищем идеальную настройку, включающую nginx в качестве нашего балансировщика нагрузки верхнего уровня, который распределяет нагрузку по нескольким экземплярам Varnish.

Каков наилучший способ распределить эту нагрузку? Один из способов - просто распределить его равномерно по экземплярам, ​​а другой - распределить нагрузку на основе шаблона URL-адреса запроса. Есть ли лучшая практика для этого?

Также - у нас есть ситуация, когда нам нужно вручную (из бэкэнда) удалить определенные элементы из наших кешей. Является ли самый эффективный способ сделать это просто, выполнив небольшой HTTP-запрос PURGE для каждого из наших экземпляров Varnish?

1 ответ

Каков наилучший способ распределить эту нагрузку? Один из способов - просто распределить его равномерно по экземплярам, ​​а другой - распределить нагрузку на основе шаблона URL-адреса запроса. Есть ли лучшая практика для этого?

Это зависит. Две причины, по которым вы хотите основывать распространение на чем-то вроде хэша URL:

  1. Размер кэша. Если вы кешируете достаточно данных в целом, чтобы заполнить кеш заданного бэкэнда, было бы полезно, чтобы определенный URL всегда попадал в один и тот же бэкэнд, чтобы распределять хранилище данных кеша между бэкэндами, а не хранить дубликаты.
  2. Скорость пропущенного запроса / время жизни кэша. Если клиент запрашивает отсутствие кэша, это проблема, и ваш кэш не длится долго, вы, вероятно, получите меньше промахов, если определенный фрагмент контента всегда попадет на данный сервер Varnish.

Также - у нас есть ситуация, когда нам нужно вручную (из бэкэнда) удалить определенные элементы из наших кешей. Является ли самый эффективный способ сделать это просто, выполнив небольшой HTTP-запрос PURGE для каждого из наших экземпляров Varnish?

Это работает, но оставляет следующему инициатору контента потенциально медленное пропускание кеша. Альтернативой является использование Varnish's. req.hash_always_miss заставить обновление ресурса в кеше вместо того, чтобы просто сделать его недействительным, чтобы запрос извне не был пропущен.

Так что-то вроде этого в вашем Vcl:

acl purge {
    "localhost";
}
sub vcl_recv {
    /* add this into your existing config: */
    if (req.http.X-Varnish-Nuke == "1" && client.ip ~ purge) {
        set req.hash_always_miss = true;
    }
}

Затем запрос с таким набором заголовков заставит внутренний запрос обновить содержимое в кэше (с помощью curl или wget, --header "X-Varnish-Nuke: 1").

Другие вопросы по тегам