Question Forcer la requête à rater le cache mais conserver la réponse


J'ai une application web lente sur laquelle j'ai placé Varnish. Toutes les pages sont statiques (elles ne varient pas pour un utilisateur différent), mais elles doivent être mises à jour toutes les 5 minutes pour pouvoir contenir des données récentes.

J'ai un script simple (wget --mirror) qui explore tout le site toutes les 15 minutes. Chaque exploration prend environ 5 minutes. Le but de l'exploration est de mettre à jour chaque page du cache Varnish afin qu'un utilisateur n'ait jamais à attendre que la page soit générée (toutes les pages ont été générées récemment grâce à l'araignée).

La chronologie ressemble à ceci:

  • 00:00:00: Cache vidé
  • 00:00:00: Spider commence à explorer pour mettre à jour le cache avec de nouvelles pages
  • 00:05:00: Spider termine l'exploration, toutes les pages sont mises à jour jusqu'à 00:15:00

Une demande qui arrive entre 0:00:00 et 0:05:00 risque d'apparaître sur une page qui n'a pas encore été mise à jour et sera forcée d'attendre quelques secondes pour obtenir une réponse. Ce n'est pas acceptable.

Ce que je voudrais faire, c’est peut-être, en utilisant un peu de magie VCL, toujours envoyer les requêtes de l’araignée au back-end, tout en conservant la réponse dans le cache. De cette façon, un utilisateur jamais attendre qu’une page soit générée car il n’ya pas de fenêtre de 5 minutes dans laquelle des parties du cache sont vides (sauf peut-être au démarrage du serveur).

Comment puis-je faire ceci?


7
2017-09-08 05:53


origine




Réponses:


req.hash_always_miss devrait faire l'affaire.

Ne faites pas de vidage complet du cache au début de l'exécution de l'araignée. Au lieu de cela, il suffit de mettre l’araignée au travail - et dans votre vcl_recv, configurez les requêtes de l'araignée pour qu'elles rateront toujours la recherche dans le cache; ils vont chercher une nouvelle copie du backend.

acl spider {
  "127.0.0.1";
  /* or whereever the spider comes from */
}

sub vcl_recv {
  if (client.ip ~ spider) {
    set req.hash_always_miss = true;
  }
  /* ... and continue as normal with the rest of the config */
}

Pendant ce temps et jusqu'à ce que la nouvelle réponse soit dans le cache, les clients continueront à recevoir de manière transparente l'ancien cache servi (tant qu'il reste dans sa durée de vie).


10
2017-09-08 06:27



Merci d'avoir répondu; J'étais à mi-chemin en train de taper la solution que j'ai trouvée quand j'ai vu votre réponse. Le vôtre est clairement supérieur au mien (et j'utilise déjà le vôtre). Pouvez-vous jeter un coup d'oeil à ma réponse et me faire savoir tout problème avec elle juste pour que je puisse apprendre? - Tom Marthenal


La réponse de Shane ci-dessus est meilleure que celle-ci. C'est une solution alternative qui est plus compliquée et pose des problèmes supplémentaires. S'il vous plaît, contrôlez la réponse de Shane, pas celle-ci. Je montre juste une autre méthode de résolution du problème.


Ma pensée initiale était de return (pass); dans vcl_recv puis, une fois la requête extraite, dans vcl_fetch, en quelque sorte dire à Varnish qu'il devrait cache l'objet, même s'il a été spécifiquement passé auparavant.

Il s'avère ce n'est pas possible:

Si vous avez choisi de transmettre la requête dans une fonction VCL antérieure (par exemple:   vcl_recv), vous allez toujours exécuter la logique de vcl_fetch, mais le   L'objet n'entre pas dans le cache, même si vous indiquez une heure de cache.

Donc, la meilleure chose à faire est de lancer une recherche comme une requête normale, mais assurez-vous qu'elle échoue toujours. Il n'y a aucun moyen d'influencer le processus de recherche, donc il va toujours frapper (en supposant que est mis en cache; si ce n'est pas le cas, alors il va rater et ranger quand même). Mais on peut influencer vcl_hit:

sub vcl_hit {
    # is this our spider?
    if (req.http.user-agent ~ "Wget" && client.ip ~ spider) {
        # it's the spider, so purge the existing object
        set obj.ttl = 0s;
        return (restart);
    }

    return (deliver);
}

Nous ne pouvons pas le forcer à ne pas utiliser le cache, mais nous pouvons purger cet objet du cache et redémarrer tout le processus. Maintenant, ça remonte au début, à vcl_recv, où il fait éventuellement une autre recherche. Puisque nous avons déjà purgé l’objet que nous essayons de mettre à jour, il manquera, puis récupérera les données et mettra à jour le cache.

Un peu compliqué, mais ça marche. La seule fenêtre pour un utilisateur bloqué entre une purge et la réponse stockée est le délai de traitement d'une seule demande. Pas parfait, mais plutôt bien.


2
2017-09-08 06:49



Yup, ça devrait marcher! Une chose supplémentaire que vous pouvez faire qui devrait empêcher un utilisateur d’obtenir une réponse lente en raison de la réduction de la distance entre la suppression et la re-mise en cache serait de définir une valeur courte. mode grace minuteur; depuis le redémarrage aura été déclenché, Varnish aura déjà une demande pour le contenu. Le mode Grace active le contenu obsolète au-delà de sa durée de vie, au lieu d'attendre la fin de la demande de l'araignée. - Shane Madden♦
@ShaneMadden merci pour la note sur le mode de grâce - J'essaie toujours de comprendre Varnish et je n'en avais pas encore entendu parler. Votre solution est toujours nettement meilleure, mais j'apprécie l'opportunité d'en apprendre davantage sur Varnish. - Tom Marthenal