如何防止RuntimeError(“无法创建新的会话密钥。”)?

时间:2011-07-29 05:55:34

标签: django amazon-ec2 memcached

客户端的Dj​​ango应用程序间歇性地(大约每天两次)投掷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.

从回溯中可以看出,当使用缓存会话后端和memcached缓存后端时,这会发生在django.contrib.sessions的内部深处。

Django trac票证(https://code.djangoproject.com/ticket/14093)建议将会话密钥哈希从MD5更改为UUID4,但这没有帮助 - 问题在于网络。我观察到(使用tcpdump)当从app server到memcache服务器的TCP连接由于丢包而超时时,会发生此异常。

我们有两个app服务器和一个memcached(1.4.2)服务器,所有服务器都在Amazon EC2中运行。在高需求期间,我观察到一个应用服务器与memcache服务器交换75,000个数据包/秒。在这个需求高的时期,我观察到一个SYN数据包丢失了一个新的memcache连接,导致python-memcache连接超时(在内核改变重传之前)和RuntimeError

我对如何解决这个问题感到茫然。我想调整Linux的TCP重传计时器低于三秒,但它不可调。如果做不到这一点,我想让python-memcache在放弃之前重试连接几次,但事实并非如此。我看到pylibmc具有可配置的连接和重试行为,但我无法找到解决丢包问题的选项组合。

想法?

6 个答案:

答案 0 :(得分:5)

刚刚用apt-get install memcached解决了同样的问题。可能也是你的情况。

哦,对不起,这不是你的情况。我只是更加注意阅读问题。但我会留下我的答案 - 因为它是关于这个运行时错误。

答案 1 :(得分:3)

查看启动板上的python-memcached代码,您应该可以调整dead_retryretry_timeout。另一个选项可能是在主存储器服务器无法访问时,在一个或两个应用服务器上运行memcached的低内存,低连接实例作为后备。

答案 2 :(得分:3)

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)
  • 你也可以check your entropy

这是命令:

cat /proc/sys/kernel/random/entropy_avail

答案 3 :(得分:1)

我在运行Django项目的本地开发版本时遇到此错误,因为它经常无法连接到非本地缓存。我realized我可以将会话后端更改为a file-based session以解决此问题。

在本地开发版Django的设置文件中,我只需设置以下值:

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

这不是我在生产环境中使用的解决方案,而不是我建议原始海报的解决方案,但我花了几分钟才弄清楚问题是什么,这是唯一的结果之一当我用谷歌搜索时出现,所以我想我会在这里发帖,可能会帮助其他类似的问题。

答案 4 :(得分:0)

我面临同样的问题,检查在django和memcached中配置的端口。可能两者都不同。

你可以改变memcached port vim /etc/memcached.conf找到'默认连接端口是'根据你的需要改变了重新启动memcached服务

答案 5 :(得分:0)

在文件/ etc / sysconfig / memcached中 更改

  

-l 127.0.0.1至-l 0.0.0.0

在某些机器上,它在文件/etc/memcached.conf