2013-05-16 38 views
6

Chcesz synchronizować dane z pamięci podręcznej między dwoma serwerami. Obie bazy danych współużytkują tę samą bazę danych, ale w celu uzyskania lepszych danych wykonania buforowałem dane do Hash Map podczas uruchamiania. W ten sposób chcesz zsynchronizować dane z pamięci podręcznej bez restartowania serwerów. (Oba serwery uruchamiają się w tym samym czasie).Najlepszy sposób synchronizowania danych z pamięci podręcznej między dwoma serwerami

Proszę zasugerować mi najlepszy i skuteczny sposób.

Odpowiedz

22

Zamiast próbować zsynchronizować buforowane dane między dwiema instancjami serwera, dlaczego nie należy scentralizować pamięci podręcznej zamiast używać czegoś takiego jak memcached/couchbase lub redis? Używanie rozproszonego buforowania z czymś takim jak ehcache jest o wiele bardziej skomplikowane i narażone na błędy IMO niż centralizowanie buforowanych danych za pomocą serwera buforującego, takiego jak wspomniane.

Jako dodatek do mojej oryginalnej odpowiedzi, przy podejmowaniu decyzji, jakie podejście do buforowania należy zastosować (w pamięci, scentralizowane), jedną rzeczą, którą należy wziąć pod uwagę, jest zmienność danych, które są buforowane.

Jeśli dane są przechowywane w bazie danych, ale nie zmieniają się po załadowaniu serwerów, nie jest wymagana synchronizacja między serwerami. Po prostu pozwól, aby każdy załadował te statyczne dane do pamięci ze źródła, a następnie przejdź na ich wesołe sposoby robienia tego, co robią. Dane nie ulegną zmianie, więc nie trzeba wprowadzać skomplikowanego wzorca do synchronizacji danych między serwerami.

Jeśli w danych rzeczywiście występuje poziom zmienności (np., Że buforujesz wyszukiwanie danych o podmiotach z bazy danych w celu zapisania trafień w bazie danych), to nadal uważam, że scentralizowane buforowanie jest lepszym rozwiązaniem niż w przypadku -pamięci rozproszone i zsynchronizowane buforowanie. Musisz tylko upewnić się, że stosujesz odpowiednie wygaśnięcie danych z pamięci podręcznej, aby od czasu do czasu umożliwić odświeżanie danych. Możesz również po prostu upuścić dane z pamięci podręcznej ze scentralizowanego sklepu w ścieżce aktualizacji dla konkretnej jednostki, a następnie pozwolić jej ponownie załadować z pamięci podręcznej w następnym żądaniu dla tych danych. Jest to IMO lepsze niż próba stworzenia prawdziwej pamięci podręcznej zapisu, w której zapisujesz dane do bazowego magazynu, a także do pamięci podręcznej. Sam DB może wprowadzać poprawki w danych (np. Za pomocą domyślnie niepotrzebnych wartości), a dane w pamięci podręcznej w tym przypadku mogą nie odpowiadać zawartości w DB.

EDIT:

pytanie został poproszony w komentarzach o zaletach scentralizowanej pamięci podręcznej (zgaduję przed czymś jak w rozproszonej pamięci podręcznej). Przekażę moją opinię na ten temat, ale najpierw standardowe zastrzeżenie. Scentralizowane buforowanie nie jest lekarstwem. Ma na celu rozwiązywanie konkretnych problemów związanych z buforowaniem pamięci typu in-jvm. Zanim przejdziesz do oceny, czy chcesz się do niego włączyć, powinieneś najpierw zrozumieć, na czym polegają problemy, i sprawdzić, czy pasują do zalet scentralizowanego buforowania. Scentralizowane buforowanie jest zmianą architektoniczną i może zawierać problemy/zastrzeżenia. Nie zmieniaj tego na prosty, ponieważ ktoś mówi, że to lepsze niż to, co robisz. Upewnij się, że przyczyna pasuje do problemu.

Okay, teraz na mój zdaniem za jakie problemy scentralizowane buforowanie może rozwiązać vs cache in-jvm-memory (i ewentualnie dystrybuowane). Mam zamiar wymienić dwie rzeczy, chociaż jestem pewna, że ​​jest ich jeszcze kilka. Moje dwa duże to: Ogólny ślad pamięci i Problemy z synchronizacją danych.

Zacznijmy od Ogólny ślad pamięci. Powiedzmy, że robisz standardowe buforowanie obiektów, aby chronić relacyjny DB przed nadmiernym obciążeniem. Powiedzmy również, że masz dużo danych do buforowania, aby naprawdę chronić swój DB; powiedzmy w zakresie wielu GB.Jeśli robisz buforowanie pamięci w jvm, a mówisz, że ma 10 skrzynek serwera aplikacji, musisz pobrać tę dodatkową pamięć ($$$) razy 10 dla każdego z pól, które powinny być buforowane w jvm pamięć. Ponadto będziesz musiał przydzielić większą stertę do maszyny JVM w celu uwzględnienia danych z pamięci podręcznej. Jestem zdania, że ​​stado JVM powinno być małe i usprawnione, aby ułatwić pozbywanie się śmieci. Jeśli masz duże kawałki Starego Genomu, które nie mogą być zebrane, wtedy kładziesz nacisk na swój garbage collector, gdy przejdzie on do pełnego GC i spróbuje wyciągnąć coś z tej rozdętej przestrzeni Starego Gen. Chcesz uniknąć długich przerw w GC2, a wzdęcie twojego Starego Genomu nie pomoże w tym. Ponadto, jeśli wymagania dotyczące pamięci przekraczają określony próg, a na warstwie aplikacji działają maszyny 32-bitowe, konieczne będzie uaktualnienie do maszyn 64-bitowych, co może być kolejnym kosztem zaporowym.

