Szybka baza danych lub szybki cache z zapisem na dysk

1

Przymierzam się do nowszego projektu i zastanawiam się nad wyborem rozwiązania - pewnie jakiejś bazy danych (choć niekoniecznie).

Taki opis czego szukam:

  • musi być bardzo szybka i ogarniać jednocześnie duże ilości danych
  • samych tabel nie będzie dużo
  • bez żadnych update'ów czy usuwania danych (chyba, że w jakichś sytuacjach awaryjnych, ale wtedy można przyjąć że cały system leży i admin sobie będzie mógł grzebać do woli)
  • będą za to raczej skomplikowane query czytające duże ilości rekordów
  • raczej musi być programowalna - tj. zapis jednego rekordu będzie tworzył kilka rekordów (a z powodu wolumenu danych nie chcemy tego słać po sieci)
  • dobrze by było, żeby były relacje, ale nie jest to warunek konieczny
  • może być jakaś rozproszona, jeśli tylko nie będzie to miało wpływu na latency
  • na razie załóżmy, że infrastruktura jest dostępna w dowolnych ilościach, natomiast będzie stała na tyle daleko, że ruch sieciowy jest problemem
  • załóżmy też, że programiści którzy będą pracować na projekcie będą ogarnięci, więc nauka jakiegoś dziwnego języka nie jest problemem
  • po trzech-czterech dniach będą mogły być archiwizowane (tj. z punktu widzenia bazy danych - usunięte)
  • jeśli baza padnie to dane muszą być dostępne po starcie, więc samo in-memory odpada
  • jeśli chodzi o ramy czasowe to tak z 80% ruchu będzie się odbywać w ciągu 1:00 - 13:00, jakoś tak między 20:00-21:00 można będzie robić przerwę techniczną (np. wspomniane czyszczenie danych)
  • selecty będą głównie latały po danych z ostatniego dnia (na starym systemie to ok. 95% zapytań) i to one mają priorytet jeśli chodzi o czasy wykonywania.

Ewentualnie może ktoś ma inne propozycje, np. jakiś szybki cache + baza danych. Oczywiście nie chciałbym tego wszystkiego pisać prawie od zera (też padł taki pomysł), jedynie zestawić i oprogramować już istniejące rozwiązania - więc pytam o wasze doświadczenia.

2

Pytanie co oznacza wiele rekordów, bo dla jednego to 1e6, dla drugiego 1e9. Prawda nieobjawiona jest taka, że nie ma czegoś takiego jak relacyjna baza danych o dużej wydajności w zapisie i odczycie.

Czy potrzebujesz transakcyjności, czy wystarczy ci eventual consistency?
Bo mogę sobie to wyobrazić tak, że dane wlatują do jakiejś kolejki, za kolejka jest usługa, która je ładuje asynchronicznie do DB ze strukturą przygotowaną do odczytu.
Ewentualnie rozgłaszasz te dane jakimś topic'iem, za każdy z zelektów odpowiada osobna usługa, która robi na nich reduce i uaktualnia wynik każdego z tych rozbuchanych zapytań.

Jeżeli to naprawdę ma szybko działać i przetwarzać naprawdę dużo danych, to czeka cię zagłębienie się w big data. Czyli np. to map/reduce.
Czy casłość musi być on-premise, czy mogą to być usługi chmurowe?

https://cloud.google.com/products/#section-7
https://cloud.google.com/products/#section-8

0

Ile terabajtów na sekundę ma obsługiwać baza? Bo od tego wiele zależy

0

I co to za dane.

2

Strzał: Redis!
Używam i sobię chwalę, płacę, znaczy inwestorzy płacą xD

0

@piotrpo:

  1. W tej chwili "dużo" to ok. sześć miliardów rekordów wejściowych na te dwanaście godzin, (czyli jakieś 200 tys. na sekundę) natomiast będą wzrosty.
  2. eventual consistency raczej odpada.
  3. Jeżeli to naprawdę ma szybko działać i przetwarzać naprawdę dużo danych, to czeka cię zagłębienie się w big data - swoje doświadczenia mam, natomiast pytam innych :)
  4. Czy casłość musi być on-premise, czy mogą to być usługi chmurowe? - dane nie mogą być przechowywane w publicznej chmurze, natomiast jeśli coś da się zainstalować na mocnej maszynie to możemy negocjować.

@anonimowy: nie wiem, czy istnieje system ogarniający terabajty w real-time z SLA na poziomie minuty.

