Огромная таблица сессий Django, нормальное поведение или ошибка? - PullRequest
20 голосов
/ 15 декабря 2010

Возможно, это совершенно нормальное поведение, но я чувствую, что таблица django_session намного больше, чем должна быть.

Прежде всего, я ежедневно запускаю следующую команду очистки, чтобы размер не вызвано просроченными сессиями :

DELETE FROM %s WHERE expire_date < NOW()

Числа:

  • У нас около 5000 уникальных посетителей (исключая ботов)) каждый день.
  • По умолчанию SESSION_COOKIE_AGE установлено по умолчанию, 2 недели
  • В таблице чуть более 1 000 000 строк

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

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

Ответы [ 4 ]

17 голосов
/ 16 декабря 2010

После небольшой отладки мне удалось отследить причину проблемы. В одном из моих промежуточных программ (и в большинстве моих представлений) содержится request.user.is_authenticated().

Промежуточное ПО django.contrib.auth устанавливает request.user на LazyUser()

Источник: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L13 (я не понимаю, почему там есть return None, но хорошо ...)

class AuthenticationMiddleware(object):
    def process_request(self, request):
        assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
        request.__class__.user = LazyUser()
        return None

LazyUser вызывает get_user(request), чтобы получить пользователя:

Источник: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L5

class LazyUser(object):
    def __get__(self, request, obj_type=None):
        if not hasattr(request, '_cached_user'):
            from django.contrib.auth import get_user
            request._cached_user = get_user(request)
       return request._cached_user

Метод get_user(request) делает user_id = request.session[SESSION_KEY]

Источник: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/init.py?rev=14919#L100

def get_user(request):
    from django.contrib.auth.models import AnonymousUser
    try:
        user_id = request.session[SESSION_KEY]
        backend_path = request.session[BACKEND_SESSION_KEY]
        backend = load_backend(backend_path)
        user = backend.get_user(user_id) or AnonymousUser()
    except KeyError:
        user = AnonymousUser()
    return user

При доступе к сеансу устанавливает accessed в true:

Источник: http://code.djangoproject.com/browser/django/trunk/django/contrib/sessions/backends/base.py?rev=14919#L183

def _get_session(self, no_load=False):
    """
    Lazily loads session from storage (unless "no_load" is True, when only
    an empty dict is stored) and stores it in the current instance.
    """
    self.accessed = True
    try:
        return self._session_cache
    except AttributeError:
        if self._session_key is None or no_load:
            self._session_cache = {}
        else:
            self._session_cache = self.load()
    return self._session_cache

И это приводит к инициализации сеанса. Ошибка была вызвана ошибочным бэкэндом сеанса, который также генерирует сеанс, когда accessed установлен в true ...

3 голосов
/ 15 декабря 2010

Возможно ли для роботов получить доступ к любой странице, на которой вы что-то установили в пользовательском сеансе (даже для анонимных пользователей), или к любой странице, где вы используете session.set_test_cookie() (например, представление входа по умолчанию в Django при вызове этого метода)? В обоих случаях создается новый объект сеанса. Исключение таких URL в robots.txt должно помочь.

0 голосов
/ 25 марта 2015

В моем случае я неправильно установил SESSION_SAVE_EVERY_REQUEST = True в settings.py, не понимая точного значения.

Тогда каждый запрос к моей службе django будет генерировать запись сеанса, особенно запрос проверки пульса от вышестоящих балансировщиков нагрузки.После нескольких дней работы стол django_session превратился в огромный.

0 голосов
/ 15 декабря 2010

Django предлагает команду управления для очистки этих сеансов с истекшим сроком действия!

...