震惊!Django缓存中的数据频频丢失,究竟谁是幕后黑手!

导语: Django Cache 内容不同步的真相

1.起因

昨天晚上尝试使用celery对Django缓存进行定时任务的更新, 但是发现定时任务并不能刷新到Django中, 由此开始了一阵debug

2.经过

2.1问题出现的场景

想使用一个后台任务在缓存中存放一些信息,然后在Django中有request的时候可以快速获取到页面信息, 但是失败了,用户在进入主页的时候并没有获取到后台任务在缓存中存放的信息

2.2尝试解决问题经过

首先使用celery打出cache对象的内存地址以及一些简单信息

代码逻辑如下

发现和views.py中的打出的cache内存不一

原因: 不同py进程在from django.core.cache import cache中获取的 cache 只是原型的复制品,并不是同一块内存

2.3 解决问题的过程

当然,我们的问题并没有解决,真正的原因是因为我一开始使用的是

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

我所使用的 LocMemCache 它的机制是不能做同步缓存的 (*见第三小节)

在更改为DatabaseCache之后,问题解决

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'django_cache',
    }
}

3.结论与文档

废话不多说,直接上官方文档吧:

Local-memory caching

This is the default cache if another is not specified in your settings file. If you want the speed advantages of in-memory caching but don’t have the capability of running Memcached, consider the local-memory cache backend. This cache is per-process (see below) and thread-safe. To use it, set BACKEND to “django.core.cache.backends.locmem.LocMemCache”. For example:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

The cache LOCATION is used to identify individual memory stores. If you only have one locmem cache, you can omit the LOCATION; however, if you have more than one local memory cache, you will need to assign a name to at least one of them in order to keep them separate.

Note that each process will have its own private cache instance, which means no cross-process caching is possible. This obviously also means the local memory cache isn’t particularly memory-efficient, so it’s probably not a good choice for production environments. It’s nice for development.

着重标记最后一段文档:

Note that each process will have its own private cache instance, which means no cross-process caching is possible. 注意每个进程都有自己的私有缓存实例,这意味着不可能有跨进程缓存

所以说,LocMemCache是不能用来做同步缓存的! 请使用别的任意Cache!

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

Khalil的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

JetBrains Rider 破解 (ideaIU等等开发工具都通用)

贴一下Rider下载地址:(下载不了可以用百度云离线下载) Win:https://download.jetbrains.com/resharper/JetBr...

3804
来自专栏Kirito的技术分享

Re:从零开始的Spring Session(三)

上一篇文章中,我们使用Redis集成了Spring Session。大多数的配置都是Spring Boot帮我们自动配置的,这一节我们介绍一点Spring Se...

34911
来自专栏程序猿DD

从零开始的Spring Session(三)

新媒体管家 上一篇文章中,我们使用Redis集成了Spring Session。大多数的配置都是Spring Boot帮我们自动配置的,这一节我们介绍一点Spr...

2798
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (3)

上一部分简单的弄了个web api 并通过Client_Credentials和ResourceOwnerPassword两种方式获取token然后进行api请...

3086
来自专栏Java Edge

Cookie设置HttpOnly属性

在Servlet 3.0中增加对Cookie(请注意,这里所说的Cookie,仅指和Session互动的Cookie,即人们常说的会话Cookie)较为全面的操...

1.5K7
来自专栏我的博客

HTTP 状态码汇总

400 Bad request(错误请求) 401.1 Logon failed(登录失败) 401.2 Logon failed due to serve...

3448
来自专栏优启梦

Servlet HTTP 状态码大全列表

状态行包括 HTTP 版本(在本例中为 HTTP/1.1)、一个状态码(在本例中为 200)和一个对应于状态码的短消息(在本例中为 OK)。

3647
来自专栏battcn

一起来学SpringBoot | 第十五篇:actuator与spring-boot-admin 可以说的秘密

一起来学SpringBoot | 第十四篇:强大的 actuator 服务监控与管理 中介绍了 actuator 的作用,细心的朋友可能会发现通过 http r...

1232
来自专栏文大师的新世界

3. spring security & oauth2

解释看代码字面意思就懂了,没什么特殊的,还可以修改比如登录表单里的用户名和密码的名字,还可以添加各种登录成功之后的handler等等,写法都一样。

1382
来自专栏技术博文

http状态码一览表

http状态码一览表 1**:请求收到,继续处理 2**:操作成功收到,分析、接受 3**:完成此请求必须进一步处理 4**:请求包含一个错误语法或不能完成 5...

3447

扫码关注云+社区