@S4t: wartości liczbowe (głównie floaty, long/timestamp), ewentualnie wartości, które da się łatwo przetłumaczyć na liczby (tj. enumy)

@lion137: też biorę opcję z cache'm pod uwagę, chociaż nie Redis.

1

Wejście na kafkę, za kafką usługi wyliczające wyniki, albo zbiór usług map-reduce?

0

To moze cos dla serii czasowych. Jakis influx osłoniety kafka albo jakas kolejka.

0

Dzięki za odpowiedzi, natomiast bardziej chodziło mi o nieco konkretniejsze rozwiązania.
Sam problem patrząc na dużych klockach nie jest jakoś specjalnie skomplikowany bo sprowadza się do czegoś in-memory z opcją zapisu na dysk. Jako, że jedynie dopisujemy rekordy to oczywiście mamy jakiś format kolumnowy.

Tyle tylko, że diabeł tkwi w szczegółach w stylu:

  • jaka baza in-memory?
  • jak konkretnie zapisywać dane na dysk?

Tak jak napisałem - mam swoje pomysły (których celowo nie podaję), i pytam czy może ktoś może pracował przy podobnych problemach i zna jakieś konkretne produkty. Oczywiście jeśli ktoś pracował przy obróbce danych w real-time i robił to inaczej to też z chęcią poczytam, jak wyglądał system :)

Samym streamingiem typu Kafka Streams niestety sprawy nie rozwiążę - bo te selecty będą robione ad-hoc, więc nie można sobie tworzyć raportów na zaś.

0

To może Apache Druid?

0

Troche za malo informacji zeby powiedziec jaka baza tak na 100%. To by trzeba wiedzieć co.sie będzie działo z tymi danymi. Jak często itp itd. 6 miliardów rekordów tez nie wiele mówi jak nie wiadomo jak dużo to danych czy to jakies dane ustruktyrozowane czy nie. Czy masz mieć zapis synchroniczny czy nie. Czy utrata jakis danych boki czy nie. Itp.

0

