当前位置: 首页 > news >正文

常见的 2 中缓存

ttl_cache 通常指的是带有 TTL(Time-To-Live,生存时间) 的缓存机制,即缓存的数据在指定的时间后会自动失效。这种缓存策略广泛应用于各种场景,如 Web 开发、数据库查询优化、API 调用等,以提高性能并减少重复计算或网络请求。

1. TTL 的含义

  • TTL(Time-To-Live):表示缓存项的有效时间。一旦超过这个时间,缓存项将被视为过期,下次请求时需要重新生成或获取数据。
  • 例如,设置一个缓存的 TTL 为 60 秒,意味着该缓存项在 60 秒后失效,之后的请求将重新计算或从源获取数据。

2. 常见的 ttl_cache 实现

Python 中的 cachetools 库

cachetools 是一个常用的 Python 缓存库,提供了多种缓存策略,包括基于 TTL 的缓存。

安装
pip install cachetools
示例代码
from cachetools import TTLCache
import time# 创建一个最多存储 100 个条目,TTL 为 60 秒的缓存
cache = TTLCache(maxsize=100, ttl=60)def get_data(key):if key in cache:print("从缓存中获取数据")return cache[key]else:print("计算数据并存入缓存")# 模拟耗时操作data = f"数据_{key}_{int(time.time())}"cache[key] = datareturn data# 测试
print(get_data("test"))  # 第一次调用,计算数据
time.sleep(2)
print(get_data("test"))  # 第二次调用,从缓存中获取
装饰器形式的 ttl_cache

cachetools 还提供了装饰器形式的 @ttl_cache,可以更方便地为函数添加缓存。

from cachetools import ttl_cache
import time@ttl_cache(ttl=60, maxsize=100)
def get_user_info(user_id):print(f"查询用户 {user_id} 的信息")# 模拟耗时操作time.sleep(1)return {"user_id": user_id, "name": "张三", "timestamp": int(time.time())}# 测试
print(get_user_info(1))  # 第一次调用,查询用户信息
print(get_user_info(1))  # 第二次调用,从缓存中获取

3. 其他语言和框架中的 ttl_cache

JavaScript/Node.js

在 Node.js 中,可以使用 node-cachememory-cache 等库实现 TTL 缓存。

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 60 }); // TTL 60 秒function getData(key) {const cached = cache.get(key);if (cached) {console.log('从缓存中获取数据');return cached;} else {console.log('计算数据并存入缓存');const data = `数据_${key}_${Date.now()}`;cache.set(key, data);return data;}
}console.log(getData('test'));  // 第一次调用,计算数据
setTimeout(() => console.log(getData('test')), 2000);  // 第二次调用,从缓存中获取
Redis

Redis 是一个流行的内存数据结构存储,支持 TTL 缓存。

import redis
import jsonr = redis.Redis(host='localhost', port=6379, db=0)def get_data(key):cached = r.get(key)if cached:print("从 Redis 缓存中获取数据")return json.loads(cached)else:print("计算数据并存入 Redis 缓存")data = {"key": key, "value": f"数据_{key}_{int(time.time())}"}r.setex(key, 60, json.dumps(data))  # TTL 60 秒return dataprint(get_data("test"))  # 第一次调用,计算数据
time.sleep(2)
print(get_data("test"))  # 第二次调用,从缓存中获取

✅ 方法 1:使用 ex 参数(秒)

r = redis.Redis(host='localhost', port=6379, db=0)
r.set('my_key', 'my_value', ex=60)  # ex=60 表示 60 秒后过期

✅ 方法 2:使用 px 参数(毫秒)

r.set('my_key', 'my_value', px=60000)  # 60000 毫秒 = 60 秒

4. 应用场景

  • Web API 缓存:避免频繁调用外部 API,减少响应时间。
  • 数据库查询缓存:缓存复杂的查询结果,减少数据库负载。
  • 会话管理:存储用户会话信息,设置合理的过期时间。
  • 配置管理:缓存配置信息,避免频繁读取文件或数据库。

5. 注意事项

  • 内存管理:TTL 缓存会占用内存,需合理设置 maxsize 和 ttl,避免内存泄漏。
  • 一致性:缓存数据可能与源数据不一致,特别是在数据频繁更新的场景下。
  • 并发问题:在高并发环境下,多个请求可能同时触发缓存失效和重新计算,需考虑使用锁或其他同步机制。

