Zapytania w czasie rzeczywistym na dużą skalę

W tym dokumencie znajdziesz wskazówki dotyczące skalowania aplikacji bezserwerowych ponad tysiące operacji na sekundę lub setek tysięcy w tym samym czasie. Ten dokument zawiera zaawansowane tematy pomocne aby dokładnie zrozumieć system. Jeśli dopiero zaczynasz przygodę z Cloud Firestore, przeczytaj krótki przewodnik.

Cloud Firestore oraz pakiety SDK Firebase do aplikacji mobilnych i internetowych zapewniają zaawansowany model tworzenia aplikacji bez serwera, w których kod po stronie klienta bezpośrednio uzyskuje dostęp do bazy danych. Pakiety SDK umożliwiają klientom odbieranie aktualizacji danych w czasie rzeczywistym. Ty mogą używać aktualizacji w czasie rzeczywistym do tworzenia elastycznych aplikacji, które nie wymagają serwera i infrastrukturze. O ile to bardzo łatwe, aby zrozumieć ograniczenia w systemach, które składają się na Cloud Firestore aby bezserwerowa aplikacja była skalowana i działała dobrze w miarę wzrostu natężenia ruchu.

W poniższych sekcjach znajdziesz porady dotyczące skalowania aplikacji.

Wybierz lokalizację bazy danych blisko użytkowników

Ten schemat przedstawia architekturę aplikacji działającej w czasie rzeczywistym:

Przykładowa architektura aplikacji w czasie rzeczywistym

Gdy aplikacja uruchomiona na urządzeniu użytkownika (w przeglądarce lub na urządzeniu mobilnym) tworzy połączenie połączenie z Cloud Firestore, jest kierowane do Cloud Firestore serwer frontendu w tym samym region, w którym znajduje się baza danych. Przykład: jeśli baza danych znajduje się w regionie us-east1, połączenie będzie również kierowane do Frontend Cloud Firestore również w środowisku us-east1. Te połączenia są długotrwałe i pozostają otwarte, dopóki aplikacja ich nie zamknie. Frontend odczytuje dane z podstawowych systemów pamięci masowej Cloud Firestore.

Odległość między fizyczną lokalizacją użytkownika a lokalizacją bazy danych Cloud Firestore ma wpływ na opóźnienie odczuwane przez użytkownika. Na przykład użytkownik z Indiek, którego aplikacja komunikuje się z bazą danych w regionie Google Cloud w Ameryce Północnej, może zauważyć wolniejsze działanie aplikacji i mniejsze płynność niż w przypadku bazy danych znajdującej się bliżej, np. w Indiach lub w innej części Azji.

Projektowanie z myślą o niezawodności

Te tematy zwiększają niezawodność aplikacji lub wpływają na nią:

Włącz tryb offline

Pakiety SDK Firebase zapewniają trwałość danych offline. Jeśli aplikacja na urządzeniu użytkownika nie może połączyć się z siecią Cloud Firestore, można nadal z niej korzystać, korzystając z danych w lokalnej pamięci podręcznej. Dzięki temu użytkownicy będą mieli dostęp do danych nawet wtedy, gdy ich połączenie z internetem będzie niestabilne lub całkowicie utracą dostęp na kilka godzin lub dni. Więcej informacji: w trybie offline – przeczytaj artykuł Włączanie danych offline.

Automatyczne ponowne próby

Pakiety SDK Firebase zajmują się ponawianiem operacji i przywracaniem zerwane połączenia. Pomaga to obejść przejściowe błędy spowodowane przez ponowne uruchomienie serwerów lub problemy z siecią między klientem a w bazie danych.

Wybieranie lokalizacji w wielu regionach lub w wielu regionach

Wybór między regionem a regionem wiąże się z wieloma kompromisami. znajdujących się w wielu regionach. Główna różnica dotyczy sposobu replikacji danych. To zapewnia dostępność gwarantowaną przez aplikację. Instancji w wielu regionach zapewnia większą niezawodność wyświetlania i zwiększa trwałość danych, ale kosztem jest koszt.

Omówienie systemu zapytań w czasie rzeczywistym

Zapytania w czasie rzeczywistym (nazywane też detektorami zrzutów) pozwalają aplikacji nasłuchiwać zmian w bazie danych i otrzymywać powiadomienia o krótkim czasie oczekiwania, gdy dane zmian. Aplikacja może uzyskać ten sam wynik, okresowo odpytując bazę danych pod kątem ale często jest to wolniejsze, droższe i wymaga więcej kodu. Dla: jak konfigurować i używać zapytań w czasie rzeczywistym: Aktualizacje w czasie rzeczywistym W poniższych sekcjach szczegółowo opisać działanie detektorów zrzutów i opisać niektóre ze sprawdzonymi metodami skalowania zapytań w czasie rzeczywistym przy zachowaniu wydajności.

