Django缓存系统
一、今日学习内容概述
学习模块 | 重要程度 | 预计学时 | 主要内容 |
---|---|---|---|
缓存基础概念 | ⭐⭐⭐⭐⭐ | 1小时 | 缓存原理、配置方式 |
Django内置缓存后端 | ⭐⭐⭐⭐⭐ | 2小时 | 内存、文件、数据库缓存 |
Redis缓存后端 | ⭐⭐⭐⭐⭐ | 2小时 | Redis配置、使用方式 |
缓存最佳实践 | ⭐⭐⭐⭐ | 1小时 | 性能优化、策略设计 |
二、Django缓存配置
2.1 基本配置
python
# settings.py
# Memcached配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
# Redis配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PASSWORD': 'your-password', # 如果有密码
}
}
}
# 文件系统缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 300, # 5分钟
'OPTIONS': {
'MAX_ENTRIES': 1000,
'CULL_FREQUENCY': 3,
}
}
}
# 本地内存缓存
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
三、缓存使用示例
3.1 视图级缓存
python
# views.py
from django.views.decorators.cache import cache_page
from django.core.cache import cache
from django.shortcuts import render
from .models import Article
# 使用装饰器缓存整个视图
@cache_page(60 * 15) # 缓存15分钟
def article_list(request):
articles = Article.objects.all()
return render(request, 'articles/list.html', {'articles': articles})
# 手动管理缓存
def article_detail(request, pk):
cache_key = f'article_{pk}'
article = cache.get(cache_key)
if article is None:
try:
article = Article.objects.get(pk=pk)
# 缓存文章,有效期1小时
cache.set(cache_key, article, 60 * 60)
except Article.DoesNotExist:
return HttpResponse('文章不存在', status=404)
return render(request, 'articles/detail.html', {'article': article})
3.2 模板片段缓存
html
<!-- templates/articles/list.html -->
{% load cache %}
<div class="article-list">
{% cache 300 'article_list' %}
{% for article in articles %}
<div class="article-item">
<h2>{{ article.title }}</h2>
<p>{{ article.summary }}</p>
</div>
{% endfor %}
{% endcache %}
</div>
3.3 自定义缓存类
python
# cache_utils.py
from django.core.cache import cache
from functools import wraps
import hashlib
import json
class CacheManager:
def __init__(self, timeout=300):
self.timeout = timeout
def generate_key(self, *args, **kwargs):
"""生成缓存键"""
key_dict = {
'args': args,
'kwargs': kwargs
}
key_str = json.dumps(key_dict, sort_keys=True)
return hashlib.md5(key_str.encode()).hexdigest()
def cache_decorator(self, prefix=''):
"""缓存装饰器"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
cache_key = f"{prefix}_{self.generate_key(*args, **kwargs)}"
result = cache.get(cache_key)
if result is None:
result = func(*args, **kwargs)
cache.set(cache_key, result, self.timeout)
return result
return wrapper
return decorator
def invalidate(self, prefix='', *args, **kwargs):
"""清除缓存"""
cache_key = f"{prefix}_{self.generate_key(*args, **kwargs)}"
cache.delete(cache_key)
# 使用示例
cache_manager = CacheManager(timeout=3600)
@cache_manager.cache_decorator(prefix='get_user_data')
def get_user_data(user_id):
# 耗时的数据库查询
return User.objects.get(id=user_id).get_full_data()
四、Redis缓存实现
4.1 Redis缓存管理器
python
# redis_cache.py
import json
from django_redis import get_redis_connection
from datetime import datetime
class RedisCacheManager:
def __init__(self, connection='default'):
self.redis = get_redis_connection(connection)
def set_json(self, key, data, timeout=None):
"""存储JSON数据"""
json_data = json.dumps(data)
if timeout:
self.redis.setex(key, timeout, json_data)
else:
self.redis.set(key, json_data)
def get_json(self, key):
"""获取JSON数据"""
data = self.redis.get(key)
if data:
return json.loads(data)
return None
def increment(self, key, amount=1):
"""递增计数器"""
return self.redis.incr(key, amount)
def expire(self, key, timeout):
"""设置过期时间"""
self.redis.expire(key, timeout)
def delete(self, key):
"""删除键"""
self.redis.delete(key)
def clear_prefix(self, prefix):
"""清除指定前缀的所有键"""
keys = self.redis.keys(f"{prefix}:*")
if keys:
self.redis.delete(*keys)
# 使用示例
class ArticleService:
def __init__(self):
self.cache = RedisCacheManager()
def get_article_cache_key(self, article_id):
return f"article:{article_id}"
def get_article(self, article_id):
cache_key = self.get_article_cache_key(article_id)
article_data = self.cache.get_json(cache_key)
if not article_data:
article = Article.objects.get(id=article_id)
article_data = {
'id': article.id,
'title': article.title,
'content': article.content,
'updated_at': article.updated_at.isoformat()
}
self.cache.set_json(cache_key, article_data, timeout=3600)
return article_data
五、缓存流程图
六、高级缓存策略
6.1 分层缓存
python
class LayeredCache:
def __init__(self):
self.local_cache = caches['local']
self.redis_cache = caches['redis']
def get(self, key):
# 先查本地缓存
value = self.local_cache.get(key)
if value is not None:
return value
# 查Redis缓存
value = self.redis_cache.get(key)
if value is not None:
# 写入本地缓存
self.local_cache.set(key, value, timeout=60)
return value
return None
def set(self, key, value, timeout=None):
# 同时写入本地缓存和Redis
self.local_cache.set(key, value, timeout=min(timeout, 60) if timeout else 60)
self.redis_cache.set(key, value, timeout=timeout)
6.2 缓存预热
python
# cache_warmer.py
from django.core.cache import cache
from django.db.models import Q
from datetime import datetime, timedelta
class CacheWarmer:
def __init__(self):
self.cache = cache
def warm_article_cache(self):
"""预热热门文章缓存"""
# 获取最近一周的热门文章
recent_date = datetime.now() - timedelta(days=7)
popular_articles = Article.objects.filter(
Q(created_at__gte=recent_date) |
Q(view_count__gte=1000)
).select_related('author')
for article in popular_articles:
cache_key = f'article_{article.id}'
self.cache.set(cache_key, article, timeout=3600)
return len(popular_articles)
# 在Django管理命令中使用
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = '预热缓存'
def handle(self, *args, **kwargs):
warmer = CacheWarmer()
count = warmer.warm_article_cache()
self.stdout.write(
self.style.SUCCESS(f'Successfully warmed cache for {count} articles')
)
七、缓存监控和管理
python
# cache_monitor.py
from django.core.cache import cache
import time
import logging
logger = logging.getLogger(__name__)
class CacheMonitor:
def __init__(self):
self.cache = cache
def monitor_operation(self, operation_name):
"""监控缓存操作的装饰器"""
def decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
elapsed_time = time.time() - start_time
self.log_operation(operation_name, True, elapsed_time)
return result
except Exception as e:
elapsed_time = time.time() - start_time
self.log_operation(operation_name, False, elapsed_time, str(e))
raise
return wrapper
return decorator
def log_operation(self, operation, success, elapsed_time, error=None):
"""记录缓存操作日志"""
log_data = {
'operation': operation,
'success': success,
'elapsed_time': elapsed_time,
'error': error
}
if success:
logger.info(f'Cache operation: {operation}', extra=log_data)
else:
logger.error(f'Cache operation failed: {operation}', extra=log_data)
八、性能优化建议
- 缓存键设计
- 使用有意义的前缀
- 避免过长的键名
- 考虑版本号机制
- 缓存粒度
- 合理划分缓存单位
- 避免过大的缓存对象
- 考虑部分字段缓存
- 缓存策略
- 设置合适的过期时间
- 实现缓存预热机制
- 使用分层缓存提高命中率
- 缓存清理
- 及时清理过期缓存
- 实现缓存更新机制
- 避免缓存穿透
九、总结
今天我们学习了:
- Django缓存系统的基本配置
- 多种缓存后端的使用方法
- 自定义缓存管理器的实现
- 缓存性能优化策略
怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!