【问题标题】:Django Sessions via Memcache: Cannot find session key manually通过 Memcache 的 Django 会话:无法手动找到会话密钥
【发布时间】:2017-12-12 09:05:02
【问题描述】:

我最近使用 pylibmc 从数据库支持的会话迁移到通过 memcached 存储的会话。

这是我的 settings.py 中的 CACHES、SESSION_CACHE_ALIAS 和 SESSION_ENGINE

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': ['127.0.0.1:11211'],
    }
}


SESSION_CACHE_ALIAS = 'default'


SESSION_ENGINE = "django.contrib.sessions.backends.cache"

幕后一切正常,我可以看到它正在使用新的缓存系统。从 pylibmc 运行 get_stats() 方法会显示缓存中当前项目的数量,我可以看到它增加了 1。

问题是我无法使用 pylibmc 手动获取会话。

在views.py中检查请求会话数据时:

def my_view(request):
    if request.user.is_authenticated():

        print request.session.session_key
        # the above prints something like this: "1ay2kcv7axb3nu5fwnwoyf85wkwsttz9"

        print request.session.cache_key
        # the above prints something like this: "django.contrib.sessions.cache1ay2kcv7axb3nu5fwnwoyf85wkwsttz9"

        return HttpResponse(status=200)
    else:
        return HttpResponse(status=401)

我注意到在打印 cache_key 时,它使用默认的 KEY_PREFIX 打印,而 session_key 则没有。看看代码中的 cmets 就明白我的意思了。

所以我想,“好的,很好,其中一个键名应该可以工作。让我尝试手动获取会话数据,仅用于教育目的”:

import pylibmc

mc = pylibmc.Client(['127.0.0.1:11211'])

# Let's try key "1ay2kcv7axb3nu5fwnwoyf85wkwsttz9"

mc.get("1ay2kcv7axb3nu5fwnwoyf85wkwsttz9")

嗯,没有任何反应,该名称不存在密钥。好的,不用担心,我们试试 cache_key,那肯定可以正常工作?

mc.get("django.contrib.sessions.cache1ay2kcv7axb3nu5fwnwoyf85wkwsttz9")

什么?我怎么还是一无所获?当我测试时,我决定设置并获取一个随机键值,看看它是否有效。我再次运行 get_stats() 只是为了确保密钥确实存在。我还测试了网络应用程序,看看我的会话是否确实有效并且确实有效。所以这让我得出结论,我不知道有一个不同的命名方案。

如果是,正确的命名方案是什么?

【问题讨论】:

    标签: django session caching memcached pylibmc


    【解决方案1】:

    是的,Django 内部使用的缓存键通常与发送到缓存后端(在本例中为 pylibmc / memcached)的键不同。让我们将这两个键分别称为 django 缓存键和最终缓存键。

    request.session.cache_key 给出的 django 缓存键 用于 Django 的低级缓存 API,例如:

    >>> from django.core.cache import cache
    >>> cache.get(request.session.cache_key)
    {'_auth_user_hash': '1ay2kcv7axb3nu5fwnwoyf85wkwsttz9', '_auth_user_id': u'1', '_auth_user_backend': u'django.contrib.auth.backends.ModelBackend'}
    

    另一方面,最终缓存键key prefix、django缓存键和缓存version number的组合。下面的 make_key 函数(来自 Django docs)演示了如何组合这三个值来生成这个键:

    def make_key(key, key_prefix, version):
        return ':'.join([key_prefix, str(version), key])
    

    默认情况下,key_prefix 为空字符串,version 为 1。

    最后,通过检查make_key,我们发现正确的最终缓存键传递给mc.get

    :1:django.contrib.sessions.cache1ay2kcv7axb3nu5fwnwoyf85wkwsttz9
    

    格式为<KEY_PREFIX>:<VERSION>:<KEY>

    注意:可以通过在缓存设置中定义KEY_FUNCTION来更改最终的缓存键。

    【讨论】:

      猜你喜欢
      • 2021-09-02
      • 2013-04-28
      • 2023-04-06
      • 1970-01-01
      • 2012-06-26
      • 2014-10-29
      • 1970-01-01
      • 2017-12-10
      • 2017-02-14
      相关资源
      最近更新 更多