2010-01-22 14 views
5

Występują niezwykle wysokie zużycie pamięci. I zauważyłem, że wiele miejsc w naszym kodzie pobieramy 100s rekordów z DB, pakując je w niestandardowe obiekty danych, dodając je do listy i przechowując w sesji. Chciałbym wiedzieć, jaki jest zalecany górny limit przechowywania danych w sesji. Tylko dobra praktyka, zła praktyka.Ile danych sesji jest za dużo?

Używam JRockit 1,5 i 1,6 GB pamięci RAM. Zrobiłem profilowanie z Jprobe i odkryłem, że niektóre części aplikacji mają bardzo duży ślad pamięci. Większość tych danych jest w sesji do wykorzystania później.

+0

Używam aplikacji rozpórki J2EE na Weblogic 10 –

+0

Jest to naprawdę agnostyczne pytanie o platformę. –

Odpowiedz

6

Wszystko zależy od tego, ile sesji jest zwykle dostępnych (co z kolei zależy od liczby użytkowników, czasu przebywania w witrynie i limitu czasu sesji) oraz ilości pamięci RAM serwera.

Ale przede wszystkim: czy rzeczywiście użyłeś profilera pamięci, aby powiedzieć, że twoje "wysokie zużycie pamięci" jest spowodowane danymi sesji, czy po prostu zgadujesz?

Jeśli jedynym problemem jest "wysokie zużycie pamięci" na maszynie produkcyjnej (tj. Może obsłużyć obciążenie produkcyjne, ale nie działa tak dobrze, jak chcesz), najprostszym rozwiązaniem jest uzyskanie większej ilości pamięci RAM dla serwer - znacznie szybszy i tańszy niż przeprojektowanie aplikacji.

Ale buforowanie całych zestawów wyników w sesji jest złe także z innego powodu: co jeśli dane ulegną zmianie w DB i użytkownik spodziewa się zobaczyć tę zmianę? Jeśli chcesz przechować pamięć podręczną, użyj one of the existing systems, która to zrobi na poziomie żądania DB - pozwolą Ci na buforowanie wyników między użytkownikami i mają udogodnienia do unieważnienia pamięci podręcznej.

+0

Dodano więcej szczegółów w pytaniu. –

6

Przechowywanie danych w sesji w celu zwiększenia wydajności, należy rozważyć użycie prawdziwego buforowania, ponieważ pamięć podręczna ma zastosowanie dla całej aplikacji, podczas gdy sesja jest dla użytkownika, co powoduje niepotrzebne powielanie podobnych obiektów.

Jeśli jednak przechowujesz je dla użytkownika do edycji tych obiektów (co wątpię, ponieważ setki obiektów to o wiele za dużo), spróbuj zminimalizować ilość przechowywanych danych lub optymistyczną kontrolę współbieżności.

1

Powiedziałbym, że zależy to w dużej mierze od liczby aktywnych sesji, których się spodziewasz. Jeśli piszesz aplikację intranetową z użytkownikami < 20, z pewnością nie ma problemu z umieszczeniem kilku MB w sesji. Jeśli jednak na przykład oczekuje 5000 sesji na żywo, każdy MB danych przechowywanych na sesję stanowi 5 GB pamięci RAM.

Jednak generalnie zaleca się, aby nie przechowywać żadnych danych z bazy danych w sesji. Po prostu pobierz z DB dla każdego żądania. Jeśli wydajność jest problem, użyj cache całej aplikacji (np. Pamięć podręczna drugiego poziomu Hibernate).

1

Co to jest rodzaj danych? Czy jest naprawdę potrzebny na sesję, czy może być buforowany na poziomie aplikacji? Czy naprawdę potrzebujesz wszystkich kolumn lub tylko podzestawu? Jak często jest on dostępny? Jakie strony musi być dostępne na stronie? I tak dalej.

Może być o wiele więcej sensu odzyskiwanie rekordów z bazy danych, kiedy naprawdę trzeba. Przechowywanie setek rekordów w sesji nigdy nie jest dobrą strategią.

+0

Jest to potrzebne na sesję, nie mogę buforować jej poziomu aplikacji. Czy nie będzie to opłata za wydajność, jeśli pobierze się za każdym razem z DB, nawet gdy zdobędę trochę pamięci –

+1

I potrzebujesz * wszystkich * danych kolumny? I wszystkie te rzędy? Na każdej stronie? Musisz być w stanie zoptymalizować to nieco. I tak, generalnie przechowywanie setek pełnowymiarowych rekordów w sesji, niezależnie od obciążenia itp., Nie jest dobrą strategią. –

1

Powiedziałbym, że staram się przechowywać minimalną ilość danych, która wystarczy, aby odtworzyć niezbędne środowisko w kolejnym żądaniu. Jeśli przechowujesz dane w pamięci, aby uniknąć bazy danych w obie strony, przydatne może być prawdziwe rozwiązanie buforujące, takie jak Memcache.

Jeśli przechowujesz te sesje w pamięci zamiast w bazie danych, zapisywana jest podróż w obie strony, a żądania będą obsługiwane szybciej, dopóki obciążenie pamięci jest niskie i nie ma stronicowania. Po zwiększeniu liczby klientów i rozpoczęciu stronicowania większość klientów odczuje ogromną degradację czasu odpowiedzi. Obie te zmienne i są odwrotnie powiązane.

Lepiej zmierzyć opóźnienie w stosunku do serwera bazy danych, który w większości przypadków jest zwykle wystarczająco niski, aby można go było uznać za realistyczny sposób przechowywania zamiast w pamięci.

1

Spróbuj podzielić dane, które aktualnie przechowujesz w sesji, na dane specyficzne dla użytkownika i statyczne. Następnie zaimplementuj buforowanie dla wszystkich części statycznych. To da ci wiele możliwości ponownego użycia w całej aplikacji i nadal pozwoli ci buforować określone dane, nad którymi pracuje użytkownik.

1

Można również utworzyć bazę danych mini sqlite dla każdego użytkownika i połączyć się z nią, a także przechowywać dane, do których użytkownik uzyskuje dostęp, a następnie pobierać z niej rekordy, gdy użytkownik tego żąda, a po rozłączeniu użytkownika po prostu usuń bazę danych sqlite.