tutorial - the django project
Enorme tabla Django Session, comportamiento normal o error? (4)
Quizás este es un comportamiento completamente normal, pero siento que la tabla django_session
es mucho más grande de lo que debería ser.
En primer lugar, ejecuto el siguiente comando de limpieza diariamente para que el tamaño no sea causado por sesiones caducadas :
DELETE FROM %s WHERE expire_date < NOW()
Los números:
- Tenemos alrededor de 5000 visitantes únicos (excluidos los robots) todos los días.
- El
SESSION_COOKIE_AGE
se establece en el valor predeterminado, 2 semanas - La mesa tiene poco más de 1.000.000 de filas.
Entonces, supongo que Django también genera claves de sesión para todos los bots que visitan el sitio y que los bots no almacenan las cookies, por lo que continuamente genera nuevas cookies.
Pero ... ¿es este el comportamiento normal? ¿Hay una configuración para que Django no genere sesiones para usuarios anónimos, o al menos ... no hay sesiones para usuarios que no usan sesiones?
¡Django ofrece un comando de administración para limpiar estas sesiones expiradas!
¿Es posible que los robots accedan a cualquier página en la que configures algo en una sesión de usuario (incluso para usuarios anónimos), o cualquier página en la que utilices session.set_test_cookie()
(por ejemplo, la vista de inicio de sesión predeterminada de Django en este método)? En ambos casos se crea un nuevo objeto de sesión. La exclusión de tales URL en robots.txt debería ayudar.
Después de un poco de depuración, logré rastrear la causa del problema. Uno de mis middlewares (y la mayoría de mis puntos de vista) tiene una request.user.is_authenticated()
en ellos.
El middleware django.contrib.auth
establece request.user
en LazyUser()
Fuente: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L13 (No veo por qué hay un return None
hay, pero está bien. ..)
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
El LazyUser
llama a get_user(request)
para obtener al usuario:
Fuente: 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
El get_user(request)
hace un user_id = request.session[SESSION_KEY]
Fuente: 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
Al acceder a los conjuntos de sesión accessed
a true:
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
Y eso hace que la sesión se inicie. El error fue causado por un backend de sesión defectuoso que también genera una sesión cuando el accessed
se establece en verdadero ...
En mi caso, configuré erróneamente SESSION_SAVE_EVERY_REQUEST = True
en settings.py
sin entender el significado exacto.
Luego, cada solicitud a mi servicio django generaría una entrada de sesión, especialmente la solicitud de prueba de latido de los balanceadores de carga ascendentes. Después de varios días de funcionamiento, la tabla django_session
se convirtió en una enorme.