Zachowanie cache w przypadku niemożłiwości odświeżenia

1

Załóżmy, że cachujemy sobie wartości pobrane z jakiegoś zewnętrznego webserwisu, mamy ustawione jakieś expiration time, i okazuje się, że po jego upłynięciu webserwis nie jest dostępny. Jak powinno zachować się cache?

  1. Trzymać i zwracać stare dane, ustawić jakiś krótszy expiration time (np. minutę) i próbować odpytywać webserwis.
  2. Zgodnie z pierwotnymi założeniami wyczyścić się i nie zwracać niczego.
7

Wydaje mi sie że to jest trochę bardziej pytanie "biznesowe" niz techniczne. Czy ten cache to jest tylko optymalizacja czasowa, czy istnieja też jakieś inne ograniczenia? Bo jeśli gdzieś "bieznesowo" jest gwarancja że dane będą "nie stasze niż..." to nie możesz sobie ot tak trzymać tego cache dłużej i może lepiej nie zwracać nic / jakiś error, niz zwracać niepoprawne dane.
Jeśli nie ma takich ograniczeń, to ja bym trzymał te wartości w cache dłużej, ale tak jak mówe, ja bym jednak spytał jakiegoś Product Ownera czy BA czy lepiej żeby nie działało, czy lepiej żeby pracowało na starych danych.

1

cache to cache a nie failover wiec proste, zrodlo danych umiera to istnienie cache przestaje miec sens (zakladajac ze przekroczylismy expiry time)

0

Dla komponentu "cache", spodziewałbym się, że da się ustawić różne strategie zachowania i ustawiam taką jakiej potrzebuję w określonym scenariuszu biznesowym.

Skoro ustawiłem "Expire", to cache zgodnie z tą strategią powinien zapomnieć wpis.

Kto wstawia dane do cache?

0
Shalom napisał(a):

Wydaje mi sie że to jest trochę bardziej pytanie "biznesowe" niz techniczne. Czy ten cache to jest tylko optymalizacja czasowa, czy istnieja też jakieś inne ograniczenia? Bo jeśli gdzieś "bieznesowo" jest gwarancja że dane będą "nie stasze niż..." to nie możesz sobie ot tak trzymać tego cache dłużej i może lepiej nie zwracać nic / jakiś error, niz zwracać niepoprawne dane.
Jeśli nie ma takich ograniczeń, to ja bym trzymał te wartości w cache dłużej, ale tak jak mówe, ja bym jednak spytał jakiegoś Product Ownera czy BA czy lepiej żeby nie działało, czy lepiej żeby pracowało na starych danych.

@Shalom - no niby decyzje biznesowe, z drugiej strony developer może zaproponować co ma sens.
W tym przypadku nie ma biznesowej gwarancji, że dane nigdy nie będą nieaktualne, gdyby tak miało byc, to bym przecież nie pytał. :)
To raczej takie dodatkowe metadane, dajmy na to współrzędne GPS punktu odbioru przesyłki. Nie są krytyczne, ale fajnie jeśli klient je widzi. Zbyt często się nie zmieniają, więc jest sens je cachować. Ale czasem dochodzą nowe punkty odbioru, albo może zajść jakaś korekta w starych, bo ktoś coś zwalił, więc dobrze czasem odświeżyć. No i głupio moim zdaniem przestać zwracać te dane tylko dlatego, że źródło nie jest chwilowo dostępne.

katelx napisał(a):

cache to cache a nie failover wiec proste, zrodlo danych umiera to istnienie cache przestaje miec sens (zakladajac ze przekroczylismy expiry time)

Dlaczego cache przestaje mieć sens?

yarel napisał(a):

Skoro ustawiłem "Expire", to cache zgodnie z tą strategią powinien zapomnieć wpis.

A skoro innej niż Expire ustawić nie można, to trzeba się z tym pogodzić?

Kto wstawia dane do cache?

Kto to chyba jest złe pytanie w tym przypadku. Kod programu wstawia.

5

To raczej takie dodatkowe metadane, dajmy na to współrzędne GPS punktu odbioru przesyłki. Nie są krytyczne, ale fajnie jeśli klient je widzi. Zbyt często się nie zmieniają, więc jest sens je cachować. Ale czasem dochodzą nowe punkty odbioru, albo może zajść jakaś korekta w starych, bo ktoś coś zwalił, więc dobrze czasem odświeżyć. No i głupio moim zdaniem przestać zwracać te dane tylko dlatego, że źródło nie jest chwilowo dostępne.

A widzisz, ale to w takim razie chyba nie do końca jest cache jak dla mnie. Bo generalnie odróżniam 2 rzeczy:

  • cache per request -> user wysyła zapytanie, pobieramy wynik, wrzucamy go do cache i potem przy następnym requeście zwracamy to co w cache, czas życia entry w cache jest ograniczony i kiedyśtam zniknie.
  • tymczasowe in-memory data store, które co jakiś czas jest refreshowane faktycznymi danymi -> przychodzące requesty są obsługiwane za pomocą danych trzymanych w pamięci, a inny wątek raz na jakiś czas pobiera prawdziwe dane ze źródła, buduje nowy stan tego memory-store i je podmienia.