Teraz, jeśli zdecydowałeś się scentralizować dane w pamięci podręcznej (używając czegoś takiego jak Redis lub Memcached), możesz znacznie zmniejszyć ogólny poziom pamięci w buforowanych danych, ponieważ możesz mieć go na kilku skrzynkach zamiast na wszystkich skrzynki serwera aplikacji w warstwie aplikacji. Prawdopodobnie chcesz zastosować podejście klastrowe (obie technologie je obsługują) i co najmniej dwa serwery, aby zapewnić wysoką dostępność i uniknąć pojedynczego punktu awarii w warstwie buforowania (więcej o tym w sekundę). Gdy ma się kilka maszyn do obsługi wymaganej pamięci do buforowania, można zaoszczędzić sporo znaczących $$. Ponadto możesz teraz dostroić skrzyneczki aplikacji i skrzynki podręczne inaczej, ponieważ służą one innym celom. Skrzynki aplikacji mogą być dostrojone do wysokiej przepustowości i niskich stert, a skrzynki podręczne mogą być dostrojone do dużej pamięci. A posiadanie mniejszych stosów zdecydowanie pomoże w ogólnej przepustowości skrzynek z warstwami aplikacji.

Teraz jeden szybki punkt dla scentralizowanego buforowania. Powinieneś skonfigurować swoją aplikację w taki sposób, aby mogła przetrwać bez pamięci podręcznej, gdyby całkowicie zniknęła na pewien czas. W tradycyjnym buforowaniu jednostek oznacza to, że gdy pamięć podręczna staje się całkowicie niedostępna, po prostu uderzasz w swój DB bezpośrednio dla każdego żądania. Nie niesamowite, ale też nie koniec świata.

Okay, teraz dla Problemy z synchronizacją danych. Dzięki rozproszonemu buforowaniu pamięci w formacie jvm musisz zachować synchronizację pamięci podręcznej. Zmiana danych w pamięci podręcznej w jednym węźle musi zostać zreplikowana do innych węzłów i zsynchronizowana z ich buforowanymi danymi. Podejście to jest trochę przerażające, jeśli z jakiegoś powodu (np. Z powodu awarii sieci) jeden z węzłów nie jest zsynchronizowany, to kiedy żądanie trafi do tego węzła, dane, które widzi użytkownik, nie będą dokładne w stosunku do tego, co aktualnie znajduje się w DB. Co gorsza, jeśli zgłoszą inne żądanie i trafią do innego węzła, zobaczą inne dane i będą mylące dla użytkownika. Centralizując dane, eliminujesz ten problem. Teraz można by argumentować, że scentralizowana pamięć podręczna wymaga kontroli współbieżności wokół aktualizacji tego samego buforowanego klucza danych. Jeśli do tego samego klucza przychodzą dwie równoczesne aktualizacje, w jaki sposób upewniasz się, że te dwie aktualizacje nie są ze sobą powiązane? Moją myślą tutaj jest nawet nie martwić się o to; kiedy nastąpi aktualizacja, upuść element z pamięci podręcznej (i napisz bezpośrednio do DB) i pozwól mu go ponownie załadować podczas następnego odczytu. W ten sposób jest bezpieczniej i łatwiej. Jeśli nie chcesz tego zrobić, możesz użyć funkcji CAS (Check-And-Set) zamiast optymalizacji kontroli współbieżności, jeśli naprawdę chcesz zaktualizować zarówno pamięć podręczną, jak i db na aktualizacje.

Podsumowując, można zaoszczędzić pieniądze i lepiej dostroić urządzenia warstwy aplikacji, jeśli scentralizujesz dane, które przechowują w pamięci podręcznej. Możesz również uzyskać większą dokładność tych danych, ponieważ masz mniej problemów z synchronizacją danych, z którymi możesz sobie poradzić. Mam nadzieję, że to pomoże.

+0

Dzięki za odpowiedź. Czy możesz po prostu wyjaśnić zalety scentralizowanej pamięci podręcznej, ponieważ znowu może to zwiększyć obciążenie mojego serwera. Obecnie ma około 5000 jednoczesnych użytkowników. Uwaga: zgodnie z aktualnymi statystykami teraz również otrzymuję pamięć poza limitem w określonym czasie. –

+0

Zaktualizowany przez odpowiedź na niektóre zalety ... – cmbaxter

+0

Thanx Cmbaxter ... To naprawdę pomaga ... –

8

Po pierwsze, staraj się zapomnieć o przedwczesnej optymalizacji. Czy naprawdę potrzebujesz pamięci podręcznej? 99%, że go nie potrzebujesz. W takim przypadku rozwiązaniem jest usunięcie zbędnego kodu.

Jeśli jednak jest to potrzebne, spróbuj zatrzymać ponowne wynajdowanie kół. Istnieją idealne gotowe do użycia biblioteki. Na przykład ehCache, który ma tryb rozproszony.

+0

Dzięki za odpowiedź. Mam około 5000 jednoczesnych użytkowników, więc nie mogę usunąć pamięci podręcznej Przypuszczam. przeszuka ehCache ... –

2

Użyj HazelCast. Umożliwia synchronizację danych między serwerami za pomocą protokołu multiemisji. Jest łatwy w użyciu. Obsługuje blokowanie i inne funkcje.

Powiązane problemy