Кэш Varnish слишком быстро устаревает для объектов

У меня возникла проблема с кешем лака (v3.0.2), из-за которого он продолжает сбрасывать кеш объекта менее чем через 60 секунд, несмотря на то, что TTL составляет 24 часа, файлы cookie удалены, кодировка контента нормализована, некритические заголовки отключены, Cache-Control установлен как общедоступный, s-maxage=86400 и т. д.

По какой-то причине, если вы обращаетесь к следующему URL-адресу несколько раз в течение минуты, вы можете увидеть, что возраст увеличивается, а затем достигает нуля (при этом X-Cache возвращает MISS):

http://data.eyewire.org/volume/83329/chunk/0/1/0/1/tile/xz/32:64

Объектов n_lru_nuked нет, а кеш больше 60 ГБ. Я наблюдал за лаковым журналом и, возможно, видел что-то с ExpBan, но я не могу понять, почему.

Вот некоторые ключевые части моего файла vcl:

sub vcl_recv {
  set req.grace = 120s;

   # normalize Accept-Encoding to reduce vary
  if (req.http.Accept-Encoding) {
    if (req.http.User-Agent ~ "MSIE 6") {
      unset req.http.Accept-Encoding;
    } 
    elsif (req.http.Accept-Encoding ~ "gzip") {
      set req.http.Accept-Encoding = "gzip";
    } 
    elsif (req.http.Accept-Encoding ~ "deflate") {
      set req.http.Accept-Encoding = "deflate";
    } 
    else {
      unset req.http.Accept-Encoding;
    }
  }

  # This uses the ACL action called "purge". Basically if a request to
  # PURGE the cache comes from anywhere other than localhost, ignore it.
  if (req.request == "PURGE") 
    {if (!client.ip ~ purge)
      {error 405 "Not allowed.";}
    return(lookup);}

  if (req.http.Upgrade ~ "(?i)websocket") {
    return (pipe);
  }

  # ....

  if ( req.http.host ~ "data\.eyewire\.org" ) {
    unset req.http.Cookie;
    unset req.http.Accept-Language;
    unset req.http.Expires;
    unset req.http.Cache-Control;
    unset req.http.User-Agent;
    return(lookup);
  }

  # ....
}


sub vcl_fetch {
  # ....

  if ( req.http.host ~ "data.eyewire.org" ) {
    if ( req.url ~ "^/volume" ) {
      unset beresp.http.Set-Cookie;
      set beresp.ttl = 24h;
      set beresp.http.Cache-Control = "public, s-maxage=86400";
      set beresp.http.X-TTL = beresp.ttl;
      return(deliver);
    }
    elsif (req.url ~ "^/cell") {
      set beresp.ttl = 1h;
      return(hit_for_pass);
    }
  }
}

# from http://blog.bigdinosaur.org/adventures-in-varnish/
sub vcl_pass {
  set bereq.http.connection = "close";
  if (req.http.X-Forwarded-For) {
      set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
  }
  else {
      set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
  }
}

# from http://blog.bigdinosaur.org/adventures-in-varnish/
sub vcl_pipe {
  #we need to copy the upgrade header
  if (req.http.upgrade) {
      set bereq.http.upgrade = req.http.upgrade;
      set bereq.http.connection = req.http.connection;
  }

  set bereq.http.connection = "close";
  if (req.http.X-Forwarded-For) {
      set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
  }
  else {
      set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
  }
}

# from http://blog.bigdinosaur.org/adventures-in-varnish/
sub vcl_hit {
  if (req.request == "PURGE") {
      purge;
      error 200 "Purged.";
  }
}

# from http://blog.bigdinosaur.org/adventures-in-varnish/
sub vcl_miss {
  if (req.request == "PURGE") {
      purge;
      error 200 "Purged.";
  }
}

sub vcl_deliver {  
    # Display hit/miss info
    if (obj.hits > 0) {
      set resp.http.X-Cache = "HIT";
      set resp.http.X-Cache-Hits = obj.hits;
    }
    else {
        set resp.http.X-Cache = "MISS";
    }

    # Security Non-Disclosure
    remove resp.http.X-Varnish;
    remove resp.http.X-Powered-By;
    remove resp.http.Server;

    return(deliver);
}

Спасибо!

Редактировать: FYI: мне пришлось отменить некоторые изменения в моем VCL, чтобы решить проблему в производстве, но проблема по существу остается той же.


person SapphireSun    schedule 16.09.2014    source источник
comment
Если это на самом деле VCL, который используется, я нахожу очень странным, что X-TTL не присутствует в ответе... Может ли быть возврат до того, как вы достигнете пункта if хоста? (#.... Я думаю, указывает на то, что, как вы предполагаете, не играет)   -  person Clarence    schedule 19.09.2014
comment
Привет, Кларенс, мне жаль, что я должен добавить эту часть обратно. Я вернул часть информации об отладке, когда откатывал VCL. Тем не менее, я могу без проблем добавить раздел доставки VCL обратно. Позвольте мне сделать это сейчас.   -  person SapphireSun    schedule 20.09.2014
comment
Можете ли вы подтвердить, что нет внешнего процесса, отправляющего запросы на очистку контента? Если контент не удаляется с помощью ядерной бомбы LRU, то, скорее всего, он удаляется/запрещается из кеша.   -  person Ketola    schedule 25.09.2014


Ответы (2)


Я испытал такое же поведение, когда число попаданий увеличивалось, и без какой-либо причины казалось, что кеш был очищен. После некоторых исследований я обнаружил, что причиной был заголовок vary: Accept-Encoding, User-agent, из-за которого для каждого пользовательского агента сохранялся другой кеш.

Попробуйте установить изменяющийся заголовок только для Accept-Encoding.

person Brian van Rooijen    schedule 24.10.2014

Что бы это ни стоило, я только что обновился до Varnish 4, и это, похоже, решило проблему. Во время обновления мы также удалили определения vcl_hit и vcl_miss, которые включали директиву очистки, которая не выглядела так, как будто она была сбита, но кто знает.

person SapphireSun    schedule 28.10.2014