💡 额外建议

1. 使用连接池(生产推荐)

from redis import ConnectionPoolpool = ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)

避免每次创建新连接。


2. 处理序列化(存字典、列表等)

Redis 只能存字节或字符串,所以复杂数据要序列化:

import jsondata = {'name': 'Alice', 'age': 30}
r.set('user:1', json.dumps(data), ex=300)# 读取时反序列化
raw = r.get('user:1')
user = json.loads(raw) if raw else None

3. 异常处理

import redistry:r = redis.Redis(host='localhost', port=6379, db=0, socket_connect_timeout=2)r.set('test', 'value', ex=60)
except redis.ConnectionError:print("Redis 连接失败")
except Exception as e:print(f"其他错误: {e}")

通过合理使用 ttl_cache,可以显著提升应用的性能和用户体验。

=========================

functools.lru_cache 是 Python 标准库中一个非常实用的装饰器(decorator),用于为函数添加 LRU 缓存(Least Recently Used Cache) 功能。

它的作用是:

缓存函数的返回值,避免重复计算,提升性能。


🚀 一、基本用法

from functools import lru_cache@lru_cache(maxsize=128)
def fibonacci(n):if n < 2:return nreturn fibonacci(n-1) + fibonacci(n-2)print(fibonacci(100))  # 第一次计算,结果会被缓存
print(fibonacci(100))  # 第二次直接从缓存返回,速度极快 ✅

🔍 二、参数详解

@lru_cache(maxsize=128, typed=False)

参数说明
maxsize缓存的最大条目数。默认 128,设为 None 表示无限制
typed是否区分参数类型。True 时,fibonacci(3.0) 和 fibonacci(3) 被视为不同调用
示例:typed=True 的影响
@lru_cache(maxsize=32, typed=True)
def add(x, y):print(f"计算 {x} + {y}")return x + yadd(1, 2)     # 计算 1 + 2
add(1.0, 2.0) # 再次计算,因为 1.0 和 1 类型不同(float vs int)

🧠 三、工作原理

  • 缓存键(Cache Key):基于函数的位置参数和关键字参数生成。
  • LRU 策略:当缓存满时,最近最少使用(Least Recently Used) 的条目会被清除。
  • 存储位置:在函数的内存中(属于该函数对象的一部分)。

✅ 四、适用场景(适合缓存的函数)

  1. 纯函数(Pure Function)

    • 相同输入 → 相同输出
    • 无副作用(不修改全局状态)
  2. 计算密集型

    • 递归、数学计算、复杂逻辑
  3. 频繁调用且参数重复

    • 如 API 调用封装、数据库查询(简单场景)

⚠️ 五、不适用场景(慎用!)

场景问题
函数有副作用缓存后不会再次执行,副作用丢失
返回可变对象(如 list、dict)多次调用返回同一个对象,修改会影响其他调用
参数是不可哈希类型如 listdictset 会报错 TypeError: unhashable type
多线程/多进程共享问题缓存是线程安全的,但每个进程有自己的缓存副本
❌ 错误示例:
@lru_cache
def get_data():return {'time': time.time()}  # ❌ 返回可变字典,且时间会变

📊 六、性能监控(高级用法)

lru_cache 提供了 .cache_info().cache_clear() 方法:

@lru_cache(maxsize=32)
def square(n):return n * nsquare(2)
square(3)
square(2)  # 命中缓存print(square.cache_info())
# 输出:CacheInfo(hits=1, misses=2, maxsize=32, currsize=2)square.cache_clear()  # 手动清空缓存

🆚 七、与 cachetools.ttl_cache 对比

特性functools.lru_cachecachetools.ttl_cache
是否标准库✅ 是❌ 需安装 pip install cachetools
过期机制LRU(按使用频率)TTL(按时间)
是否支持过期时间❌ 不支持✅ 支持 ttl=60 秒
多进程共享❌ 每个进程独立❌ 同样独立(除非用 Redis)
适合场景纯计算、递归API 缓存、数据库查询、有时效性要求

