2010-01-22 2 views
5

Мы сталкиваемся с необычно высокими проблемами использования памяти. И я заметил, что во многих местах нашего кода мы вытаскиваем 100 записей из БД, упаковываем его в пользовательские объекты данных, добавляем его в arraylist и сохраняем в сеансе. Я хочу знать, каков рекомендуемый верхний предел хранения данных в сеансе. Просто хорошая практика плохой практики.Сколько данных сеанса слишком много?

Я использую JRockit 1.5 и 1.6 ГБ оперативной памяти. Я сделал профилирование с Jprobe и обнаружил, что некоторые части приложения имеют очень большой объем памяти. Большая часть этих данных входит в сеанс, который будет использоваться позже.

+0

Я запускаю приложение J2EE struts на Weblogic 10 –

+0

На самом деле это вопрос агностики на платформе. –

ответ

6

Это зависит полностью от количества сеансов, которые обычно присутствуют (что, в свою очередь, зависит от того, сколько у вас пользователей, сколько времени они остаются на этом сайте и тайм-аута сеанса) и от того, сколько оперативной памяти у вашего сервера.

Но прежде всего: действительно ли вы использовали профилировщик памяти, чтобы сказать, что ваше «использование высокой памяти» вызвано данными сеанса, или вы просто угадываете?

Если единственная проблема, с которой вы сталкиваетесь, - это «использование большой памяти» на производственной машине (то есть она может обрабатывать производственную нагрузку, но не работает так, как вам хотелось бы), самым простым решением является получение большего объема ОЗУ для сервер - намного быстрее и дешевле, чем перепроектировать приложение.

Но кеширование целых наборов результатов в сеансе плохо по другой причине: что делать, если данные изменяются в БД и пользователь ожидает увидеть это изменение? Если вы собираетесь кэшировать, используйте one of the existing systems, которые делают это на уровне запроса БД - они позволят вам кэшировать результаты между пользователями, и у них есть возможности для недействительности кеша.

+0

Добавил еще несколько вопросов в вопрос. –

6

Если вы сохраняете данные в сеансе для повышения производительности, подумайте об использовании истинного кэширования, поскольку кеш является общесистемным, тогда как сеанс является для каждого пользователя, что приводит к ненужному дублированию в противном случае похожих объектов.

Если вы храните их у пользователя для редактирования этих объектов (что я сомневаюсь, поскольку сотни объектов слишком много), попробуйте минимизировать объем хранимых данных или оптимизировать управление параллелизмом.

1

Я бы сказал, что это сильно зависит от количества активных сеансов, которые вы ожидаете. Если вы пишете приложение интрасети с < 20 пользователями, это, безусловно, не проблема поставить несколько МБ в сессии. Однако, если вы ожидаете, например, 5000 живых сеансов, каждый МБ данных, хранящихся за сеанс, составляет 5 ГБ ОЗУ.

Однако я бы рекомендовал не хранить данные из базы данных в сеансе. Просто выберите из БД для каждого запроса. Если производительность является проблемой, используйте кэш приложения (например, кеш второго уровня Hibernate).

1

вид данных не так ли? Действительно ли это необходимо для каждого сеанса или может быть кэшировано на уровне приложения? Вам действительно нужны все столбцы или только подмножество? Как часто к нему обращаются? На каких страницах он должен быть доступен? И так далее.

Возможно, имеет смысл получить данные из БД, когда вам действительно нужно. Хранение сотен записей в сеансе никогда не является хорошей стратегией.

+0

Его необходимо за сеанс, я не могу кэшировать его уровень приложения. Не будет ли это платёжеспособностью, если я буду извлекать каждый раз из БД, даже когда я получу часть памяти –

+1

И вам нужны * все * данные столбца? И все эти ряды? На каждой странице? Вы должны быть в состоянии немного оптимизировать это. И да, как правило, хранение сотен полномасштабных записей в сеансе, независимо от нагрузки и т. Д., Не является хорошей стратегией. –

1

Я бы сказал, попробуйте сохранить минимальный объем данных, который будет достаточным для воссоздания необходимой среды в последующем запросе. Если вы храните в памяти, чтобы избежать дублирования базы данных, то может оказаться полезным верное решение для кеширования, такое как Memcache.

Если вы храните эти сеансы в памяти вместо базы данных, то туда и обратно сохраняется, и запросы будут обслуживаться быстрее, пока загрузка памяти будет низкой, и нет пейджинга. После того, как количество клиентов начнет развиваться и начнется пейджинг, большинство клиентов увидит огромное ухудшение времени ответа. Обе эти переменные и обратно связаны друг с другом.

Лучше всего измерить задержку на сервере базы данных, которая в большинстве случаев обычно является достаточно низкой, чтобы считаться жизнеспособным средством хранения вместо памяти.

1

Попытайтесь разделить данные, хранящиеся в данный момент в сеансе, на пользовательские и статические данные. Затем выполните кэширование для всех статических частей. Это даст вам много повторного использования в масштабах приложения и позволит вам кэшировать конкретные данные, над которыми работает пользователь.

1

Вы также можете сделать доступную для каждого пользователя мини-базу данных sqlite и подключиться к ней, а также сохранить данные, которые пользователь получает в ней, а затем просто извлечь записи из нее, когда пользователь запрашивает ее, а после того, как пользователь отключается просто удалите базу данных sqlite.