2010-12-30 11 views
8

Pracuję nad aplikacją internetową, która historycznie została zbudowana na stosie PHP/MySQL.Czy korzystanie z serwerów stanowych ma sens?

Jedna z kluczowych operacji aplikacji musiała wykonać kilka ciężkich obliczeń, które wymagały powtórzenia w każdym wierszu całej tabeli DB. Nie trzeba dodawać, że było to poważne wąskie gardło. Podjęto więc decyzję o przepisaniu całego procesu w Javie.

Dało nam to dwie korzyści. Po pierwsze, Java, jako język, była znacznie szybsza niż proces PHP. Po drugie, mogliśmy utrzymać cały zestaw danych w pamięci serwera aplikacji Java. Teraz możemy wykonywać obliczenia - ciężkie operacje w pamięci, a wszystko dzieje się znacznie szybciej.

To działało przez chwilę, dopóki nie uświadomiliśmy sobie, że musimy skalować, więc potrzebujemy więcej serwerów internetowych.

Problem polega na tym, że według obecnego projektu wszystkie muszą zachować ten sam stan. Wszystkie wysyłają zapytanie do DB, przetwarzają dane i utrzymują je w pamięci. Ale co się dzieje, gdy trzeba zmienić te dane? W jaki sposób wszystkie serwery zachowują spójność?

Ta architektura wydaje mi się błędna. Wydajność sprawia, że ​​przechowywanie wszystkich danych w pamięci jest oczywiste, ale to poważnie utrudnia skalowalność.

Jakie są opcje z tego miejsca? Przejdź do pamięci wewnętrznej, pary klucz-wartość, magazynu danych? Czy powinniśmy całkowicie zrezygnować z utrzymywania stanu na serwerach?

Odpowiedz

4

teraz przejść do Erlang :-)

tak, że to żart; ale jest ziarno prawdy. Problem polega na tym, że pierwotnie miałeś swój stan w zewnętrznym, współużytkowanym repozytorium: DB.teraz masz go (częściowo) wstępnie obliczone w wewnętrznym niewspółużytkowanym repozytorium: obiekty Java RAM. Oczywistym sposobem jest to, aby był jeszcze wstępnie obliczony, ale w zewnętrznym repozytorium współdzielonym, im szybciej, tym lepiej.

Jedną z łatwych odpowiedzi jest memcached.

Innym jest zbudowanie własnego "serwera kalkulacyjnego", który centralizuje zarówno zadanie obliczeniowe, jak i (częściowe) wyniki. Frontend sieciowy przetwarza właśnie dostęp do tego serwera. W Erlang byłby to naturalny sposób na zrobienie tego. W innych językach, parapet może to zrobić, po prostu więcej pracy. Sprawdź ZeroMQ dla inspiracji, nawet jeśli nie użyjesz jej w końcu (ale jest to cholernie dobra implementacja).

+0

+1 za ziarno prawdy. – duffymo

1

To może być banał, ale dane zawsze się powiększają, aby wypełnić miejsce, w którym je umieścisz. Twoje dane mogą dziś pasować do pamięci, ale gwarantuję, że nie będzie to miało miejsca w przyszłości. Jak daleko jest od tego czasu, musisz wymyślić lepszą architekturę. Stanowość twojej aplikacji jest tylko symptomem tego większego problemu.

Czy każdy wykonuje inne obliczenia w całym zestawie danych? Czy jest to coś, co możesz zrobić w partii na noc i mieć dostęp do ludzi w ciągu dnia? Jak to jest wrażliwe na czas?

Myślę, że to są pytania, na które należy odpowiedzieć, ponieważ w pewnym momencie nie będzie można kupić wystarczającej ilości pamięci do przechowywania potrzebnych danych. To może zabrzmieć głupio, biorąc pod uwagę, gdzie teraz jesteś, ale powinieneś planować, że to prawda. Wielu programistów, z którymi rozmawiałem, nie myśli o tym, jaki sukces wygląda i jaki ma wpływ na ich projekty.

+0

Całkowicie się z tobą zgadzam. * Dojdziemy do punktu, w którym przechowywanie wszystkich tych danych w pamięci będzie stanowić problem. Jakie istnieją rozwiązania tej sytuacji? Czy magazyn danych K-V jest opcją? Przechowuj raz dla wszystkich serwerów internetowych? Lub, jeśli surowe dane są przechowywane w ciężkim DB na zapleczu, gdzie przechowujesz meta-dane, które powinny być łatwo dostępne? –

+0

Nie wiem wystarczająco dużo o charakterze danych lub obliczeniach, aby ci w tym pomóc. – n8wrl

1

Zgadzam się z tobą - to brzmi wadliwie, ale potrzebowałbym więcej szczegółów, aby wiedzieć na pewno.

Wspominasz o dużym zbiorze danych i ciężkich obliczeniach, ale nie mówisz o tym, jak dane są aktualizowane, kiedy są wykonywane obliczenia, czy jest to dzień danych lub cały zestaw danych itp. To brzmi bardzo podobne do zadania wsadowego, które można wykonywać codziennie poza siecią.

Jeśli tak jest, nie jestem pewien, gdzie sieć ma do niego dostęp. Czy Twoi internauci po prostu wykonują niestandardowe zapytania po zakończeniu kompresji? Czy dane są przeznaczone tylko do odczytu lub do odczytu głównie dla użytkowników? Czy ciągle zmieniają dane w locie?

Zastanawiam się, czy wybrana przez ciebie technologia wytrwałości wpływa na różne rzeczy? Być może alternatywa NoSQL może być lepsza dla twojego problemu - jak rozproszony klaster MongoDB.

+0

Zasadniczo, gdzie jest właściwe przechowywanie metadanych, co pomaga w szybszym wykonywaniu ciężkich obliczeń? –

1

To pytanie dotyczy silnika danych, tak jak jest to pytanie dotyczące dystrybucji serwera sieciowego. Dlaczego twój (centralny) silnik bazy danych nie może wykonać obliczeń (wystarczająco szybko)?

Można zapisać wstępnie obliczone wartości oznaczone jako nieaktualne po zmianie danych bazowych, wymagające ponownego obliczenia. Po zmianie danych nie ma potrzeby powtarzania. Trzeba tylko zarządzać czasem i zmianą, która wpłynie na konsumentów danych.

+0

Baza danych zawiera tylko nieprzetworzone dane. Nie jest zbudowany do przechowywania metadanych, które pochodzą z nieprzetworzonych danych. –

+1

Nie sądzę, że warto wywoływać obliczenia na podstawie danych "metadanych". Termin ten może wprowadzić w błąd. Metadane to dane o danych, a nie dane pochodzące z danych. W każdym razie, silnik danych jest IMO właściwym i najprostszym miejscem do rozwiązania tego pytania. Silnik danych ma pojemność obliczeniową, a struktura bazy danych jest rozszerzalna. Alternatywą jest złożony schemat, w którym klienci korzystający z danych subskrybują usługę zmiany publikacji, dzięki czemu mogą odświeżać swoje lokalne rozproszone kopie podstawowego zestawu danych. – Tim

Powiązane problemy