2011-07-29 103 views
14

客户端的Dj​​ango应用程序是间歇性(大约一天两次)投掷RuntimeError("Unable to create a new session key.")如何防止RuntimeError(“无法创建新的会话密钥”)?

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),当从应用程序服务器到memcache服务器的TCP连接由于数据包丢失而超时时,可能会发生此异常。

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

我不知道如何解决这个问题。我想调整Linux的TCP重传定时器低于3秒,但它不可调。如果不行,我想让python-memcache在放弃之前重试一次连接,但它不会。我发现pylibmc具有可配置的连接和重试行为,但是我一直无法找到可以解决数据包丢失的选项组合。

想法?

+0

我有纯的Django的DEV-服务器同样的问题。发布请你的设置。 – I159

+0

不是你正在寻找的答案 - 但是redis是一个选项?特别是对于会话,因为Redis具有基于磁盘的备份,如果服务重新启动,则memcached将会终止您的用户会话。 :( –

回答

3

查看启动板上的python-memcached代码,您应该可以调整dead_retryretry_timeout。另一种选择可能是在主要memcached服务器无法访问时,在一台或两台应用程序服务器上运行memcached的低内存,低连接实例作为回退。

+0

我喜欢运行本地memcache作为备份的想法 – claymation

+0

你是怎么解决这个@claymation的?提供更多详细信息? – silviomoreto

+0

我没有解决它:) – claymation

5

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

欧,抱歉,这不是你的情况。我只是阅读更多关注的问题。但我会留下我的答案 - 因为这是关于这个运行时错误。

+0

谢谢,但在应用程序服务器本地运行缓存(这是我认为你建议的)不是一个选项,因为我们有多个应用程序服务器,并希望在所有应用程序服务器之间共享缓存。 – claymation

+0

@claymation,我刚刚告诉过可能的原因,当然memcached可以在其他服务器上。 –

+0

谢谢@尼科莱Fominyh – AmanKumar

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_keytime.sleep(0.001)
  • check your entropy可以:

这里的命令:

cat /proc/sys/kernel/random/entropy_avail 
1

我得到这个错误运行的Django项目的地方,开发版本,因为它是定期在连接到故障非本地缓存。我realized,我可以将我的会话后端更改为a file-based session来解决该问题。

在设置文件的Django的这个地方,开发版,我简单地设置以下值:

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

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

0

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

你可以改变memcached的端口VIM /etc/memcached.conf找到“默认连接端口是”根据您的需要改变重新启动的memcached服务