Tło :
Stworzyłem aplikację internetową, którą chciałbym móc odpowiednio skalować. Wiem, że nie jestem Google ani Twitterem, ale moja aplikacja używa dość dużej ilości danych dla każdego użytkownika, a zatem ma dość wysokie wymagania dotyczące danych. Chcę być gotowy do skalowania w miarę dobrze bez konieczności późniejszej zmiany architektury.
Uważam się za programistę, a nie eksperta od baz danych. Dlatego piszę tutaj. Mam nadzieję, że ktoś z dużo większą wiedzą na temat baz danych może mi doradzić.
Przy względnie dużej liczbie użytkowników, ale nie takich jak numery na Facebooku, oczekuję, że będę mieć DB, która wygląda następująco:
Jeden „duży stół”:
- 250 milionów rekordów
- 20 kolumn
- Około 100 GB danych
- Ma indeksowany klucz obcy bigint (20)
- Ma indeksowaną kolumnę varchar (500) string_id
- Ma kolumnę „wartość” int (11)
4 inne tabele:
- 10 milionów rekordów każdy
- Po około 2–4 GB danych
- każda z tych tabel ma 4–8 kolumn
- jedna kolumna jest datowana data_tworzona
- jedna kolumna jest kolumną varchar (500) string_id
- jedna lub dwie kolumny z każdej z tych tabel zostaną wybrane w złączeniu
Jedna z tych tabel jest używana do przechowywania średnich - jej schemat to bigint (20) id, varchar (20) string_id, data-godzina utworzona, zmiennoprzecinkowa wartość średnia
Co chcę zrobić - dwa stosunkowo drogie zapytania:
Oblicz nowe średnie wartości:
- Używając klucza obcego, wybierz do kilku milionów oddzielnych rekordów z dużej tabeli.
- Oblicz nową średnią, grupując według string_id.
- Wstaw wyniki do tabeli średnich.
- W tej chwili w tej kwerendzie używane są dwa sprzężenia.
Twórz zdenormalizowane rekordy tylko do odczytu do obsługi użytkowników:
- Za pomocą klucza obcego wybierz dowolne miejsce spośród 1000–40 000 rekordów z dużego stołu.
- Połącz z każdą z pozostałych czterech tabel najnowszego rekordu za pomocą kolumny id łańcucha.
- Wstaw wyniki do zdenormalizowanej tabeli.
- Te rekordy są używane przez interfejs użytkownika do wyświetlania informacji użytkownikom.
- W tej chwili w tej kwerendzie używane są cztery sprzężenia.
Planuję uruchomić każde z tych drogich zapytań w bazie danych zaplecza wsadowego, która przekaże wyniki do front-endowego serwera DB w czasie rzeczywistym, który obsługuje żądania od użytkowników. Te zapytania będą uruchamiane w regularnych odstępach czasu. Nie zdecydowałem, jak często. Średnie zapytanie może być wykonane raz dziennie. Zapytanie o znormalizowanie będzie musiało być częstsze - może co kilka minut.
Każde z tych zapytań jest obecnie uruchamiane w MySQL w ciągu kilku sekund na bardzo niskiej jakości komputerze z zestawem danych z 100 000 rekordów w „dużej tabeli”. Martwi mnie zarówno moja zdolność do skalowania, jak i koszty skalowania.
Pytania :
- Czy to podejście wydaje się uzasadnione? Czy jest z tym coś złego z dużej perspektywy?
- Czy RDBMS jest właściwym narzędziem, czy powinienem spojrzeć na inne rozwiązania „big data”, takie jak coś w rodzinie Hadoop? Moją skłonnością jest używanie RDBMS, ponieważ dane są ustrukturyzowane i ładnie pasują do modelu relacyjnego. Jednak w pewnym momencie rozumiem, że mogę już nie być w stanie korzystać z RDBMS. Czy to prawda? Kiedy ten przełącznik będzie potrzebny?
- Czy to zadziała? Czy zapytania te można uruchomić w rozsądnym czasie? Mogę poczekać godziny na zapytanie nr 1, ale zapytanie nr 2 powinno zakończyć się za kilka minut.
- Co powinienem rozważyć z perspektywy sprzętowej? Jakie mogą być wąskie gardła mojej pamięci RAM i procesora? Zakładam, że utrzymanie indeksów w pamięci RAM jest ważne. Czy jest jeszcze coś, co powinienem rozważyć?
- W pewnym momencie prawdopodobnie będę musiał podzielić moje dane na partycje i korzystać z wielu serwerów. Czy mój przypadek użycia wydaje się, że jest już w tej kategorii, czy też będę mógł przez jakiś czas przeskalować pojedynczą maszynę? Czy to zadziała z 10-krotnością danych? 100x?