Wszystkie projekty, z którymi do tej pory miałem do czynienia, wymagały tylko jednej bazy danych na jednym serwerze. Chciałbym dowiedzieć się więcej o tym, w jaki sposób projekty wymagające skalowania przechodzą do wielu baz danych i / lub serwerów, aby pomóc w zarządzaniu obciążeniem. Mam świadomość wysokiej skalowalności , ale szczególnie interesują mnie przykłady kodu lub dodatkowe zasoby, w których mogłem przeczytać więcej na ten temat.
Na przykład:
- Jak budowane są sprzężenia między dwiema tabelami w wielu bazach danych? (Przydałby się tutaj przykładowy kod).
- Czy są jakieś specjalne strategie śledzenia, które tabele znajdują się w której bazie danych?
- Czy kod aplikacji musi wiedzieć, że jedna lub więcej baz danych jest rozproszonych na wielu serwerach? Jeśli nie, na jakim poziomie żądania są filtrowane?
- Kiedy należy wyjść poza konfigurację 1 bazy danych / 1 serwera? Jak często trzeba to robić?
Odpowiedzi:
Ok, podzielmy to:
To całkiem proste. Obiekty SQL mają dowolną konwencję nazewnictwa od jednej do czterech części:
Servername.databasename.schemaname.tablename
Jeśli wszystkie tabele znajdują się na tym samym serwerze w tej samej bazie danych, z tym samym właścicielem / schematem, możesz po prostu zignorować pierwsze trzy części i użyć tego, do czego najczęściej jesteś przyzwyczajony:
Jeśli jedna z tabel znajduje się w innej bazie danych i obie używają domyślnego schematu dla swoich baz danych, po prostu dodajesz bazę danych do drugiej tabeli:
Jeśli akurat znajdujesz się w trzeciej bazie danych innej niż ta, której dotyczy zapytanie, jawnie użyj obu nazw baz danych:
Jeśli w końcu użyjesz różnych schematów i / lub właścicieli, możesz dodać je w:
I na koniec, jeśli jesteś bardzo ostrożny i masz bardzo dobry powód, możesz dołączyć do (zwykle małej) tabeli na innym serwerze:
Połączę te dwa, ponieważ idą w parze. Prawie zawsze dobrze jest zacząć od założenia, że jedna baza danych wystarcza na jeden serwer, dopóki ograniczenia projektowe / biznesowe / techniczne nie zmuszą Cię do korzystania z większej ilości.
Aby więc najpierw odpowiedzieć na drugie pytanie, ponieważ generalnie masz powód posiadania oddzielnych baz danych, powinno to być dość oczywiste ze znajomości projektu systemu, w którym coś jest.
Co do tego, kiedy / dlaczego konieczne jest przejście poza jedną bazę danych. Zwykle jest to mieszanka reguł biznesowych, polityki i / lub powodów technicznych.
Na przykład tam, gdzie pracuję, mamy 16 baz danych rozproszonych na 4 serwerach. Mamy MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Aby podać przykłady, dlaczego się różnią:
• Czy kod aplikacji musi wiedzieć, że jedna lub więcej baz danych jest rozproszonych na wielu serwerach? Jeśli nie, na jakim poziomie żądania są filtrowane?
W szerokim sensie prawdopodobnie tak. Muszą przynajmniej wiedzieć, na jaki serwer wskazują w ciągu połączenia z bazą danych. Przetwarzanie, raportowanie, główne itp.
Stamtąd potrzebują kontekstu bazy danych, aby wykonać. Zasadniczo byłby to najczęściej używany w aplikacji, być może nawet oryginalny z jednej bazy danych / jednego serwera dni aplikacji. MOŻESZ mieć aplikację wyraźnie przełączającą kontekst bazy danych przy każdym wywołaniu, ale bardzo utrudnia to dostosowanie bazy danych bez zmiany aplikacji.
Zwykle (a przynajmniej MY zwykle) podejście polega na tym, aby zawsze uzyskiwać dostęp za pośrednictwem jednej lub dwóch głównych baz danych.
Następnie w razie potrzeby utwórz widoki do innych baz danych w połączeniu z łączeniem się z bazą danych za pomocą procedur przechowywanych.
Aby zilustrować:
Załóżmy, że chcesz uzyskać informacje demograficzne klienta, dane sprzedaży i saldo kredytu, które są rozłożone na trzy tabele pierwotnie wszystkie w MainDB.
Więc piszesz połączenie ze swojej aplikacji:
Niesamowite. Jednak teraz za każdym razem, gdy zmieniamy nazwę kolumny lub zmieniamy nazwę / przenosimy tabelę, musisz zaktualizować kod aplikacji. Zamiast tego robimy dwie rzeczy:
Tworzymy klientów, Sprzedaż, Widoki Konta Odbiorcy (nie używałbyś Select *, ale tutaj demonstruję)
Następnie utworzylibyśmy również procedurę przechowywaną, spGetClientSalesAR
I niech twoja aplikacja to nazwie.
Teraz, dopóki nie zmieniam interfejsu w tym przechowywanym proc, mogę praktycznie zrobić wszystko, co muszę zrobić z bazą danych zaplecza, aby zwiększyć lub zmniejszyć.
W skrajności mógłbym nawet uczynić mój stary MainDB tylko zbiorem procedur przechowywanych w skorupie i widokami, tak że pod tymi widokami, które stworzyliśmy, wyglądało to tak:
A Twoja aplikacja nigdy nie pozna różnicy (zakładając między innymi szybkie rury i dobrze zainscenizowane dane).
Oczywiście to ekstremalne i kłamałbym, gdybym powiedział, że wszystko zostało zaplanowane w ten sposób, ale korzystanie z procedur / widoków przechowywanych, nawet jeśli robisz to podczas refaktoryzacji, zapewni ci dużą elastyczność, gdy Twoja aplikacja wyrasta ze skromnej bazy danych / jednego serwera początek.
źródło
Podstawowym sposobem, w jaki spotkałem wiele serwerów baz danych w świecie internetowym (ponieważ pytanie jest oznaczone jako PHP), są konfiguracje, w których istniała jedna baza „master” (zapis), a następnie jedna lub więcej replikowanych „slave” (read) baz danych . Zapisy w bazie danych są wykonywane na bazie danych „master”. Zawartość tej bazy danych jest replikowana na serwery „slave” w czasie prawie rzeczywistym. Zapytania - szczególnie intensywne raporty - są następnie uruchamiane względem jednej z baz danych „slave”, aby przenieść obciążenie na te serwery. Należy pamiętać, że ta konkretna konfiguracja jest najlepsza dla aplikacji, które mają dużo odczytów, ale nie dużo pisania. W żadnym wypadku nie jest to jedyny sposób na uporządkowanie rzeczy.
źródło
Oni nie są. Bazy danych NoSQL w ogóle nie wykonują sprzężeń, a nawet gdybyś mógł wykonać sprzężenie SQL między serwerami RDBMS, nie chciałbyś, jeśli cenisz wydajność (por. Błędy przetwarzania rozproszonego ).
W relacyjnej bazie danych SQL partycjonowanie zwykle odbywa się w ramach jednego serwera / bazy danych, przy użyciu różnych plików umieszczonych na różnych dyskach. Niemal z definicji rozwiązanie do skalowania w poziomie oznacza, że wszystkie bazy danych mają wszystkie tabele, a także masz jakieś transakcyjne tworzenie kopii lustrzanych, replikacja lub niestandardowe rozwiązanie zapewniające spójność ostateczną, aby mieć pewność, że wszystkie dane dotrą tam, gdzie powinny.
Jeśli faktycznie dzielisz bazę danych logicznie, a nie tylko fizycznie, to mapowania zdefiniowane w DAL lub ORM zadeklarują, które tabele znajdują się w której bazie danych.
Bazy danych NoSQL to połączenie rozwiązań partycjonujących. Czasami partycjonowane są „tabele” (lub częściej „kolekcje”). Innym razem są to „wiersze” (lub „dokumenty”). W niektórych przypadkach tak naprawdę są to kolumny , jak w zorientowanej na kolumny bazie danych, takiej jak HBase. Zależy to całkowicie od używanej technologii. Jedną z nich wszystkich jest to, że sam silnik śledzi to wszystko, więc wszystko, co musisz zrobić, to poprosić o dokument lub wiersz.
To oczywiście zakładając, że faktycznie korzystasz z funkcji dzielenia fragmentów, a nie tylko tworzysz kilka różnych baz danych. Jeśli robisz to drugie, to jesteś sam.
Jeśli są to różne logiczne bazy danych, tak. Jeśli są one rozproszone tylko fizycznie, to nie - przy założeniu, że twoja konkretna baza danych natywnie obsługuje dzielenie na fragmenty lub używasz rozwiązania równoważenia obciążenia (dla baz danych SQL). Zakładając również, że wszystkie twoje operacje są bezpaństwowe; jeśli chcesz skalowania w poziomie, będziesz musiał zrezygnować z ACID.
Nadszedł czas, aby zoptymalizować wszystko, co możliwe na jednym serwerze, i nadal nie jest w stanie wycisnąć wystarczającej wydajności z powodu ograniczeń obciążenia we / wy. Jeśli musisz zadać pytanie, jest za wcześnie.
Zauważ, że problemy z wydajnością w przyzwoitym produkcie RDBMS (Oracle, SQL Server) są częściej spowodowane złym projektem, słabym indeksowaniem, słabymi zapytaniami, rywalizacją o blokadę i tak dalej; produkty te można skalować w pionie w absurdalnym stopniu. Powtórz więc, powinieneś rozważyć „wyjście poza konfigurację 1 bazy danych / 1 serwera”, gdy masz absolutną pewność, że problemy z wydajnością wynikają z ograniczeń sprzętowych, a nie tylko z mniejszego projektu / implementacji.
Albo, jak sądzę, innym powodem, dla którego niektórzy ludzie przechodzą na rozproszone bazy danych, jest to, że nie są przygotowani na płacenie dużych (lub jakichkolwiek) pieniędzy w opłatach licencyjnych i chcą porzucić SQL jako świadomy wybór, aby wymienić niski koszt zwiększonej złożoności aplikacji. Całkowicie uzasadniony powód, jeśli jesteś startupem programistycznym, ale zwykle nie dotyczy sektora korporacyjnego.
źródło
Istnieją trzy główne typy konfiguracji replikacji dla baz danych:
Przykład Master-Slave: MySQL master + MySQL slaves, MongoDB
Przykład Master-Master: CouchDB, Cassandra, Riak
Przykład konsensusu: ScalienDB
...aby wymienić tylko kilka.
Mają różne cechy. Konfiguracje master-slave pozwalają węzłom slave dogonić master z maksymalną szybkością, jednocześnie bardzo szybko obsługując żądania odczytu, podczas gdy serwer master jest odpowiedzialny za integralność danych. Ponieważ wszystkie zapisy trafiają do mastera, nigdy nie ma blokady rywalizacji, ponieważ jeden stosunkowo powolny pisarz blokuje wiele czytników, ale z drugiej strony serwery podrzędne są ostatecznie spójne i nie dostajesz gwarancji izolacji transakcji, które byś miał z czytania tylko od mistrza. (dalsze czytanie; ACID vs BASE, poziomy izolacji transakcji, replikacja bazy danych, MVCC / Izolacja: migawka, replikacja transakcyjna)
Master-Master zawsze zezwala na zapisy, abyś miał wiele autorytetów w tym, co jest prawdą. Może to, ale nie musi stanowić problemu, w zależności od tego, co robi twoja aplikacja, ale jeśli napiszesz sprzeczne dane, możesz następnym razem uzyskać wiele wyników przy następnym czytaniu tego klucza / wiersza / kolumny, które będziesz musiał scalić z logiką aplikacji i zapisz z powrotem do bazy danych. (dalsza lektura: twierdzenie CAP, replikacja CouchDB, replikacja Riaka, spójne haszowanie, Bitcask i StormDB, kworum w / MongoDB w sprawie podziału sieci, strategie rozwiązywania scalania)
Bazy danych oparte na konsensusie z replikacją między węzłami, takie jak Scalien, zawsze byłyby spójne w przypadku zapisów, ale kosztem wymiany wielu wiadomości przed potwierdzeniem zapisu. Nie stanowi to większego problemu, jeśli masz szybki Ethernet i nie musisz zapisywać na dysku przed ACKingiem, co nie będzie potrzebne, jeśli twoje minimum trzy serwery znajdują się na różnych szafach serwerowych z osobnymi zasilaczami (jeden umiera; pozostali dwaj upewniają się, że zapisali na dysku). (dalsze czytanie; PAXOS, PAXOS COMMIT, zatwierdzanie dwufazowe z transakcjami rozproszonymi, zatwierdzanie trójfazowe)
Inne dalsze czytanie: (książka: „Elementy przetwarzania rozproszonego”, zegary wektorowe, wektory wersji, wektory macierzowe, zegary logiczne, algorytm piekarniczy, zegary drzewa interwałowego, aktorzy i programowanie reaktywne i reaktory, programowa pamięć transakcyjna, transakcje, AKKA, Stact, błędy przetwarzania rozproszonego, protokoły plotek, rozszerzenia protokołu plotek anty-entropii Cassandry, rozproszone tabele skrótów, dokumenty na temat scalania danych w rozproszonym otoczeniu, architektura ZooKeeper, prezentacja InfoQ na temat „protokołu asynchronicznego”, architektura HBase, papier MapReduce, papier Amazon Dynamo które rozpoczęło wszystkie funkcje NoSQL, kolejkowanie, klastrowanie o wysokiej dostępności przez królikmq)
Mam nadzieję, że dałem trochę do myślenia :). Możesz śledzić mnie na Twitterze @henrikfeldt, jeśli chcesz też tweetów na ten temat.
źródło
OK, oto kolejny punkt widzenia na skalowalność.
Omówmy, co to znaczy, że dane są danymi, co oznacza zachowanie i logika aplikacji.
Zwykle, gdy ktoś zapuszcza się w krainę aplikacji korporacyjnych i tym podobnych, miałby kontakt z ideą nakładania warstw. Oczywiście nakładanie warstw jest wszędzie w komputerach, takich jak stos sieciowy (model ISO), grafika (Photoshop) lub SOA (usługi mogą wywoływać rodzeństwo lub dzieci, ale nigdy rodziców).
Jednak szczególnym rodzajem warstw, które były nadużywane bez względu na to, co kiedykolwiek było, jest „GUI”, „warstwa logiki biznesowej”, a następnie „warstwa dostępu do danych”. Chodzi mi o to, że pomysł jest dobry, podobnie jak komunizm, ale w rzeczywistości tak nie jest.
Zobaczmy, dlaczego. Argument, który zamierzam użyć, dotyczy sprzężenia; punkty z jednej warstwy, która dotyka punktów na innej warstwie. Za każdym razem, gdy zaczynasz tworzyć aplikację warstwową aka z warstwami w domyślnym trybie przedsiębiorczości, w który wchodzą ludzie, tworzą oni tak wiele punktów kontaktu między warstwami.
W istocie chodzi o to, że warstwy są wymienne; ale nie są! Dlaczego? Ze względu na wszystkie połączenia strony wywoławczej.
Zamiast tego zobacz, dlaczego sieć jest oddzielona! Ponieważ interfejs jest strumieniem bajtów nad pojedynczym wskaźnikiem pliku, który wskazuje na otwarte gniazdo! Wszystkie warstwy w modelach ISO są podobne do tego, co wzorzec projektowy zwany „łańcuchem odpowiedzialności” ma na celu zorientowanie obiektowe! Każda warstwa otacza podstawową warstwę, nie znając semantyki danych w tej warstwie.
Gdy pakiet danych zbliża się do Ethernetu i nieprzetworzonych sygnałów elektrycznych na dole, jest ciągle owijany warstwami, które znają tylko swoją specyficzną kopertę wiadomości, swoją własną „partię bajtów”, którą może wysłać; i nic więcej. Nie musi zmieniać ścieżek wywołań w zależności od zawartości pakietu.
Porównaj to z poziomem n, w którym musiałbyś zmienić ścieżkę połączeń w warstwach aplikacji podczas „połączenia” przechodzącego przez twoje warstwy w drodze do bazy danych - na przykład „klienci złota” są polimorficznie nadzbiorem „zwykłych klientów” dlatego, że używamy „tabeli na podklasę”, musimy wiedzieć o tym teraz, gdy dane (byt) przemierzają warstwy; zarówno w tak zwanej „warstwie logiki biznesowej”, jak i w warstwie danych, która faktycznie oszczędza.
Nie jest skalowalny ani optymalny z punktu widzenia komputerów.
Dlaczego nie jest skalowalny? Ponieważ architektura jest sprzężona, a następnie nadal znajdujesz się w tej samej starej bazie danych, którą próbujesz skalować do wielu węzłów! Ponieważ jednak potrzebujesz do tego ACID, a także trzeciego podmiotu (obiektu danych), musisz mieć je w jednej bazie danych, która dokonuje transakcji!
Righty, a więc z tym zakazem; jakie są inne sposoby?
Istnieje znienawidzony skrót o nazwie „SOA”, tj. Architektura zorientowana na usługi. Oczywiście, Tomas Erls na świecie , chciałby zaimplementować wszystkie swoje warstwy, ale zamiast XML i SOAP.
Z wszystkich powyższych powodów jest to niewłaściwa droga, ponieważ łączysz się z tymi serwerami proxy XML tak, jakbyś łączył się z warstwami aplikacji, jak wyjaśniono powyżej.
Zamiast tego używaj wiadomości i pozwól, aby cokolwiek implementowało dla nich funkcjonalność, słuchaj ich. Twoja powierzchnia serwisowa staje się listą wiadomości, które możesz wysłać, a operacji nie połączyłeś z fasadą usługi; i nawet nie musisz wiedzieć, która aplikacja lub punkt końcowy implementuje te operacje, ponieważ wszystko, co robisz, to publikowanie komunikatu, który jakiś inny mechanizm routingu skieruje do właściwego konsumenta!
Ponieważ oddzieliłeś fasady usług od faktycznych operacji, które chcesz wykonać, możesz teraz dodać wiele usług; tak właśnie robi Netflix. Obejrzyj te prezentacje: http://www.slideshare.net/adrianco/global-netflix-platform . http://www.slideshare.net/adrianco/global-netflix-platform . Oni są dobrzy!
źródło
Istnieje nowa baza danych SQL (ACID) w wersji beta, która ma mieć elastyczne właściwości skalowania. Obecnie trwa bezpłatny program w wersji beta i sugeruję, abyś spojrzał, nazywa się NuoDB.
Najwyraźniej z łatwością przewyższa MySQL nawet na maszynie z jednym wątkiem, ale skaluje się szczęśliwie do ponad 70 wystąpień w niektórych testach porównawczych.
źródło