Blog Sessions im Cache halten

Djangos Session Framework speichert die Sessions standardmässig in einer Datenbanktabelle. Sendet der Browser eine Session-ID wird immer ein SQL-Query ausgeführt:

SELECT session_key, session_data, expire_date
FROM django_session
WHERE (session_key = a4b2774d4ebdc0cc919d8048c460eec4
        AND expire_date > 2009-08-05 15:07:52.565487 )

Nun ist das nicht der Performancefaktor aber Django bietet eine Möglichkeit, Sessions nicht in der Datenbank sondern im Cache (z.B. memcached) zu halten. Der Vorteil liegt klar auf der Hand: kein Query und minimale Latenz zwischen Django und dem Sessionspeicher.

Die Einbindung ist simpel, der Parameter SESSION_ENGINE definiert das Backend, dass zum Session-speichern genutzt wird. Um Sessions im Cache zu halten, ist nur der Parameter SESSION_ENGINE in deiner settings.py notwendig:

# Als Beispiel Cache Backend hier memcached
CACHE_BACKEND = 'memcached://127.0.0.1:11211/'

# Das Session Backend
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'

Nun hat das ganze auch Nachteile. Nutzen wir wie im Beispiel den memcached würden alle Sessions verloren gehen, wenn z.B. der Server neu gestartet wird oder die memcached Instanz volläuft und die älteren Daten überschreibt. Aber um Sessions persistent zu speichern, liefert Django eine Lösung gleich mit. Statt dem cache Backend nutzen wir einfach das cached_db Backend:

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

Diese Lösung ist simpel und genial zugleich. Sessions werden weiterhin im Cache gehalten, Write Zugriffe werden aber im Cache und in die Datenbank geschrieben, Read Zugriffe werden nur aus dem Cache gelesen, kein Datenbank-Query wird ausgeführt. Wird aber kein Session-Eintrag im Cache gefunden, schaut das Backend zusätzlich noch einmal in der Datenbank nach. Hier das ganze noch mal grafisch dargestellt:

http://static.mahner.org/assets/weblog/django/memcache_db.png

Dieses Verfahren beschert also die Vorteile eines Caches mit der Persistenz einer Datenbank und ich kann es eigentlich immer als Standardvariante empfehlen.

Weitere Infos dazu findest du in der Django-Dokumentation, so ist zum Beispiel auch ein klassisches File-Storage möglich.

Den Cache im Auge behalten

Wer sich nicht sicher ist, ob der zugewiesene Speicher seiner memcached Instanz ausreicht, dem empfehle ich mein kleines App django-memcache-status. Es zeigt die aktuelle Auslastung und viele weitere Werte der zugewiesenen memcache Instanzen übersichtlich in der Admin-Oberfläche an:

http://static.mahner.org/assets/weblog/django/memcache_status_1.png

Das App ist BSD lizensiert und den Quellcode sowie eine Beschreibung findest du in meinem GitHub Account. Klar kannst du es auch einfach vom Käseshop aus installieren:

pip install django-memcache-status