Wyobraź sobie 2 użytkowników, którzy łączą się z usługą Cloud Firestore za pomocą wiadomości za pomocą jednego z mobilnych pakietów SDK.

Klient A zapisuje w bazie danych, aby dodawać i aktualizować dokumenty w kolekcji pod tytułem chatroom:

collection chatroom:
    document message1:
      from: 'Sparky'
      message: 'Welcome to Cloud Firestore!'

    document message2:
      from: 'Santa'
      message: 'Presents are coming'

Klient B nasłuchuje aktualizacji w tej samej kolekcji za pomocą detektora zrzutów. Klient B otrzymuje natychmiastowe powiadomienie, gdy ktoś utworzy nową wiadomość. Ten diagram przedstawia architekturę odbiorcy zrzutu:

Architektura połączenia odbiornika zrzutu

Poniższa sekwencja zdarzeń ma miejsce, gdy Klient B połączy zrzut dysku detektor bazy danych:

  1. Klient B otwiera połączenie z serwerem Cloud Firestore i rejestruje słuchacza, nawiązując połączenie z numerem onSnapshot(collection("chatroom")) przez pakiet SDK Firebase. Ten odbiornik może być aktywny przez wiele godzin.
  2. Frontend Cloud Firestore wysyła zapytania do podstawowego systemu magazynowania, aby zainicjować zbiór danych. Wczytuje on cały zbiór wyników dokumenty. Nazywamy to zapytaniem ankietowym. System oceniane jest w ramach Reguły zabezpieczeń Firebase do sprawdź, czy użytkownik ma dostęp do tych danych. Jeśli użytkownik jest autoryzowany, zwraca dane użytkownikowi.
  3. Zapytanie Klienta B przechodzi do trybu nasłuchiwania. Rejestrator się rejestruje z modułem obsługi subskrypcji i czeka na aktualizacje danych.
  4. Klient A wysyła teraz operację zapisu, aby zmodyfikować dokument.
  5. Baza danych zatwierdza zmianę w dokumencie systemu pamięci masowej.
  6. Transakcyjnie system zatwierdza tę samą aktualizację dla wewnętrznego dziennik zmian. Dziennik zmian określa rygorystyczną kolejność zmian, i tak się dzieje.
  7. Zmiany są następnie rozprowadzane do puli obsługi subskrypcji.
  8. Wykonywane jest odwrotne dopasowywanie zapytań, aby sprawdzić, czy zaktualizowany dokument pasuje do dowolnego z obecnie zarejestrowanych odbiorników migawek. W tym przykładzie dokument pasuje do detektora zrzutów klienta B. Jak sama nazwa wskazuje, funkcję dopasowywania odwrotnego zapytania, jak w przypadku normalnego zapytania do bazy danych, ale wykonywane w odwrotnej kolejności. Zamiast przeszukiwać dokumenty w celu znalezienia tych, które pasują do zapytania, skutecznie przeszukuje zapytania, aby znaleźć te, które pasują do przychodzącego dokumentu. Po znalezieniu dopasowania system przekaże odpowiedni dokument detektorom zrzutu. Następnie system ocenia reguły zabezpieczeń Firebase tej bazy danych. , aby mieć pewność, że tylko autoryzowani użytkownicy otrzymają dane.
  9. system przekaże aktualizację dokumentu do pakietu SDK na urządzeniu klienta B oraz uruchomi się wywołanie zwrotne onSnapshot. Jeśli włączona jest trwała lokalna, pakiet SDK spowoduje zastosowanie aktualizacji również do lokalnej pamięci podręcznej.

Kluczowa część skalowalności funkcji Cloud Firestore zależy od rozpowszechniania do modułów obsługi subskrypcji i serwerów frontendu. pozwala na skuteczne rozpowszechnienie pojedynczej zmiany danych w milionach zapytań w czasie rzeczywistym i połączenia z użytkownikami. Przez uruchomienie wielu replik wszystkich tych komponenty w wielu strefach (lub wielu regionach w przypadku wielu regionów, wdrożenia), Cloud Firestore zapewnia wysoką dostępność i skalowalność.