✅ 八、最佳实践建议

  1. 优先用于纯函数:无副作用、输入输出确定。
  2. 设置合理的 maxsize:避免内存泄漏。
  3. 避免缓存可变对象:返回 tuple 而不是 list
  4. 在数据变化时手动清除缓存(如果有依赖):
    square.cache_clear()  # 清除所有缓存
  5. 生产环境复杂缓存用 Redislru_cache 只适合单进程、无持久化需求的场景。

🎯 总结

问题回答
lru_cache 是什么?Python 内置的 LRU 缓存装饰器
适合什么函数?纯函数、计算密集型、参数可哈希
缓存会自动更新吗?❌ 不会,除非手动清除或 LRU 淘汰
重启后还存在吗?❌ 不存在,存储在内存中
生产环境能用吗?✅ 可以,但复杂场景建议用 Redis

==============================

django.core.cache 是 Django 框架中用于缓存系统的核心模块。它提供了一套统一的 API,让你可以轻松地在 Django 项目中使用各种缓存后端(如内存、Redis、数据库等),从而大幅提升网站性能


🚀 一、为什么要用缓存?

在 Web 开发中,有些操作很耗时,比如:

  • 复杂的数据库查询
  • 调用外部 API
  • 渲染大型模板

缓存的作用就是:

把结果存起来,下次直接用,避免重复计算或请求


📦 二、django.core.cache 能干什么?

它提供了:

  • 统一的缓存 API
  • 支持多种缓存后端
  • 视图缓存、模板片段缓存、低级缓存 API
  • 过期时间(TTL)支持

🔧 三、如何配置(settings.py)

首先在 settings.py 中配置缓存后端:

# settings.pyCACHES = {'default': {'BACKEND': 'django.core.cache.backends.redis.RedisCache',  # Redis'LOCATION': 'redis://127.0.0.1:6379/1','TIMEOUT': 300,  # 缓存默认超时时间(秒),默认 300'OPTIONS': {'CLIENT_CLASS': 'django_redis.client.DefaultClient',}},'local': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 本地内存'LOCATION': 'unique-snowflake',}
}# 可选:设置默认缓存
CACHE_MIDDLEWARE_ALIAS = 'default'
CACHE_MIDDLEWARE_SECONDS = 600
CACHE_MIDDLEWARE_KEY_PREFIX = 'mysite'

⚠️ 如果你用 Redis,需要安装:pip install django-redis


🛠 四、常用缓存后端

后端说明是否推荐
redis.RedisCacheRedis 缓存(高性能,生产推荐)✅ 强烈推荐
locmem.LocMemCache本地内存缓存(开发用)✅ 开发
filebased.FileBasedCache文件系统缓存⚠️ 性能差
db.DatabaseCache数据库表缓存⚠️ 一般不用
memcached.PyMemcacheCacheMemcached✅ 生产可用

💡 五、使用方式

1. 低级缓存 API(最灵活)

from django.core.cache import cache# 写入缓存
cache.set('my_key', 'Hello, Cache!', timeout=60)  # 60秒后过期# 读取缓存
value = cache.get('my_key')  # 'Hello, Cache!'
value = cache.get('not_exist', 'default')  # 如果不存在,返回默认值# 删除缓存
cache.delete('my_key')# 批量操作
cache.set_many({'a': 1, 'b': 2})
values = cache.get_many(['a', 'b'])  # {'a': 1, 'b': 2}# 设置过期时间
cache.set('user_1', user_data, 300)  # 5分钟

2. 视图缓存(缓存整个页面)

from django.views.decorators.cache import cache_page@cache_page(60 * 15)  # 缓存 15 分钟
def my_view(request):# 复杂查询或渲染return render(request, 'my_template.html')

URL 每次访问都会从缓存返回,直到过期。


3. 模板片段缓存

{% load cache %}<!-- 缓存这个片段 500 秒 -->
{% cache 500 user_info user.id %}<div><h1>{{ user.name }}</h1><p>{{ user.profile.bio }}</p></div>
{% endcache %}

如果 user.id 变了,缓存也会更新(因为它是缓存键的一部分)。


4. 缓存用户特定内容

# 使用 vary_on_cookie 或 vary_on_headers
from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie@cache_page(60)
@vary_on_cookie
def user_dashboard(request):# 不同用户的缓存是分开的return render(request, 'dashboard.html')

