Który magazyn danych jest najlepszy dla mojego scenariusza?

10

Pracuję nad aplikacją, która wymaga bardzo wysokiej wydajności aktualizacji / wyboru zapytań w bazie danych.

Mam tabelę podstawową (A), która będzie zawierała około 500 rekordów dla jednostki na jeden dzień. I dla każdego użytkownika w systemie tworzona jest odmiana tego bytu na podstawie niektórych preferencji użytkownika i są one przechowywane w innej tabeli (B). Odbywa się to przez zadanie crona, które działa codziennie o północy.

Jeśli więc w tabeli A znajduje się 10 000 użytkowników i 500 rekordów, w tabeli B będzie 5 milionów rekordów tego dnia. W tych tabelach zawsze przechowuję dane na jeden dzień, a o północy archiwizuję dane historyczne w HBase. Ta konfiguracja działa dobrze i do tej pory nie mam problemów z wydajnością.

Ostatnio nastąpiła zmiana wymagań biznesowych, a teraz niektóre atrybuty w tabeli podstawowej A (dla 15-20 rekordów) będą się zmieniać co 20 sekund i na tej podstawie muszę ponownie obliczyć niektóre wartości dla wszystkich tych rekordów zmian w tabeli B dla wszyscy użytkownicy. Mimo że zmienia się tylko 20 rekordów głównych, muszę dokonać ponownego obliczenia i zaktualizować 200 000 rekordów użytkowników, co zajmuje więcej niż 20 sekund, a następnie następna aktualizacja nastąpi ostatecznie, w wyniku czego wszystkie zapytania Select zostaną umieszczone w kolejce. Dostaję około 3 żądań / 5 sekund od użytkowników online, co powoduje 6-9 Wybierz zapytania. Aby odpowiedzieć na żądanie interfejsu API, zawsze używam pól w tabeli B.

Mogę kupić większą moc obliczeniową i rozwiązać tę sytuację, ale jestem zainteresowany posiadaniem odpowiednio skalowanego systemu, który może obsłużyć nawet milion użytkowników.

Czy ktoś może tu zaproponować lepszą alternatywę? Czy relacyjna baza danych nosql + mi tu pomaga? Czy są jakieś platformy / magazyny danych, które pozwolą mi często aktualizować dane bez blokowania, a jednocześnie dadzą mi elastyczność uruchamiania wybranych zapytań na różnych polach w jednostce?

Dzbanki
źródło
Czy naprawdę musisz przechowywać wszystkie te dane? Brzmi to trochę tak, jakbyś lepiej obliczać na żądanie. Jeśli możesz obliczyć 200 000 rekordów w nieco ponad 20 sekund, powinno być możliwe obliczenie tych 20 rekordów * 3 użytkowników = 60 rekordów w mgnieniu oka. Być może mógłbyś sprawdzić, którzy użytkownicy są w danym momencie online i jeszcze bardziej zoptymalizować? Wygląda trochę tak, jakbyś generował tony danych, których nikt nigdy nie używa (w tym czasie dane są co najmniej ważne)
Thorsten Müller,
Generowanie tylko dla zalogowanych użytkowników jest bardzo dobrą opcją. Też o tym myślałem, ale wciąż nie jest to podejście skalowalne. Moja platforma będzie używana tylko w ciągu dnia i dlatego w tym czasie większość użytkowników będzie aktywna. Wszelkie inne sugestie, kolego?
Dzbanki
@Jugs - To wciąż pozostawia pytanie, czy można po prostu obliczyć w locie. Czy mają do aktualizacji zapisów, czy też aplikacja wystarczy dane tam być?
Bobson
Obawiam się, że nie mogę obliczyć w locie, ponieważ tabela wpisów B jest uszeregowana dla użytkownika (od 5 gwiazdek do 1 gwiazdki), a po wykonaniu tych obliczeń ponownie przeprowadzamy ranking dla użytkownika. Cały proces dla użytkownika zajmuje 500 ms, a jeśli zrobię to w locie, wpłynie to na czas odpowiedzi API
Jugs
Zastanawiałem się, czy sensowne jest przechowywanie wyników i rankingów poza RDBMS, może znajdować się w db nosql, aby wybrane instrukcje nadal działały bez żadnych problemów, jednak czasami muszę zapytać o wyniki i rangi. Więc jestem w tej chwili trochę zagubiony i dlatego szukam porady u niektórych ekspertów, takich jak wy
Jugs