Warto zauważyć, że wszystkie operacje odczytu wykonywane z mobilnych i internetowych pakietów SDK z użyciem powyższego modelu. Wykonują zapytanie odpytywania, a potem tryb nasłuchiwania w celu zachowania gwarancji spójności. Dotyczy to też detektorów w czasie rzeczywistym, wywołań służących do pobierania dokumentu oraz zapytań jednorazowych. Wybieranie pojedynczych dokumentów i jednorazowe zapytania można traktować jako krótkotrwałych słuchaczy zrzutów, którzy mają podobne ograniczenia dotyczące wydajności.

Stosowanie sprawdzonych metod skalowania zapytań w czasie rzeczywistym

Aby projektować skalowalne zapytania w czasie rzeczywistym, stosuj te sprawdzone metody.

Informacje o dużym ruchu zapisu w systemie

Z tej sekcji dowiesz się, jak system reaguje na rosnącą liczbę próśb o zapisywanie.

Cloud Firestore dzienniki zmian, które generują zapytania w czasie rzeczywistym automatycznie skalują się w poziomie w miarę wzrostu natężenia ruchu związanego z zapisem. Jako że szybkość zapisu dla bazy danych rośnie ponad możliwa do obsłużenia pojedynczy serwer, jest dzielone między wiele serwerów, a przetwarzanie zapytań rozpoczyna się wykorzystują dane z kilku modułów obsługi subskrypcji, a nie z jednego. Z poziomu z perspektywy klienta i pakietu SDK, że wszystko jest przejrzyste i nie trzeba podejmować żadnych działań. z aplikacji, gdy następuje podział. Poniższy diagram pokazuje, skala zapytań w czasie rzeczywistym:

Architektura rozgałęzienia historii zmian

Automatyczne skalowanie umożliwia zwiększanie ruchu zapisu bez ograniczeń, ale wraz ze wzrostem natężenia ruchu system może potrzebować więcej czasu na reakcję. Postępuj zgodnie z zaleceniami dotyczącymi reguły 5–5–5, aby uniknąć tworzenia obszaru roboczego zapisu. Key Visualizer to przydatne narzędzie do analizowania obszarów interaktywnych zapisu.

Wiele aplikacji notuje przewidywalny wzrost organiczny, który Cloud Firestore może bez stosowania środków ostrożności. Zadania wsadowe, takie jak importowanie dużych może jednak zbyt szybko przyspieszyć zapisy. Podczas projektowania aplikacji nie opuszczaj tego, skąd pochodzi ruch związany z zapisem.

Jak działają zapisy i odczyty

System zapytań w czasie rzeczywistym można traktować jak potok łączący zapis operacji na czytnikach. Po utworzeniu, zaktualizowaniu lub usunięciu dokumentu zmiana zostanie przeniesiona z systemu pamięci masowej do obecnie zarejestrowanego słuchaczom. Struktura historii zmian w Cloud Firestore gwarantuje wysoką co oznacza, że aplikacja nie będzie nigdy otrzymywać aktualizacje, które są niezgodne z datą zatwierdzenia danych przez bazę danych zmian. Ułatwia to tworzenie aplikacji przez usunięcie przypadki skrajne związane ze spójnością danych.

Ten połączony potok oznacza, że operacja zapisu powodująca hotspoty lub rywalizacji o blokady mogą negatywnie wpływać na operacje odczytu. Gdy operacje zapisu nie powiodą się lub dochodzi do ograniczenia, odczyt może czekania na spójne dane z historii zmian. Jeśli tak się stanie w Twojej aplikacji, możesz zauważyć zarówno wolne operacje zapisu, jak i powiązane z nimi długie czasy odpowiedzi na zapytania. Unikanie takich obszarów to klucz do uniknięcia .

Przechowuj dokumenty i zapisuj niewielkie operacje

Gdy tworzysz aplikacje z detektorami zrzutów, zwykle chcesz, aby użytkownicy o zmianach danych. Aby osiągnąć ten cel, staraj się unikać drobnych rzeczy. może przesyłać do systemu niewielkie dokumenty z dziesiątkami pól, szybko. Większe dokumenty z setkami pól i dużymi danymi wymagają więcej czasu do przetwarzania.

Z kolei, aby skrócić czas oczekiwania, preferuj krótkie i szybkie operacje zatwierdzania oraz zapisu. Duże wsady mogą zapewnić większą przepustowość z punktu widzenia autora ale może wydłużyć czas powiadomienia detektorów zrzutów. Jest to często nieintuicyjne w porównaniu z użyciem innych systemów baz danych, w których do poprawy wydajności można użyć grupowania.