🔄 六、缓存键(Cache Key)生成

Django 会自动为每个缓存生成唯一的 key,比如:

  • 视图缓存:views.decorators.cache.cache_page.{hash}.{path}.{lang}
  • 低级缓存:你指定的 key(如 'my_key'

你也可以自定义 key 生成函数:

def make_key(key, key_prefix, version):return f'{key_prefix}:{version}:{key}'CACHES = {'default': {'BACKEND': '...','KEY_FUNCTION': 'myapp.utils.make_key',}
}

🧹 七、清除缓存

# 删除单个 key
cache.delete('my_key')# 删除多个
cache.delete_many(['key1', 'key2'])# 清空所有(慎用!)
cache.clear()# 删除带前缀的 key(需要 django-redis)
from django.core.cache import caches
cache = caches['default']
cache.delete_pattern('user_*')  # 删除所有 user_ 开头的 key

✅ 八、最佳实践

建议说明
✅ 生产用 Redis性能好,支持 TTL,多进程共享
✅ 设置合理的 TIMEOUT不要太长(数据过期),不要太短(失去缓存意义)
✅ 在数据变更时主动清除缓存避免脏数据
✅ 使用 cache.get_or_set()原子操作,更安全
# 推荐写法
data = cache.get_or_set('expensive_data', compute_expensive_data, 300)

🎯 总结

功能方法
缓存数据cache.set(key, value, timeout)
获取数据cache.get(key, default)
删除数据cache.delete(key)
缓存整个页面@cache_page(60)
缓存模板片段{% cache 60 name %}
生产推荐后端Redis

django.core.cache 是 Django 性能优化的核心工具之一。掌握它,你的网站速度会快上好几倍

http://www.dtcms.com/a/390435.html

相关文章:

  • Python基于Django的微博舆情可视化系统 关键词/用户ID/评论分析 大数据项目(建议收藏)✅
  • 四大访问控制模型:OBAC、RBAC、TBAC与ABAC的对比与应用
  • 如何使用AI IDE书写Vue3数据可视化大屏项目
  • React 类名控制工具库ClassName 简化类写法 条件控制 样式处理
  • 【MySQL】用户和权限管理
  • STM32项目分享:游泳馆闸机计费管理系统设计
  • 《C++进阶之STL》【unordered_set/unordered_map 模拟实现】
  • LLM中如何添加special_token,并且尽可能保持原模型的训练效果
  • [x-cmd] 使用系统包管理器安装 x-cmd
  • 亮数据MCP结合Dify:构建自动化视频数据抓取与智能分析工作流的深度实践
  • 革新交互体验,开启未来智慧生活 —— OPE.AI 多语言多模态AI产品
  • 生活琐记(2)
  • 一文读懂HTTP 1.1/2.0/3.0:从原理到应用的通俗解析
  • JavaStream用法全解析
  • 在日常开发中实现异常处理和空值处理的最佳实践
  • openstack port binding failure (by quqi99)
  • leetcode 3484. 设计电子表格 中等
  • Docker+cpolar 实战:打造灵活可控的远程办公系统
  • uniApp开发XR-Frame微信小程序 | 设置透明贴图
  • M3 Ultra版Mac Studio无法正常升级到macOS 26.0 苹果已经在调查
  • 老的ios项目在新的mac M1上编译运行遇到的问题及整理
  • Java 大视界 -- Java 大数据机器学习模型在元宇宙虚拟场景智能交互中的关键技术
  • 2025年目标检测还有什么方向好发论文?
  • 离线openHarmonySdk鸿蒙系统动态库的封装
  • 从零实现鸿蒙智能设备数据采集:权限、传感器、云端上传全流程实战
  • 智慧医院IBMS中央集成系统解决方案:构建医疗安全优先的智慧运营中枢​
  • ✅ Python房源数据采集+分析+预测平台 requests爬虫+sklearn回归 大数据实战项目(建议收藏)机器学习(附源码)
  • 结婚证 OCR 识别:政务服务提速的 “关键一环”
  • Git企业开发--多人协作
  • 【论文阅读 | IF 2025 | IF-USOD:用于水下显著目标检测的多模态信息融合交互式特征增强架构】