W przypadku 1 zwracałbym błąd, bo inaczej aplikacja działa dość dziwnie, bo jeden user jest w stanie korzystać (bo jest w cache), a drugi nie i może to rodzić problemy.
W przypadku 2, o ile nie ma jakichś biznesowych gwarancji na to eventual consistency i to nie są jakieś krytyczne dane (typu access-control) to trzymałbym stary stan jeśli nie da się zbudować bardziej aktualnego.

0

Generalnie to co @Shalom napisał. Z tych samych powodów. Dobrze to ujął.

1
somekind napisał(a):
yarel napisał(a):

Skoro ustawiłem "Expire", to cache zgodnie z tą strategią powinien zapomnieć wpis.

A skoro innej niż Expire ustawić nie można, to trzeba się z tym pogodzić?

Dla mnie cache to takie rozwiązanie problemu szybkości dostępu do danych. Dorzucanie jakiejś logiki, że cache coś tam aktualizuje i pobiera zewnętrznego systemu, ociera się o złamanie SRP (nie zakładam, że rozwiązanie jest obiektowe, ale zasadę można trochę ekstrapolować ;-) ). Po prostu coś jest w cache albo nie ma. Można się z tym Expire pogodzić albo nie jest to wymóg.

Jeśli cache umie wygenerować notyfikację "wygasł wpis X=(a,b,c)", to ktoś może takie notyfikacje konsumować i ten ktoś może mieć logikę, która coś zrobi, np:

  • jest sesja powiązana z danymi, które "wygasają" -> odpytujemy zewnętrzny system albo wstawiamy stare dane, jak zewnętrzny system umarł
  • nie ma sesji -> olewamy to, że coś wypadło z cache

Cache pozostanie cachem.

Kto wstawia dane do cache?

Kto to chyba jest złe pytanie w tym przypadku. Kod programu wstawia.

Zakładam, że ktoś/coś robi "weź z cache, a jak nie ma, to weź z X i wstaw do cache". Chodziło mi o odpowiedzialnego (komponent/klasę) za wstawienie do cache. Tak by szerzej zrozumieć problem.

3
katelx napisał(a):

cache to cache a nie failover wiec proste, zrodlo danych umiera to istnienie cache przestaje miec sens (zakladajac ze przekroczylismy expiry time)

Dlaczego cache przestaje mieć sens?

no skoro cache to optymalizacja czasu/kosztu dostepu do danych to gdy danych nie ma to cache przestaje miec znaczenie. jesli cache ma pelnic role "backupu" to zwykle prowadzi to do roznych problemow zwiazanych ze ustalaniem co i kiedy jest prawidlowe. dlatego lepiej te dwie funkcjonalnosci (t.j. cache i backup) separowac jak najwczesniej bo potem w miare dokladania nowych "featuresow" jest tylko gorzej

2
somekind napisał(a):

@Shalom - no niby decyzje biznesowe, z drugiej strony developer może zaproponować co ma sens.
W tym przypadku nie ma biznesowej gwarancji, że dane nigdy nie będą nieaktualne, gdyby tak miało byc, to bym przecież nie pytał. :)
To raczej takie dodatkowe metadane, dajmy na to współrzędne GPS punktu odbioru przesyłki. Nie są krytyczne, ale fajnie jeśli klient je widzi. Zbyt często się nie zmieniają, więc jest sens je cachować. Ale czasem dochodzą nowe punkty odbioru, albo może zajść jakaś korekta w starych, bo ktoś coś zwalił, więc dobrze czasem odświeżyć. No i głupio moim zdaniem przestać zwracać te dane tylko dlatego, że źródło nie jest chwilowo dostępne.

Decyzja o tym, jak stare dane nadają się do użycia decyzja biznesowa. Jeżeli mamy wspomniana przez ciebie pozycję geograficzną, to ten czas będzie różny dla aplikacji pokazującej położenie drzewa i drugiej, pokazującej pilotowi położenie samolotu. Generalnie cache jest po to, żeby zwiększyć wydajność, poprzez redukcję ilości zapytań do dostawcy danych. Programista powinien przedstawić jakie są możliwości, ale to biznes musi podjąć decyzję, czy przestarzałe dane warto pokazywać.

0

Cache to nie kopia zapasowa i im szybciej zauważymy w interfejsie, że coś się posypało tym szybciej usuniemy przyczynę problemu. Inna sytuacja jeśli mamy źródło danych (np. webService), który jest niestabilny i czasem odpowiada a czasem nie - wówczas rzeczywiście warto rozszerzyć logikę kasowania cache tak by to uwzględniała - ale też bez przesadnego wgłębiania się w problematykę.
Jestem bardziej zdania, że cache to cache i jego zadaniem jest zniknąć po ustalonym czasie.A poprawnym rozwiązaniem na niestabilny webService jest postawienie "proxy", które problem rozwiązuje bez konieczności modyfikacji logiki działania samego cache.

0

