Jak ex firma mogła rozwiązać problem dużej ilości danych

Jak ex firma mogła rozwiązać problem dużej ilości danych
Marlo Taroko
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0

Pracowałem w firmie, która bardzo szybko zdobywała nowych klientów. Zaczynaliśmy od 1 serwera bazodanowego (postgres), gdzie była 1 baza z danymi wszystkich klientów. Specyfika była taka, że dane klienta A nie są w żadnej relacji z danymi klienta B, tzn. równie dobrze dane tych klientów mogłyby być na różnych bazach danych. Coś jak w systemach ERP, gdzie każdy klient może sobie definiować łancuchy dostaw, przypisywać swoich pracowników do określonych zadań, ale nie ma żadnego powiązania między danymi klienta A, a klienta B.

Bardzo szybko pozyskiwaliśmy nowych klientów, którzy generowali duży ruch (niektóre tabele miały po 2 mld nowych wpisów / msc). Pojawił się problem, że cały system zaczął działać ociężale. Np. w sytuacji, gdy 1 klient pousuwał miliardy danych ze swojego konta, aby postgres zwolnił miejsce należało użyć VACUUM FULL na tabeli, ale to powodowało blokowanie danych wszystkich innych klientów. Co wymyślili?

Założmy drugą bazę na innym serwerze, która będzie analogiczna do tej pierwszej. Podczas logowania będziemy strzelać zapytaniem do bazy wspólnej, w której będzie informacja na której bazie leżą dane klienta. No i część klientów była na 1 bazie, a część na drugiej. Klienci przybywali, więc dochodziły kolejne bazy. Niektórzy klienci mieli nawet swoje własne bazy. Łącznie baz było z 50, a wszystkie z identycznymi schematami.

No niby to działało, ale było straszne w zarządzaniu. Gdy trzeba było wyciągnąć dane dotyczące wszystkich klientów, trzeba było odpalić zapytanie na każdej bazie. Żeby dodać nową kolumnę to samo. No dramat..

Jakie rozwiązania by się sprawdziły w tej sytuacji? Jakoś ciężko mi sobie wyobrazić, by większe firmy radziły sobie w ten sam sposób. Musi być coś wygodniejszego.

YA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2386
3

Przez automatyzację :-) W ramach procesu sprzedażowego zapewne jest krok "Uruchom usługę", który można traktować jako pod-proces biznesowy i go zautomatyzować.

No niby to działało, ale było straszne w zarządzaniu. Gdy trzeba było wyciągnąć dane dotyczące wszystkich klientów, trzeba było odpalić zapytanie na każdej bazie. Żeby dodać nową kolumnę to samo. No dramat..

Bez automatyzacji, to dramat. Dlaczego trzeba było wyciągać dane dotyczące wszystkich klientów, skoro dane klienta A nie miał relacji z danymi klienta B ?

Masz rozwiązania typu kubernetes, gdzie możesz sobie separować klientów w ramach namespaceów, a na poziomie runtime separować zasoby.
Masz też różne rozwiązania wirtualizacji, gdzie możesz mieć jakiś golden image, z którego tworzysz instancję wirtualnej maszyny dla konkretnego klienta.

DR
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1135
1

Nie miałem nigdy takiego problemu do rozwiązania. Poprawcie mnie jeśli się mylę, ale wydaje mi się, że można zrobić partycje po tabeli Users i z tego co wiem, można nawet to trzymać na osobnych serwerach, a baza wciąż myśli, że jest jednym bytem. Coś mi się tak kojarzy ze studiów XD

EDIT. Sharding - https://pgdash.io/blog/postgres-11-sharding.html

KE
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 774
2

Słowo klucz: AUTOMATYZACJA. Piszesz, że dodanie nowej kolumny jest straszne, jeśli baz jest kilkadziesiąt. A wcale nie jest:

Kopiuj
for db in $(get_all_databases.sh); do
  liquibase-cli --address ${db} --changelog-file ${changelog} migrate
done

(składnia wymyślona - używam w pracy ale nie pamiętam dokładnie)

Gdy trzeba było wyciągnąć dane dotyczące wszystkich klientów, trzeba było odpalić zapytanie na każdej bazie

No tego niestety nie przeskoczą, jeśli system tak został zaprojektowany. Ewentualnie obczaj postgres fdw - pozwala na łączenie wielu baz i traktowanie jej jako jednej, aczkolwiek nie wiem jak wydajne to jest.

Marlo Taroko
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0
yarel napisał(a):

Dlaczego trzeba było wyciągać dane dotyczące wszystkich klientów, skoro dane klienta A nie miał relacji z danymi klienta B ?

Głównie pod obliczenia zagregowane, np. by dowiedzieć się ile łącznie było wykonanych operacji X przez wszystkich klientów

MY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1107
0

Osobiście wybrałbym rozwiązanie baza danych per klient. Rozwiązanie bezpieczniejsze oraz moim zdaniem bardziej elastyczne.

Marlo Taroko napisał(a):

Żeby dodać nową kolumnę to samo. No dramat..

