Клиентское приложение Django периодически (примерно два раза в день) выбрасывает RuntimeError("Unable to create a new session key.")
:
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/views/decorators.py", line 17, in _checklogin
if request.user.is_active and request.user.is_staff:
File "/usr/local/lib/python2.6/dist-packages/django/contrib/auth/middleware.py", line 9, in __get__
request._cached_user = get_user(request)
File "/usr/local/lib/python2.6/dist-packages/django/contrib/auth/__init__.py", line 107, in get_user
user_id = request.session[SESSION_KEY]
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py", line 47, in __getitem__
return self._session[key]
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py", line 195, in _get_session
self._session_cache = self.load()
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/cache.py", line 16, in load
self.create()
File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/cache.py", line 33, in create
raise RuntimeError("Unable to create a new session key.")
RuntimeError: Unable to create a new session key.
Как вы можете видеть из трассировки, это происходит глубоко в недрах django.contrib.sessions
при использовании бэкенда сеанса кэша с бэкэндом кэша memcached.
Билет Django trac (https://code.djangoproject.com/ticket/14093) предлагает изменить хэш ключа сеанса с MD5 на UUID4, но это не поможет - проблема в сети. Я заметил (с tcpdump), что это исключение может возникнуть истечение времени ожидания TCP-соединения между сервером приложений и сервером memcache из-за потери пакета.
У нас есть два сервера приложений и один сервер memcached (1.4.2), все они работают в Amazon EC2. В периоды высокого спроса я наблюдал, как один сервер приложений обменивался 75 000 пакетов в секунду с сервером memcache. В течение этого периода высокой нагрузки я наблюдал потерю одного пакета SYN для нового подключения к memcache, что привело к тайм-ауту подключения к python-memcache (еще до того, как ядро изменилось на повторную передачу) и к RuntimeError
.
Я в недоумении, как решить эту проблему. Я хотел бы настроить таймер ретрансляции TCP в Linux ниже трех секунд, но он не настраивается. Если это не удастся, я бы хотел, чтобы python-memcache повторил попытку подключения пару раз, прежде чем отказаться, но это не так. Я вижу, что pylibmc имеет настраиваемое поведение при подключении и повторных попытках, но я не смог найти комбинацию опций, которая бы работала вокруг потери пакетов.
Идеи