Odpowiedzi:

1

Wygląda na to, że tabela Bjest rodzajem pamięci podręcznej. Ale tego rodzaju pamięć podręczna, która obniża wydajność ...

Nawet jeśli masz 25 zapytań na sekundę, możesz odmówić użycia tabeliB i obliczyć odpowiedź dla każdego żądania.

W każdym razie , jeśli masz 30 sekund opóźnienia na aktualizację 20 rekordów - jest to błąd w architekturze oprogramowania (mylę się, jeśli twoja DB oblicza pierwsze 10 ^ 100 znaków PI dla każdego rekordu).

Jak wiem, relacyjna baza danych bez brzydkich zapytań SQL, z indeksami i mniej niż 1 000 000 rekordów będzie działać idealnie dla prawie wszystkich zapytań.

Spróbuj odmówić użycia tabeli Bi dodaj do niej odpowiednie indeksy A(większość nowoczesnych baz danych ma narzędzie pomocnicze). Następnie: spróbuj zoptymalizować strukturę danych (tabelę A) i zapytanie (używając analizatora zapytań lub z ekspertami SQL), aby przyspieszyć obliczenia. Jeśli zaktualizujesz tylko 20 rekordów - istnienie indeksów nie zaszkodzi wydajności procesu aktualizacji , ale znacznie poprawi szybkość wyboru .

maxkoryukov
źródło
1

Pytanie naprawdę brzmi, jaki system oblicza rekord do wstawienia do B i jaki jest rozmiar danych B.

Każda baza danych (np. MSSQL) powinna być w stanie obsłużyć liczbę wstawek, o których mówisz, bez problemu, zakładając, że obiekt nie jest ogromny.

Aktualizacje mogą być trudniejszym problemem, ale przy odpowiednim indeksowaniu i blokowaniu znowu nie powinno być dużym problemem.

99% czasu, kiedy widzę taki problem, wynika z obliczenia rekordu B przez zapisany proc. Spowoduje to obciążenie całego serwera db

W takim przypadku rozwiązaniem jest przeniesienie tego kodu do usługi offline, którą można wywołać za pośrednictwem systemu kolejkowania.

Tak więc komunikat o aktualizacji A uruchomiłby proces roboczy, który przechodziłby przez użytkowników i tworzyłby komunikat o aktualizacji B dla każdego użytkownika

Drugi proces roboczy B pobierałby aktualizację Użytkownik X z danymi Zdarzenie A tworzył rekord B i aktualizował DB

Można to skalować, dodając więcej pól z robotami kolejkowymi, dzięki czemu masz więcej mocy obliczeniowej za obliczeniami, pozostawiając db swobodnie koncentrować się na aktualizacjach i selekcjach.

możesz dalej optymalizować, oddzielając selekcje od aktualizacji / wstawek. mają nową bazę danych, która pobiera wszystkie wybrane żądania, jako podrzędną replikację, stara baza danych, która pobiera wszystkie aktualizacje.

Ewan
źródło
0

Jeśli pracujesz w Amazon, rozważę DynamoDB. Opiera się na pamięci flash. Oto link do niego: https://aws.amazon.com/dynamodb/ .

Jakiego rodzaju RDBMS używasz? Możesz zwiększyć wydajność, używając UDF lub pola obliczeniowego w widoku. Czy przeprowadzasz obliczenia w bazie danych za pomocą pojedynczego zapytania aktualizacyjnego, czy wybierasz dane z bazy danych, uruchamiasz obliczenia w innym procesie, a następnie ładujesz je z powrotem?

Oracle jest domyślnie skonfigurowany do korzystania z trybu migawki, co oznacza, że ​​wiersze nie są blokowane podczas aktualizacji, a jednoczesne wybory uzyskują oryginalną wartość. SQL Server jest domyślnie skonfigurowany z pesymistyczną współbieżnością, więc jednoczesne wybory będą blokować do czasu zakończenia aktualizacji. Niektóre wersje programu SQL Server można przełączyć w tryb migawki, jednak znacznie zwiększa to obciążenie tabeli tymczasowej.

W jakim środowisku pracujesz? Jeśli jest to RDBMS w instancji EC2 w Amazon, spróbuj umieścić pliki danych DB na lokalnym dysku flash. Widziałem różnicę wielkości rzędu podczas przenoszenia plików z EBS na dysk lokalny.

Robert-Ryan.
źródło