A to ręcznie uaktualnialiście schemy baz danych na produkcji? Przecież można trzymać skrypty uaktualniające do każdej wersji bazy po kolei i je uruchamiać na wszystkich bazach po kolei jednym kliknięciem myszki w jakimś module zarządzania baz. Bo jeśli mamy mieć wiele baz, to powinien być moduł zarządzania tym wszystkim. Co więcej wrzucenie nowej wersji apki i odpalenie aktualizacji na wszystkich bazach to przecież kwestia napisania raz jednego skryptu. No chyba, że wszystko robiliście ręcznie, ale wtedy wybór jedna/wiele baz to najmniejszy problem :)

Marlo Taroko napisał(a):

Głównie pod obliczenia zagregowane, np. by dowiedzieć się ile łącznie było wykonanych operacji X przez wszystkich klientów

Jaki problem wystawić jakiś widok/procedurę w każdej bazie danych, a potem wywołać to na każdej bazie w pętli i zagregować po stronie modułu zarządzającego na poziomie kodu źródłowego i potem wyświetlić w formie ładnej tabelki?

grinder
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 18
1

Generalnie jest taki termin w bazach danych , nazywa się sharding, można się z nim zapoznać w wolnej chwili.
Pierwszy z brzegu artykuł jakie możliwości w tym temacie oferuje postgreSQL:
https://www.squash.io/tutorial-on-database-sharding-in-postgresql/

Twój przypadek podpada pod tzw. Multi-Tenant Applications
W zależności od bazy danych , różnie jest to implementowane
np https://learn.microsoft.com/en-us/azure/azure-sql/database/saas-tenancy-app-design-patterns?view=azuresql
lub
https://docs.oracle.com/en/database/oracle/oracle-database/19/shard/oracle-sharding-architecture-and-concepts1.html#GUID-9DC0048A-2D6E-4759-BA80-10F8855E6871

Czasami wystarczy coś znacznie prostszego np. nie ma dużej ilości danych , a pilnujemy tylko dostępu na najnizszym poziomie:
https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/using-oracle-vpd-to-control-data-access.html#GUID-8AB08B54-5858-4A6F-B1F2-43F7C5922DD8

somekind
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0
Marlo Taroko napisał(a):

Głównie pod obliczenia zagregowane, np. by dowiedzieć się ile łącznie było wykonanych operacji X przez wszystkich klientów

Oferujecie swoim klientom jedynie bazę danych?
Bo jeśli nie, to może warto przenieść profilowanie do jakiegoś bardziej dogodnego miejsca.

flinst-one
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 350
5

Osobna baza per klient. Gdy klient "urośnie", to można spokojnie całą bazę przenieść na osobny serwer z większymi zasobami. W przypadku vacuum full tylko jedną bazę blokujesz, mniejsze bazy nie będą miały tak często tego robionego, jak te duże. Backupy można wtedy równolegle odpalać, a nie walić jeden duży po całości. Najdłuższy backup jaki widziałem trwał ok 50h, po rozdzieleniu schematów na bazy (które i tak były od siebie niezależne) mieściliśmy się w 8h. Dodatkowo, jak klient się "zwinie" to gasimy całą bazę, a nie wywalamy deletem kilku miliardów rekordów z jednej bazy.
Przez rodo trzeba np. kasować/hashować po pewnym czasie nazwy użytkowników i ich mejle. W osobnej bazie jest to łatwiejsze, niż w jednej z tysiącami userów. Potrzebne dane historyczne dla klienta - robi się restore tej jednej bazy, a nie całego wora.
Sharding ma sens, gdy masz np. wspólną bazę userów, którzy korzystają z dużej ilości danych, w przypadku osobnych firm to chyba niepotrzebna komplikacja.
Jak pisano wyżej - wszystko trzeba zautomatyzować. Robótki ręczne w takich przypadkach, to masochizm. Masz liquibase, ansible, puppet, jenkins i kilka innych technologii.

Co do czesania wszystkich baz - słowo klucz to hurtownia danych. Robisz agregaty na bazach źródłowych i wrzucasz do centralnej bazy, albo ciągniesz tylko ostanti dzień/tydzień z systemów źródłowych i na hurtowni to przetwarzasz (żeby nie obciążać baz sprzedażowych). Do robienia takich rzeczy masz wiele narzędzi ETL np. pentaho albo talend ETL. Wszystko sobie harmonogramujesz, jak się coś wywali, to dostajesz powiadomienia mejlowe.

Marlo Taroko
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 7
0

@first-one problem jaki widze, to ten z agregatami. No czasami są sytuacje, że trzeba coś wyciągnąć "na już". Np. przychodzi menago, że potrzebuje jakąś tam statystykę, no i trzeba dłubać. Przy 50 bazach zrobi się 50 strzałów i sie wyciągnie. A jak to zrobić przy 1 mln bazach (klientów)?

somekind
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0
Marlo Taroko napisał(a):

@first-one problem jaki widze, to ten z agregatami. No czasami są sytuacje, że trzeba coś wyciągnąć "na już". Np. przychodzi menago, że potrzebuje jakąś tam statystykę, no i trzeba dłubać. Przy 50 bazach zrobi się 50 strzałów i sie wyciągnie. A jak to zrobić przy 1 mln bazach (klientów)?

Jak pisałem - do profilowania służą inne narzędzia niż odpytywanie bazy o jej aktualny stan.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.