Как я могу предотвратить RuntimeError («Невозможно создать новый ключ сеанса.»)? - PullRequest
15 голосов
/ 29 июля 2011

Клиентское приложение 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 имеет настраиваемое поведение при подключении и повторных попытках, но я не смог найти комбинацию опций, которая бы работала вокруг потери пакетов.

Идеи

Ответы [ 6 ]

5 голосов
/ 14 ноября 2011

Только что решил ту же проблему с apt-get install memcached. Может быть, это тоже ваше дело.

Ой, прости, это не твой случай. Я просто прочитал вопрос с большим вниманием. Но я оставлю свой ответ - потому что это об этой ошибке во время выполнения.

3 голосов
/ 12 октября 2012

https://github.com/django/django/blob/master/django/contrib/sessions/backends/cache.py

def create(self):
    # Because a cache can fail silently (e.g. memcache), we don't know if
    # we are failing to create a new session because of a key collision or
    # because the cache is missing. So we try for a (large) number of times
    # and then raise an exception. That's the risk you shoulder if using
    # cache backing.
    for i in xrange(10000):
        self._session_key = self._get_new_session_key()
        try:
            self.save(must_create=True)
        except CreateError:
            continue
        self.modified = True
        return
    raise RuntimeError("Unable to create a new session key.")
  • вы можете сделать обезьяну-патч django.contrib.sessions.backends.base.SessionBase._get_new_session_key, чтобы сделать time.sleep(0.001).
  • вы также можете проверить вашу энтропию :

вот команда:

cat /proc/sys/kernel/random/entropy_avail
3 голосов
/ 23 мая 2012

Глядя на код python-memcached на панели запуска, вы сможете настроить dead_retry и retry_timeout. Другим вариантом может быть запуск экземпляра memcached с низким объемом памяти или низким количеством соединений на одном или обоих серверах приложений в качестве запасного варианта, когда основной сервер memcached недоступен.

1 голос
/ 14 апреля 2015

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

В файле настроек для этой локальной версии Django для разработки я просто установил следующее значение:

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

Это не решение, которое я бы использовал в производственной среде, и не решение, которое я бы предложил оригинальному постеру, но мне потребовалось несколько минут, чтобы выяснить, в чем проблема, и это один из немногих результатов. это появилось, когда я погуглил, поэтому я решил опубликовать здесь, возможно, чтобы помочь другим с подобной проблемой.

0 голосов
/ 07 мая 2019

В файле / etc / sysconfig / memcached измените

-l 127.0.0.1 на -l 0.0.0.0

на некоторых машинах его в файле /и т.д. / memcached.conf

0 голосов
/ 29 июля 2015

С той же проблемой, с которой я столкнулся, проверьте, настроены ли порты в django и memcached. Возможно, оба они разные.

вы можете изменить порт memcached. Vim /etc/memcached.conf find 'Порт подключения по умолчанию' изменяется в соответствии с вашими потребностями. Перезапустите службы memcached

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...