【19.0】路飞项目之Redis的使用
【一】Django中使用Redis
【1】自定义的通用方案(跟框架无关)
(1)引入(无池)
- 自定义计数器
import redis
class TextResponse(APIView):
def get(self, request):
conn = redis.Redis(host='127.0.0.1', port=6379, db=0, decode_responses=True)
# 每访问一次,Redis中的 num 值 都会 +1
# 该方案没有池,只能一个接一个处理请求
conn.incrby('num', 1)
result = conn.get('num')
print(result)
return CommonResponse(msg='Redis测试成功')
- 每访问一次该路由,在Redis中都会将 num 进行自加一操作
(2)迭代(有池)
luffyCity\luffyCity\utils\common_redis_pool.py
import redis
# 创建redis连接池
POOL = redis.ConnectionPool(max_connections=30, host="127.0.0.1", port=6379, decode_responses=True)
import redis
class TextResponse(APIView):
def get(self, request):
# 从连接池中获取连接对象
conn = redis.Redis(connection_pool=POOL)
# 每访问一次,Redis中的 num 值 都会 +1
conn.incrby('num', 1)
result = conn.get('num')
print(result)
return CommonResponse(msg='Redis测试成功')
【2】借助Django中的第三方模块
- django中有个模块,django-redis,方便我们快速集成redis
(1)下载安装
pip install django-redis
(2)配置文件中添加配置
luffyCity\luffyCity\settings\dev.py
###############Redis配置文件#################
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379", # 走 Redis 协议
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池大小
# "PASSWORD": "123", # 有密码可以自配置密码
}
}
}
(3)视图类中使用
# 导入模块
from django_redis import get_redis_connection
# 视图类中使用
conn = get_redis_connection() # 从连接池中拿出一个链接
- 示例
# 导入模块
from django_redis import get_redis_connection
class TextResponse(APIView):
def get(self, request):
conn = get_redis_connection() # 从连接池中拿出一个链接
conn.incrby('num')
result = conn.get('num')
print(result)
conn.set('name', f'dream&{result}')
return CommonResponse(msg='Redis测试成功')
【二】Django之缓存
【1】内置缓存
- django 是大而全的框架,内置了很多web开发需要的东西,缓存内置了
from django.core.cache import cache
cache.set('key','value',5) # 存放值
res=cache.get('key') # 取值
【2】更多方案
- 缓存:可以把django中的一个变量(数据),存放到某个位置,下次还可以取出来
- 之前用过:默认放在:内存中,其实可以放在文件中,数据库,redis。。。。
【3】放在redis
- 通过配置,控制存放在哪,只要如下写,就会放在redis中
###############Redis配置文件#################
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379", # 走 Redis 协议
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池大小
# "PASSWORD": "123", # 有密码可以自配置密码
}
}
}
【4】示例
- Redis 不支持放列表 ,需要转成字符串才能存进去 ---- 可以采用 JSON序列化一下
- django缓存最强大之处在于,只要是python的变量,任意类型都可以,尽管使用set设置值
- 缓存中可以设置任意类型的值,比如字典,列表,字符串,数字,元组,集合,对象等
# 测试缓存
class TextResponse(APIView):
def get(self, request):
# 将缓存放到cache中 (键,值,失效时间)
cache.set('name', 'dream', 30)
# conn = get_redis_connection() # 从连接池中拿出一个链接
# conn.lpush("l2",[1, 3, 4, 5, 6]) # Redis 不支持放列表 ,需要转成字符串才能存进去 ---- 可以采用 JSON序列化一下
# django缓存最强大之处在于,只要是python的变量,任意类型都可以,尽管使用set设置值
# 缓存中可以设置任意类型的值,比如字典,列表,字符串,数字,元组,集合,对象等
l = [1, 'hope', [1, 3, 4, 5, 6], '蚩梦']
cache.set('ll1', l)
result = cache.get('name')
print(result)
return CommonResponse(msg='Redis测试成功')
【三】celery介绍
异步任务开启线程,不好管理)
定时任务
延迟任务
借助于第三方框架,celery:芹菜,吉祥物,可以实现上面的三个功能
- http://www.celeryproject.org/
分布式的异步任务框架 celery
【简解】
- Celery是一个分布式的异步任务框架,可以实现异步任务、定时任务和延迟任务的功能。
- 在Django中使用Celery,可以更好地处理异步任务,并提高应用的性能和可扩展性。
(1)安装Celery和Redis
- 首先,在Django项目中安装Celery和Redis:
pip install celery redis
(2)配置Celery
- 在Django项目的settings.py文件中,添加Celery的配置信息:
# settings.py
CELERY_BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
- 上述配置中
CELERY_BROKER_URL
指定了Celery的消息代理(这里使用Redis)CELERY_RESULT_BACKEND
指定了Celery任务结果的存储位置。
(3)创建celery.py文件
- 在Django项目的根目录下创建一个名为celery.py的文件,并添加以下内容:
# celery.py
import os
from celery import Celery
# 设置Django环境变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings')
# 创建Celery实例
app = Celery('your_project')
# 加载Celery配置
app.config_from_object('django.conf:settings', namespace='CELERY')
# 自动发现异步任务
app.autodiscover_tasks()
(4)定义异步任务
- 在Django项目的某个应用中,创建tasks.py文件,并定义异步任务:
# your_app/tasks.py
from celery import shared_task
@shared_task
def send_email_task(to, subject, message):
# 模拟发送邮件的耗时操作
print(f"Sending email to {to}: {subject}")
print(f"Message: {message}")
- 在上面的代码中,使用
shared_task
装饰器定义一个名为send_email_task
的异步任务。
(5)调用异步任务
- 在Django的视图函数或其他逻辑中,可以通过调用异步任务来实现对应的功能:
# views.py
from your_app.tasks import send_email_task
def some_view(request):
# 异步调用发送邮件任务
send_email_task.delay("example@example.com", "Hello", "This is a test email")
return HttpResponse("Task started")
- 在上述代码中,通过
send_email_task.delay()
方法异步调用发送邮件任务,并立即返回响应给用户,不会阻塞主线程。
(6)注意事项:
- 为了确保Celery能够自动发现异步任务,需要在Django项目根目录下运行Celery的worker进程:
celery -A your_project worker --loglevel=info
- 如果需要使用定时任务和延迟任务,在Celery配置中添加相应的定时器和调度器,例如使用
beat_schedule
配置项。
(7)总结:
- 在Django中使用Celery可以实现异步任务、定时任务和延迟任务的功能,提高应用的性能和可扩展性。
- 需要安装Celery和消息代理(如Redis)。
- 配置Celery信息在Django的settings.py文件中。
- 创建celery.py文件来加载Celery配置并自动发现异步任务。
- 定义异步任务并使用
shared_task
装饰器进行注册。 - 在适当的地方调用异步任务并使用
.delay()
方法来异步执行任务。
【补充】JSON序列化和pickle序列化
- json序列化 ---> 得到字符串
- json不能序列化对象(自定义的类的对象)
- 数据结构:数据的组织形式跟下面不一样
- 能序列化: 数字,字符串,布尔,列表,字典 时间对象
- pickle序列化
- python独有的,二进制形式
- python可以序列化所有对象 ---> 二进制形式
- 二进制 ---> 返序列化回来 ---> 对象:属性,有方法
- json序列化是将数据结构转换为字符串的过程。
- 它可以将数字、字符串、布尔值、列表、字典和时间对象等基本数据类型进行序列化,从而得到一个字符串表示。
- 然而,json无法直接将自定义的类对象进行序列化。
- 只有实现了序列化接口的对象才能被json序列化。
- 这意味着,如果要对自定义类对象进行序列化,需要先将其转换为可序列化的数据结构,如字典或元组。
- 一种常见的做法是通过定义类的
__dict__
属性来将类对象转换为字典,然后再进行json序列化。
- 下面是一个使用json序列化的示例代码:
import json
data = {
"name": "John",
"age": 30,
"is_employed": True,
"hobbies": ["reading", "playing guitar"],
"address": {
"street": "123 Main St",
"city": "New York"
}
}
# 将数据结构序列化为字符串
json_str = json.dumps(data)
print(json_str)
-
在上述代码中,我们定义了一个
data
字典,其中包含了不同类型的数据,包括字符串、整数、布尔值、列表以及嵌套字典。- 调用
json.dumps()
函数将data
序列化为字符串并打印输出。
- 调用
-
相比之下,pickle序列化是Python特有的一种序列化方式,它将对象序列化为二进制数据。
- 与json不同,pickle可以序列化Python中的任意对象,包括自定义的类对象,并且可以保留对象的属性和方法。
-
下面是一个使用pickle序列化的示例代码:
import pickle
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say_hello(self):
print(f"Hello, my name is {self.name}.")
person = Person("John", 30)
# 对象序列化为二进制数据
pickled_data = pickle.dumps(person)
print(pickled_data)
# 将二进制数据反序列化为对象
unpickled_person = pickle.loads(pickled_data)
unpickled_person.say_hello()
- 在上述代码中,我们定义了一个
Person
类,并创建了一个person
对象。- 调用
pickle.dumps()
函数将person
对象序列化为二进制数据并打印输出。 - 然后,使用
pickle.loads()
函数将二进制数据反序列化为对象,并调用对象的方法。
- 调用
总结:
- json序列化是将数据结构转换为字符串的过程,可以序列化数字、字符串、布尔值、列表、字典和时间对象;
- pickle序列化是将对象序列化为二进制数据的过程,可以序列化Python中的任意对象,包括自定义的类对象,并保留对象的属性和方法。