Używaj wydajnych detektorów

Wraz ze wzrostem szybkości zapisu bazy danych Cloud Firestore rozdziela przetwarzanie danych na kilka serwerów. Algorytm fragmentacji Cloud Firestore próbuje współlokować dane z tę samą kolekcję lub grupę kolekcji na tym samym serwerze historii zmian. system próbuje zmaksymalizować możliwą przepustowość zapisu, zachowując liczbę jak najmniej liczby serwerów zaangażowanych w przetwarzanie zapytania.

Pewne wzorce mogą jednak nadal prowadzić do nieoptymalnego działania funkcji migawki. słuchaczom. Jeśli na przykład aplikacja przechowuje większość danych w jednym może być konieczne nawiązanie połączenia z wieloma serwerami, potrzebnych danych. Dzieje się tak nawet po zastosowaniu filtra zapytania. Łączenie do wielu serwerów zwiększa ryzyko wolniejszych odpowiedzi.

Aby uniknąć tych wolniejszych odpowiedzi, zaprojektuj schemat i aplikację tak, aby system może obsługiwać detektory bez konieczności przechodzenia do wielu różnych serwerów. Może to zadziałać najlepiej jest podzielić dane na mniejsze zbiory o mniejszych szybkościach zapisu.

Przypomina to analizowanie zapytań dotyczących skuteczności w relacyjnej bazie danych, która wymaga pełnego skanowania tabel. W relacji bazy danych, zapytanie wymagające pełnego skanowania tabeli jest odpowiednikiem detektor zrzutów, który ogląda kolekcję o wysokim prawdopodobieństwie rezygnacji. Może działać wolniej w porównaniu z zapytaniem, które baza danych może udostępniać przy użyciu bardziej szczegółowego indeksu. Zapytanie o bardziej szczegółowym indeksie jest jak detektor zrzutów, który obserwuje do pojedynczego dokumentu lub kolekcji, które rzadziej się zmieniają. Należy wczytać przetestować aplikację, aby jak najlepiej zrozumieć zachowanie i potrzeby danego przypadku użycia.

Szybkie odpytywanie

Kolejnym ważnym elementem zapytań w czasie rzeczywistym jest upewnienie się, że zapytanie do pobierania danych jest szybkie i wydajne. Przy pierwszym połączeniu z nowym detektorem zrzutu musi on wczytać cały zestaw wyników i wysyłanie go na urządzenie użytkownika. Powolne zapytania tworzą aplikację mniej elastycznie. Obejmuje to na przykład zapytania, które spróbuj odczytać wiele dokumentów lub zapytań, które nie korzystają z odpowiednich indeksów.

Słuchacz może też wrócić ze stanu odtwarzania do stanu sondowania w w pewnych okolicznościach. Dzieje się to automatycznie i nie wymaga interwencji ze strony SDK ani aplikacji. Stan odpytywania może być wywołany przez te warunki:

  • System równoważy historię zmian z powodu zmian obciążenia.
  • Hotspoty powodują nieudane lub opóźnione zapisy w bazie danych.
  • Tymczasowe ponowne uruchomienie serwera ma tymczasowo wpływ na detektory.

Jeśli zapytania odpytywania są wystarczająco szybkie, stan sondowania staje się przezroczysty użytkownikom aplikacji.

Wspieranie długoterminowych słuchaczy

Otwarcie słuchaczy i utrzymanie ich uwagi jest często oszczędny sposób na stworzenie aplikacji, która korzysta z Cloud Firestore. W przypadku użycia funkcji Cloud Firestore, płacisz za dokumenty zwrócone do aplikacji a nie utrzymywania otwartego połączenia. Długotrwały odczyt detektora zrzutów tylko dane potrzebne do obsługi zapytania przez cały okres jego istnienia. Ten obejmuje początkową operację odpytywania, po której następują powiadomienia, gdy dane naprawdę się zmienia. Zapytania jednorazowe umożliwiają natomiast ponowne odczytanie danych, nie uległy zmianie od ostatniego wykonania zapytania przez aplikację.

W przypadkach, gdy aplikacja musi zużywać dużą ilość danych, detektory zrzutów może być nieodpowiedni. Jeśli na przykład Twój przypadek użycia generuje wiele dokumentów na sekundę przy wykorzystaniu połączenia przez dłuższy czas, lepiej wybrać zapytania jednorazowe z mniejszą częstotliwością.

Co dalej