Клиентское приложение 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
.
Я не понимаю, как это решить. Я бы хотел настроить таймер повторной передачи Linux TCP менее трех секунд, но он не настраивается. В противном случае я хотел бы, чтобы python-memcache повторил соединение пару раз, прежде чем сдаваться, но это не будет. Я вижу, что pylibmc имеет настраиваемое поведение соединения и повтора, но мне не удалось найти комбинацию параметров, которые работают с потерей пакетов.
Идеи?