Pierwsze o czym pomyślałem, to DynamoDB z dax-em(https://aws.amazon.com/dynamodb/dax/).

Wydaje mi się, że musisz podać trochę więcej szczegółów, żeby można było wybrać najlepsze rozwiązanie.

Mówiąc, że masz skomplikowane zapytania, masz na myśli skakanie po 'secondary' indeksach, czy dużą ilość danych?

Strong consistency - przy zapisywaniu czy odczytywaniu? Czy obydwu?

0

Może nie do końca jeszcze rozumiem wymagania, ale być może biorąc pod uwagę to jakie zapytania trzeba robić, to ClickHouse by było dobrym pomysłem?

3

Jak dla mnie za mało danych w wymaganiach. Szybkość będzie wynikała z infrastruktury (ograniczenie fizyczne na prędkość przetwarzania) + architektury przetwarzania danych (ile z tej infrastruktury da się faktycznie wyciągnąć). Skoro infrastruktura jest nieograniczona, to trzeba wybrać skalowalną architekturę przetwarzania danych.

Pojedyncza baza prędzej czy później osiągnie limity (np. brak miejsca na dodatkowe cpu czy kości pamięci), więc szedłbym w rozproszone przetwarzanie (klaster bazodanowy - np. postgres na sterydach, klaster obliczeniowy + skalowalny storage - np. HDFS + Spark). Niezależnie od wybranego rozwiązania trzeba się będzie mocno pochylić nad fizyczną organizacją danych (tak, by z infrastruktury wyciągnąć ile się da, np. przechowywanie kolumnowe w bazach, czy parquet files, do tego partycjonowanie pod kątem zapytań - np. po czasie)

W tej chwili "dużo" to ok. sześć miliardów rekordów wejściowych na te dwanaście godzin, (czyli jakieś 200 tys. na sekundę) natomiast będą wzrosty.

na razie załóżmy, że infrastruktura jest dostępna w dowolnych ilościach, natomiast będzie stała na tyle daleko, że ruch sieciowy jest problemem

Jak bardzo słaba jest sieć? Przy 200k rekordach na sekundę, jak szybka musi być sieć, żeby te dane udało się wypchnąć do zapisu w zakładanym czasie? (Tu nie wiadomo jaki jest rozmiar rekordu, i czy 200k to faktycznie na sekundę, czy jednak obciązenie wygląda w czasie inaczej, np. 95% odczytów w godzinach pracy użytkowników, zaś zapisy poza godzinami pracy).

I jak szybko warstwa przechowująca dane musi być w stanie je zapisywać? Jak szybko zapytania powinny zwracać wynik? (=Jak szybko trzeba czytać dane z pamięci, czy dysków).

0

głosuję na PostgreSQL

0
dmw napisał(a):

Pierwsze o czym pomyślałem, to DynamoDB z dax-em(https://aws.amazon.com/dynamodb/dax/).

Też właśnie o tym czytam.

Mówiąc, że masz skomplikowane zapytania, masz na myśli skakanie po 'secondary' indeksach, czy dużą ilość danych?

Dużą ilość danych i zagnieżdżone zapytania.

Strong consistency - przy zapisywaniu czy odczytywaniu? Czy obydwu?

Jeśli masz oddzielne tabele A oraz B, to kiedy użytkownik zrobi "SELECT A.x, B.y WHERE A.businessId = 1 AND B.businessId = 1" to powinien dostać spójne informacje. Może dostać info sprzed powiedzmy 15 sekund, ale nie może dostać info z teraz dla A.x i sprzed 15 sekund dla B.y.

yarel napisał(a):

Jak dla mnie za mało danych w wymaganiach. Szybkość będzie wynikała z infrastruktury (ograniczenie fizyczne na prędkość przetwarzania) + architektury przetwarzania danych (ile z tej infrastruktury da się faktycznie wyciągnąć). Skoro infrastruktura jest nieograniczona, to trzeba wybrać skalowalną architekturę przetwarzania danych.

Nie powiedziałbym, że to musi koniecznie być skalowalne. Tj. na pewno to, co jest przed tym systemem i docelowy storage skalowalny być musi, natomiast samo obciążenie tego konkretnego kawałka nie będzie rosnąć w nieskończoność.

Pojedyncza baza prędzej czy później osiągnie limity (np. brak miejsca na dodatkowe cpu czy kości pamięci), więc szedłbym w rozproszone przetwarzanie (klaster bazodanowy - np. postgres na sterydach, klaster obliczeniowy + skalowalny storage - np. HDFS + Spark). Niezależnie od wybranego rozwiązania trzeba się będzie mocno pochylić nad fizyczną organizacją danych (tak, by z infrastruktury wyciągnąć ile się da, np. przechowywanie kolumnowe w bazach, czy parquet files, do tego partycjonowanie pod kątem zapytań - np. po czasie)

Właśnie po to będzie rotowanie danych - docelowo dane będą leżały na jakimś dysku/S3/cokolwiek bo ta baza nie ma być takim źródłem wiedzy. Daje to sporą elastyczność bo np. można trzymać dane z bieżącego dnia w jednej tabeli, a z poprzednich dwóch dni w innej.

Jak bardzo słaba jest sieć? Przy 200k rekordach na sekundę, jak szybka musi być sieć, żeby te dane udało się wypchnąć do zapisu w zakładanym czasie? (Tu nie wiadomo jaki jest rozmiar rekordu, i czy 200k to faktycznie na sekundę, czy jednak obciązenie wygląda w czasie inaczej, np. 95% odczytów w godzinach pracy użytkowników, zaś zapisy poza godzinami pracy).

Załóżmy, że dostarczanie wiadomości jest poza scope'm problemu (to jest oddzielne zagadnienie i tego się niestety nie przeskoczy). Chodzi o to, żeby można było robić wspomniane zapytania bezpośrednio wewnątrz systemu, tak, żeby klient nie czekał na wykonanie query tej minuty.
Jeśli chodzi o sieć to tutaj mamy pewną elastyczność, tj. załóż, że możemy sobie zestawić system tak, żeby komunikacja pomiędzy elementami była niewielka.
Wszystkie odczyty są w godzinach pracy użytkowników, na które przypada ok. 80% zapisów.

I jak szybko warstwa przechowująca dane musi być w stanie je zapisywać? Jak szybko zapytania powinny zwracać wynik? (=Jak szybko trzeba czytać dane z pamięci, czy dysków).

Zapis powinien nie być bottleneckiem, tj. chodzi o to, żeby odbywało się to mniej więcej na bieżąco.

Ogólnie to sprawa jest rozwojowa, bo w tej chwili zajmuję się sprawdzaniem, jak wygląda struktura zapisywanych danych (tj. na pewno będzie można filtrować przychodzące rekordy - ale nie mam pojęcia, czy odrzucone rekordy to będzie 5% czy 20%, ani też na jakiej zasadzie będą filtrowane). W tej chwili właśnie w tym upatruję największych zysków, natomiast czy oraz ile da się z tego wyciągnąć - nie wiem.

anonimowy napisał(a):

To może Apache Druid?

Raczej Pinot bo mamy człowieka, który się w tym rozeznaje. Natomiast nie jest to ostateczna decyzja.

@enedil: sprawdzę ClickHouse, dzięki.

0
wartek01 napisał(a):
dmw napisał(a):

Mówiąc, że masz skomplikowane zapytania, masz na myśli skakanie po 'secondary' indeksach, czy dużą ilość danych?

Dużą ilość danych i zagnieżdżone zapytania.

Najlepiej w dynamoDB jest szukać po kluczu. Niby są 'secondary indexes' ale z tego co czytam w dokumentacji to, zaczynają się ograniczenia z consistency itd. Nie znam dokładnie problemu, danych itd. trzeba by było pomysles, jak się dostać do danych zawsze po PK.

wartek01 napisał(a):
dmw napisał(a):

Strong consistency - przy zapisywaniu czy odczytywaniu? Czy obydwu?

Jeśli masz oddzielne tabele A oraz B, to kiedy użytkownik zrobi "SELECT A.x, B.y WHERE A.businessId = 1 AND B.businessId = 1" to powinien dostać spójne informacje. Może dostać info sprzed powiedzmy 15 sekund, ale nie może dostać info z teraz dla A.x i sprzed 15 sekund dla B.y.

W zapytaniu możesz zdefiniować że chcesz 'strong consistency', dodatkowo przy zapisywaniu danych do kilku tabel możesz użyć transakcji, czyli nawet jeżeli później czytałbyś wiele tabel z 'strong consistency' to nie miałbyś niespodzianek.

Do tego masz TTL, Lambdę, dynamoDB streams itd., ale jak już @some_ONE wspomniał, musiałbyś przechowywać dane w chmurze. Jeszcze później dodam post z zapytaniami interaktywnymi w Kafka Streams jako potencjalne, ale ryzykowne rozwiązanie.

0

Jeszcze jedna rzecz która przychodzi mi do głowy to używanie Kafki jako bazy danych a udostępnianie danych poprzez 'Interactive queries' z 'KafkaStateStore' z poziomu aplikacji. W praktyce działa to tak, że wszystkie dane siedzą w Kafce. Twoja aplikacja czyta te dane i wrzuca do 'KafkaStateStore'. Następnie, używasz 'Interactive queries' z RESTem lub GRPC żeby pokazać te dane na zewnątrz. Szczerze powiedziawszy jest tutaj sporo pułapek, musisz dobrze rozumieć jak działa 'KafkaStateStore', proces przywracania danych itd. z tematu Kafki do 'KafkaStateStore', jeżeli jedna instancja rozłączy się z Kafka to zacznie się rabalancing i problemy. Bardzo łatwo tutaj o downtimy itd. Jest też sporo pozytywów, między innymi takie, że możesz sobie stworzyć kilka 'KafkaStateStore' i operować na nich używając transakcji, nie potrzebujesz nic poza Kafka, i wydaje mi się, że może to być dużo tańsze rozwiązanie niż np. baza danych w chmurze. To jest ryzykowne rozwiązanie, ale warto o nim wspomnieć.

2

Szybka, bezpieczna, skalowalna, programowalna, i jeszcze on-premis
Nie doczytałem nic o budżecie, (było coś o nieograniczonej infrastrukturze ale to chyba nie to samo), mimo wszystko proponuję coś co raczej na pewno podoła wymaganiom z pierwszych postów:
Oracle Exadata Database Machine X9M
Do tego potrzebny jeden ogarnięty człowiek który pracował już z wdrożeniem Exadata

Tak wiem, brzmi to staromodnie, świat powoli odchodzi od oracle, ALE, założenia spełnia :)

0

@dmw: czysta chmura to - jak pisałem już wcześniej - odpada, natomiast jeśli da się coś zainstalować na lokalnych maszynach to by było spoko. Niby wiem, że da się chmurę AWSową stawiać lokalnie, ale też to pewnie duże przedsięwzięcie.

Jeśli chodzi o Kafkę to używałem tego w połączeniu z Trino/Presto - bardzo fajnie działa jako datalake, natomiast pewnie wydajność i spójność danych mogłaby się psuć.

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