Сколько данных сеанса слишком много? - PullRequest
5 голосов
/ 22 января 2010

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

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

Ответы [ 7 ]

6 голосов
/ 22 января 2010

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

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

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

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

6 голосов
/ 22 января 2010

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

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

1 голос
/ 22 января 2010

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

1 голос
/ 22 января 2010

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

1 голос
/ 22 января 2010

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

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

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

1 голос
/ 22 января 2010

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

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

1 голос
/ 22 января 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...