Moim zdaniem to serwer (jako właściciel danych, źródło prawdy) powinien sterować ważnością danych, które serwuje poprzez np. ustawienie nagłówka Cache-Control. W momencie kiedy czas upłynie, dane są nieważne i nie powinny być serwowane klientom. W takiej sytuacji odpowiedziałbym statusem 503, aby klient wiedział, że może ponowić żądanie po jakimś czasie.

Czasem mamy cache, który zakładamy bez świadomości serwera, żeby ograniczyć ruch. W momencie, kiedy serwer padnie zachowałbym się tak samo, jakby tego cache nie było - jeśli minie TTL, to zwracam 503. Można jeszcze pomyśleć nad jakimś fallbackiem i zwrócić jakiś default, czasem się da.

Logika czyszczenia cache (tutaj od razu czerwona lampka) w zależności od zdrowia źródła danych to kiepski pomysł, bo trzeba w jakoś sposób czyścić cache na wszystkich instancjach itd - tutaj fajny wątek: https://www.quora.com/Why-is-cache-invalidation-considered-difficult

0
Shalom napisał(a):

W przypadku 1 zwracałbym błąd, bo inaczej aplikacja działa dość dziwnie, bo jeden user jest w stanie korzystać (bo jest w cache), a drugi nie i może to rodzić problemy.

No takiego problemu nie będzie, bo chodzi tu o dane niekrytyczne, więc obaj użytkownicy mogą korzystać. Cache jest jeden, więc wszyscy użytkownicy mają dostęp do tych samych danych, czyli co najwyżej jeden user dodatkowe informacje zobaczy, drugi nie. Ale tak może się przecież stać nawet bez cache, bo np. danych może oryginalnie nie być od początku.

W przypadku 2, o ile nie ma jakichś biznesowych gwarancji na to eventual consistency i to nie są jakieś krytyczne dane (typu access-control) to trzymałbym stary stan jeśli nie da się zbudować bardziej aktualnego.

No czyli moja opcja 1.

yarel napisał(a):

Dla mnie cache to takie rozwiązanie problemu szybkości dostępu do danych. Dorzucanie jakiejś logiki, że cache coś tam aktualizuje i pobiera zewnętrznego systemu, ociera się o złamanie SRP (nie zakładam, że rozwiązanie jest obiektowe, ale zasadę można trochę ekstrapolować ;-) ).

No tak, masz rację, to był skrót myślowy z mojej strony. Chodziło mi o klasę, która jest elementem jakiegoś procesu w systemie i zawiera w sobie cache przechowujący dane a także klienta pobierającego dane ze źródła. Tylko to szczegóły implementacji, niezbyt istotne w kontekście problemu.
Odpowiadając na Twoje drugie pytanie - dane do tego faktycznego cache wstawia ta klasa podczas pierwszej potrzeby jej użycia.

katelx napisał(a):

no skoro cache to optymalizacja czasu/kosztu dostepu do danych to gdy danych nie ma to cache przestaje miec znaczenie. jesli cache ma pelnic role "backupu" to zwykle prowadzi to do roznych problemow zwiazanych ze ustalaniem co i kiedy jest prawidlowe. dlatego lepiej te dwie funkcjonalnosci (t.j. cache i backup) separowac jak najwczesniej bo potem w miare dokladania nowych "featuresow" jest tylko gorzej

Dobrze, więc niech będzie backup, a nie cache. Jak to zmienia odpowiedź? :)

Charles_Ray napisał(a):

Moim zdaniem to serwer (jako właściciel danych, źródło prawdy) powinien sterować ważnością danych, które serwuje poprzez np. ustawienie nagłówka Cache-Control.

Pewnie tak, ale tego nie robi.
Zresztą, to to nie zawsze musi mieć sens, bo te same dane mogą mieć różną ważność w różnych kontekstach, a kontekst znają konsumenci, a nie serwer.

Czasem mamy cache, który zakładamy bez świadomości serwera, żeby ograniczyć ruch. W momencie, kiedy serwer padnie zachowałbym się tak samo, jakby tego cache nie było - jeśli minie TTL, to zwracam 503.

Tak, o takim przypadku tutaj mowa, ale o zwracaniu 503 z powodu braku opcjonalnych danych nie ma mowy.

Logika czyszczenia cache (tutaj od razu czerwona lampka) w zależności od zdrowia źródła danych to kiepski pomysł, bo trzeba w jakoś sposób czyścić cache na wszystkich instancjach itd - tutaj fajny wątek: https://www.quora.com/Why-is-cache-invalidation-considered-difficult

No jeśli źródło jest niedostępne, to wszystkie instancje w tym samym czasie nie będą mogły pobrać z niego danych, więc np. cache się samo wyczyści. Nie widzę problemu.

0

co łatwiej będzie debugować za rok nowemu pracownikowi?

dlaczego XYZ ma dane C dodane 1 stycznia, jeżeli od 29 grudnia one nie były dostępne? :D

że co? jakiś mail o awarii tam był?

1 użytkowników online, w tym zalogowanych: 0, gości: 1