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?


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 .


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.