1. redis 介绍

介绍

  • 是一个 cs 架构的开源软件(用c语言写的,初级版本代码只有1w多行。公司使用 5.x,4.x多)
  • 非关系型(没有外键关联关系)数据库
  • 数据都放在内存中(读写速度超级快,每秒的 qps 10w)
  • 以 key-value 形式存储
  • 有5大数据类型(字符串,list,hash,集合,有序集合)

好处

  • 速度快,因为数据存在内存中,类似于python的字典的优势就是查找和操作的速度快
  • 支持丰富数据类型,支持 string,list,set,sorted set,hash
  • 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
  • 丰富的特性:可用于缓存(最广泛:缓存数据库),消息,按key设置过期时间,过期后将会自动删除

应用场景

  • 会话缓存(Session Cache)。原来 session 放在了 djagno-session 表中,速度慢,如果放到 redis 中速度超级快

  • 缓存:全页缓存,接口缓存:

  • 队列:程序的解耦,不是专业的,真正专业的消息队列: kafka、rabbitmq…

  • 排行榜/计数器:有序集合, 字符串类型做计数器累加(由于6.x之前redis是单线程单进程架构,不存在并发安全问题)。网站访问量,转发量,评论数(文章转发,商品销量,单线程模型,不会出现并发问题)

  • 社交网络:很多特效跟社交网络匹配,粉丝数,关注数

  • 实时系统:垃圾邮件处理系统,布隆过滤器

速度快的原因

  • 纯内存操作
  • 使用 io 多路复用的网络模型(select,poll,epoll模型)的 epoll 模型
  • 单线程,单进程架构,没有进程线程间切换的消耗

Redis 的 key 可以存储的最大值为 512M

2. redis 安装

redis 作者对 win 的支持不好(win 不支持 epoll 的网络模型,只支持 select )
于是微软把 redis 编译成可执行文件并且可以运行在win上,其主要有俩个分支,如下所示

  1. 要安装Redis,首先要获取安装包。Windows的Redis安装包需要到以下GitHub链接找到。打开网站后,找到 Release,点击前往下载页面。

在这里插入图片描述

  1. 在下载网页中,找到最后发行的版本点击下载。这里说明一下,第一个是msi微软格式的安装包,第二个是压缩包。点击按照以下顺序安装即可
    在这里插入图片描述
    在这里插入图片描述
    选择“添加Redis目录到环境变量PATH中”,这样方便系统自动识别Redis执行文件在哪里
    在这里插入图片描述
    端口号可保持默认的6379,并选择防火墙例外,从而保证外部可以正常访问Redis服务。
    在这里插入图片描述
    设定最大值为100M。作为实验和学习,100M足够了。也可以不勾选
    在这里插入图片描述

3. redis 配置命令

  1. 找到服务设置进行配置,可以设置为手动启动。
    在这里插入图片描述
  2. 测试一下Redis是否正常提供服务。进入Redis的目录。输入redis-cli 并回车。( redis-cli 是客户端程序)如图正常提示进入,并显示正确端口号,则表示服务已经启动。如果设置了环境变量可以直接敲不需要进入目录。
    在这里插入图片描述
  3. 启动 redis 服务
    redis-server.exe redis.windows-service.conf
  4. 客户端连接(cmd窗口)
    redis-cli -h 127.0.0.1 -p 6379
    redis-cli
  5. 关闭服务
先连接数据库,再关闭 redis 服务
redis-cli -h ip地址 -p 端口号 -n 数据库编号 -a 密码
shutdown
直接连接数据库并关闭 redis 服务
redis-cli -h ip地址 -p 端口号 -n 数据库编号 -a 密码 shutdown
  1. 清空 redis 数据库
连接数据库执行
flushall
  1. redis 相关配置
1)绑定的ip地址,多个ip用空格隔开
bind 127.0.0.1

2)端口,默认6379,一般不做修改
port 6379

3)是否以守护进程启动,默认为no,一般改为yes代表后台启动(windows系统不支持)
daemonize no

4)定义日志级别,默认值为notice,有如下4种取值:
	debug(记录大量日志信息,适用于开发、测试阶段)
	verbose(较多日志信息)
	notice(适量日志信息,使用于生产环境)
	warning(仅有部分重要、关键信息才会被记录)
loglevel notice

5)配置日志文件保持地址,默认打印在命令行终端的窗口上
	如果填写 "./redis.log" 就会在启动redis服务的终端所在目录下,用redis.log记录redis日志
logfile ""

eg)终端首先切断到log文件夹所在目录(一般就可以采用redis的安装目录,也可以自定义),再启动reids服务
logfile "./log/redis.log"

6)数据库个数,默认是16个,没特殊情况,不建议修改
databases 16

7)数据持久化
save 900 1  # 超过900秒有1个键值对操作,会自动调用save完成数据持久化
save 300 10  # 超过300秒有10个键值对操作,会自动调用save完成数据持久化
save 60 10000  # 超过60秒有10000个键值对操作,会自动调用save完成数据持久化

8)数据库持久化到硬盘失败,redis会立即停止接收用户数据,让用户知道redis持久化异常,避免数据灾难发生(重启redis即可),默认为yes,不能做修改
stop-writes-on-bgsave-error yes

9)消耗cpu来压缩数据进行持久化,数据量小,但会消耗cpu性能,根据实际情况可以做调整
rdbcompression yes

10)增持cpu 10%性能销毁来完成持久化数据的校验,可以取消掉
rdbchecksum yes

11)持久化存储的文件名称
dbfilename dump.rdb

12)持久化存储文件的路径,默认是启动服务的终端所在目录
dir ./

13)reids数据库密码
requirepass 密码

4. 图形化客户端

这里使用的是 redis-desktop-manage 其源码是个开源软件,用 qt 写的,图形化界面,类似于 navicate。链接:https://github.com/uglide/RedisDesktopManager 正常安装即可

  1. 安装后进行链接
    在这里插入图片描述
  2. 链接后的界面如下所示,redis 是 key-value 存储,但是它默认有16个库
    在这里插入图片描述

5. python 使用 redis

需要下载依赖:

pip3 install redis

普通链接

import redis
# decode_responses=True得到的结果会自动解码(不是二进制数据)
# db 指定某一个库
r = redis.Redis(host='127.0.0.1', port=6379, db=1, password=None, decode_responses=True)
# 或者简写
r = Redis(host="localhost",port=6379,)

r.close()

连接池方式

  • pool.py
import redis

POOL = redis.ConnectionPool(max_connections=5)
  • 链接
import redis
from utlis import pool

# 添加连接池
r = redis.Redis(host='127.0.0.1', port=6379, connection_pool=pool.POOL)

r.set('name', 'xwx')
r.close()

6. redis 数据类型

  • 5 大数据类型
    字符串,链表,hash,集合,有序集合
  • redis 支持5大数据类型,但只支持到一层,第二层必须是字符串,例如 hash 中的值类型必须为字符串,但可以使用 JSON 格式字符串

在这里插入图片描述

redis={
        k1:'123',      字符串
        k2:[1,2,3,4],   列表/数组
        k3:{1,2,3,4}     集合
        k4:{name:xwx, age:12}  字典/哈希表
        k5:{('lqz', 18),('egon', 33)}  有序集合
}

在这里插入图片描述

7. 数据类型之字符串

String操作,redis中的String在在内存中按照一个name对应一个value来存储

在这里插入图片描述

主要方法 作用
set(name, value, ex=None, px=None, nx=False, xx=False) 不存在则创建,存在则修改
setnx(name, value) 不存在执行操作,存在则不会修改
psetex(name, time_ms, value) 设置值和过期时间
mset(*args, **kwargs) 批量设置值
get(name) 获取值
mget(keys, *args) 批量获取
getset(name, value) 设置新值并获取原来的值
getrange(key, start, end) 获取子序列
setrange(name, offset, value) 修改指定索引字符串内容
setbit(name, offset, value) 对应值的二进制表示的位进行操作
getbit(name, offset) 获取对应的值的二进制表示的值
bitcount(key, start=None, end=None) 对应的值的二进制表示中 1 的个数
strlen(name) 返回对应值的字节长度
incr(self, name, amount=1) 自增 name对应的值
incrbyfloat(self, name, amount=1.0) 自增 name对应的值
decr(self, name, amount=1) 自减 name对应的值
append(key, value) 对应的值后面追加内容

set(name, value, ex=None, px=None, nx=False, xx=False)

参数 作用 示例
ex 过期时间(秒)最适合存验证码 r.set(‘name’, ‘xwx’, ex=2)
px 过期时间(毫秒) r.set(‘name’,‘xwx’,px=2000)
nx 如果设置为 True,则只有name 不存在 时,当前操作才执行。值存在,执行没效果 r.set(‘name’,‘xwx’,nx=True)
xx 如果设置为 True,则只有name 存在 时,当前操作才执行,值存在才能修改,值不存在,不会设置新值 r.set(‘name’,‘xwx’,xx=True)

setnx(name, value)

等同于 set 方法 nx 为 True 的状态,当 name 不存在时,当前操作才执行。值存在,执行没效果

psetex(name, time_ms, value)

设置过期时间,并以毫秒计算					示例: r.psetex('age', 3000, '12')

mset(*args, **kwargs)

批量设置,如下示例

r.mset({'name': 'xwx', 'age': 18})

一次 mset 和多次 set 的区别

  • 执行多条 SET 命令需要客户端和服务器之间进行多次网络通信,并因此耗费大量的时间;
  • 通过使用一条 MSET 命令去代替多条 SET 命令,可以将原本所需的多次网络通信降低为只需一次网络通信,从而有效地减少程序执行多个设置操作时所需的时间。

get(name)

获取值,如下所示

print(r.get('age'))								# b'18' 	获取的值是二进制类型
print(str(r.get('name'), encoding='utf8'))		# xwx		可以进行转码

mget(keys, *args)

批量获取值,如下所示

print(r.mget(['name', 'age']))					
print(r.mget('name', 'age'))

getset(name, value)

获取并设置值,返回原本的值或者None,并重新设置该值

print(r.getset('xwx', 222))					

getrange(key, start, end)

根据起始和终止,获取字符串,以字节计数( redis 中存储是用 utf-8 存储的)

s = r.getrange('name', 1, 2)
print(str(s, encoding='utf8'))

setrange(name, offset, value)

在指定位置可以理解为索引后设置值,原本有值会覆盖

r.setrange('name', 4, 'xxxx')

setbit(name, offset, value)

修改比特位,只能为 0 或 1,例如原本为 00000000 可以修改为 00000001

r.setbit('name', 2, 0)

getbit(name, offset)

获取指定位置的比特位,0 或 1

print(r.getbit('name', 2))

bitcount(key, start=None, end=None)

获取name对应的值的二进制表示中 1 的个数

print(r.bitcount('name', 0, 5))

strlen(name)

返回name对应值的字节长度,一个汉字为3字节

print(r.strlen('name'))

incrby(self, name, amount=1)

计数器,自增 name 对应的值(该值必须为数字),若不存在则创建,创建的默认值为 amount ,可以指定,默认为 1 。该方法自增必须为整数

print(r.incrby('age', amount=2))			# 自增对应的值并将自增后的数值返回

incrbyfloat(self, name, amount=1.0)

计数器,和 incrby 类似,但是该方法自增的是小数

print(r.incrbyfloat('age', amount=1.5))		# 自增对应的值并将自增后的数值返回

decrby(self, name, amount=1)

自减 name对应的值,当 name 不存在时,则创建 name=amount,否则,则自减。
注意:该值减去的和被减去的值必须为整数

print(r.decrby('age', amount=3))			# 自减对应的值并将自增后的数值返回

append(key, value)

在name对应的值后面追加内容

print(r.append('name', 'x'))				# 追加内容并返回值的长度

8. 数据类型之 hash

Hash操作,redis中Hash在内存中的存储格式如下图

在这里插入图片描述

主要方法:

1  hset(name, key, value)
2  hmset(name, mapping)
3  hget(name,key)
4  hmget(name, keys, *args)
5  hgetall(name)
6  hlen(name)
7  hkeys(name)
8  hvals(name)
9  hexists(name, key)
10 hdel(name,*keys)
11 hincrby(name, key, amount=1)
12 hincrbyfloat(name, key, amount=1.0)
13 hscan(name, cursor=0, match=None, count=None)
14 hscan_iter(name, match=None, count=None)

hset(name, key, value)

name对应的hash中设置一个键值对(不存在,则创建;否则,修改),有以下俩种方式

# 方式一
r.hset('userinfo', 'name', 'xwx')
r.hset('userinfo', 'age', '12')

# 方式二,指定 mapping
r.hset('userinfo1', mapping={'name': 'xwx', 'age': 12})

在这里插入图片描述


hmset(name, mapping)

批量设置,等同于 hset 方法指定 mapping ,但是现在不推荐

在这里插入图片描述


hget(name,key)

获取 name 对应的 hash 中指定的值

print(r.hget('userinfo2', 'age'))				# b'13'  返回的是二进制

hmget(name, keys, *args)

批量获取指定的值

print(r.hmget('userinfo2', ['name', 'age']))	# 也是二进制

hgetall(name)

获取所有的值,该方法慎用,如果hash类型数据量特别大,很可能撑爆内存

print(r.hgetall('userinfo2'))					# {b'name': b'xwx', b'age': b'13'}

hlen(name)

获取name对应的hash中键值对的个数

print(r.hlen('userinfo2'))

hkeys(name)

获取name对应的hash中所有的key的值

print(r.hkeys('userinfo2'))

hvals(name)

获取name对应的hash中所有的value的值

print(r.hvals('userinfo2'))

hexists(name, key)

检查 name 对应的 hash 是否存在当前传入的 key

print(r.hexists('userinfo2', 'abc'))			# False

hdel(name,*keys)

将 name 对应的 hash 中指定 key 的键值对删除

print(r.hdel('userinfo2', 'age'))				# 1    返回 1

hincrby(name, key, amount=1)

自增 name 对应的 hash 中的指定 key 的值,不存在则创建 key = amount

print(r.hincrby('userinfo2', 'age', amount=3))	# 3  返回自增后的值

hincrbyfloat(name, key, amount=1.0)
同上,不过自增的类型是浮点数


hscan(name, cursor=0, match=None, count=None)

增量式迭代获取,对于数据大的数据非常有用,hscan可以实现分片的获取数据,并非一次性将数据全部获取完,从而放置内存被撑爆

参数 说明
name redis 的 name
cursor 游标(基于游标分批取获取数据)
match 匹配指定 key,默认 None 表示所有的key
count 每次分片最少获取个数,默认 None 表示采用 Redis 的默认分片个数
print(r.hscan('userinfo2', cursor=0, count=55))

# (0, {b'name': b'xwx', b'age': b'3'})

hscan_iter(name, match=None, count=None)

利用 yield 封装 hscan 创建生成器,实现分批去 redis 中获取数据

参数 说明
match 匹配指定 key,默认 None 表示所有的 key
count 每次分片最少获取个数,默认 None 表示采用 Redis 的默认分片个数
for i in r.hscan_iter('userinfo2'):
    print(i)

# (b'name_0', b'value_0')
# (b'name_1', b'value_1')
# (b'name_2', b'value_2')
# (b'name_3', b'value_3')
# (b'name_4', b'value_4')
# (b'name_5', b'value_5')
# (b'name_6', b'value_6')
# (b'name_7', b'value_7')
# (b'name_8', b'value_8')
# (b'name_9', b'value_9')

9. 数据类型之 list

List操作,redis中的List在在内存中按照一个name对应一个List来存储。如图:

在这里插入图片描述

主要方法:

1  lpush(name,values)
2  lpushx(name,value)
3  rpushx(name, value) 表示从右向左操作
4  llen(name)
5  linsert(name, where, refvalue, value))
6  lset(name, index, value)
7  lrem(name, value, num)
8  lpop(name)
9  lindex(name, index)
10 lrange(name, start, end)
11 ltrim(name, start, end)
12 rpoplpush(src, dst)
13 blpop(keys, timeout)
14 brpoplpush(src, dst, timeout=0)
15 自定义增量迭代

lpush(name,values)

在name对应的list中添加元素,每个新的元素都添加到列表的最左边。如果列表原本有值则追加值

r.lpush('user', 'user1', 'user2', 'user3')		# 添加的顺序是从左到右

在这里插入图片描述


lpushx(name,value)

在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边

r.lpushx('user', 'user2', 'user3')		# user 若不存在该操作无效

rpush(name, values)

也是添加元素,但从右向左

r.rpush('user', 'user1', 'user2', 'user3')	# 从右往左添加

在这里插入图片描述


rpushx(name, value)

等同于 lpushx,方向相反,从右向左,只有name已经存在时,值添加到列表的最右边

r.rpushx('user', 'user4')

llen(name)

获得name对应的列表中值的个数

print(r.llen('user'))					# 4

linsert(name, where, refvalue, value))

在name对应的列表的某一个值前或后插入一个新值

参数 说明
name redis 的 name
where BEFORE(前面) 或 AFTER (之后),小写也可以
refvalue 标杆值,即:在它前后插入数据(如果存在多个标杆值,以找到的第一个为准)
value 要插入的数据
r.linsert('user', 'before', 'user2', 'user5')
# 等同于
# r.linsert('user',where='before',refvalue='user2',value='user5')

在这里插入图片描述


lset(name, index, value)

对name对应的list中的某一个索引位置重新赋值

参数 说明
name redis的name
index list的索引位置
value 要设置的值
r.lset('user', 0, 'user6')						# 修改索引为0的值(第一个)

lrem(name, num,value)

在name对应的list中删除指定的值,删除的是相同的值

参数 说明
name redis的name
value 要删除的值
num num=0 删除列表中所有的指定值;
- num=2 从前到后,删除2个;
- num=-2 从后向前,删除2个
r.rpush('user', 'user', 'user', 'user', 'user', 'user', 'user')
r.lrem('user', 0, 'user')			# 删除所有的 user 值,若删完后列表没值该列表键会销毁

lpop(name)

在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是左边第一个元素


rpop(name)

在name对应的列表的右侧获取第一个元素并在列表中移除,返回值则是右边第一个元素


lindex(name, index)

在name对应的列表中根据索引获取列表元素

print(r.lindex('user', 2))						# 获取索引为 2 的元素

lrange(name, start, end)

在name对应的列表分片获取数据,起始结束位置均为闭区间

参数 说明
name redis的name
start 索引的起始位置
end 索引结束位置
print(r.lrange('user', 2, 5))			# 获取指定区间数值,左右均为闭区间
print(r.lrange('user', 0, r.llen('user')))		# 配合 llen 获取列表所有值

ltrim(name, start, end)

在name对应的列表中移除没有在start-end索引之间的值,左右均为闭区间


rpoplpush(src, dst)

一个列表取出最右边的元素,同时将其添加至另一个列表的最左边,添加以下俩个表

  • 取出前
    在这里插入图片描述
    在这里插入图片描述
r.rpoplpush('user', 'pwd')						# 结果如下所示
  • 取出后
    在这里插入图片描述
    在这里插入图片描述

blpop(keys, timeout)

将多个列表排列,按照从左到右去pop对应列表的元素。
消息队列本质就是基于它,redis可以作为消息队列

其是阻塞式弹出,如果列表中有值,就弹出,如果没有值就阻塞,直到有值再弹出

参数 说明
keys redis的name的集合
timeout 超时时间,当元素所有列表的元素获取完之后,阻塞等待列表内有数据的时间(秒), 0 表示永远阻塞
  • test.py
...
print(r.blpop(['user', ]))
...
  • test1.py
...
r.lpush('user', 'user1', 'user2')
...

在这里插入图片描述


brpoplpush(src, dst, timeout=0)

参数 说明
src 取出并要移除元素的列表对应的name
dst 要插入元素的列表对应的name
timeout 当src对应的列表中没有数据时,阻塞等待其有数据的超时时间(秒),0 表示永远阻塞

准备以下列表
在这里插入图片描述

...
r.brpoplpush('user', 'pwd')

print(r.lrange('user', 0, r.llen('user')))
print(r.lrange('pwd', 0, r.llen('pwd')))
...

移除后
在这里插入图片描述

自定义增量迭代

由于redis类库中没有提供对列表元素的增量迭代,如果想要循环name对应的列表的所有元素,那么就需要:

1、获取name对应的所有列表
2、循环列表

但是,如果列表非常大,那么就有可能在第一步时就将程序的内容撑爆,所有有必要自定义一个增量迭代的功能:

import redis
conn=redis.Redis(host='127.0.0.1',port=6379)
# conn.lpush('test',*[1,2,3,4,45,5,6,7,7,8,43,5,6,768,89,9,65,4,23,54,6757,8,68])
# conn.flushall()				# 清空所有库的表
def scan_list(name,count=2):
    index=0
    while True:
        data_list=conn.lrange(name,index,count+index-1)
        if not data_list:
            return
        index+=count
        for item in data_list:
            yield item
print(conn.lrange('test',0,100))
for item in scan_list('test',5):
    print('---')
    print(item)

10 数据类型之集合

11 数据类型之有序集合

12 其它操作

  • delete(*names)
根据删除redis中的任意数据类型
r.delete('age')
  • exists(name)
检测redis的name是否存在
res = r.exists('age')
print(res)
  • keys(pattern=‘*’)
根据模型获取redis的name


'KEYS * '       	匹配数据库中所有 key 。
'KEYS h?llo '		匹配 hello , hallo 和 hxllo 等。
'KEYS h*llo '		匹配 hllo 和 heeeeello 等。
'KEYS h[ae]llo '	匹配 hello 和 hallo ,但不匹配 hillo 
res = r.keys('*')
res = r.keys('user?')
print(res)
  • expire(name ,time)
为某个redis的某个name设置超时时间
r.expire('user',5)
  • rename(src, dst)
对redis的name重命名为
r.rename('test', 'test1')
  • move(name, db))
将redis的某个值移动到指定的db下
r.move('tes1',3)
  • randomkey()
随机获取一个redis的name(不删除)
print(r.randomkey())
  • type(name)
获取name对应值的类型
print(r.type('age'))
  • scan(cursor=0, match=None, count=None)
    scan_iter(match=None, count=None)
同字符串操作,用于增量迭代获取key
  • dbsize
查看库里的字段数量
res=conn.dbsize()
print(res)

13 redis 管道

redis-py 默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用 pipline 实现一次请求指定多个命令,并且默认情况下一次 pipline 是原子性操作。

只有在单机时可以使用,集群没有pipline

redis不支持事务但是可以通过管道的操作将多个命令放到一个管道中,然后一次性执行,要么都成功,要么
都失败
redis 支持事务码?支持,可以通过管道实现'弱事务'
  • 准备俩个用户,设置其初始金额都是 100
r.hset('user_a', 'money', '100')
r.hset('user_b', 'money', '100')
  • 将用户 a 的金额转给用户 b,为了防止用户 a 转完后出现异常导致用户 b 未收到可以使用管道的操作,在下面模拟异常的情况,出现异常不会执行
import redis
from utlis import pool

r = redis.Redis(host='127.0.0.1', port=6379, connection_pool=pool.POOL)

# 创建管道
pipe = r.pipeline(transaction=True)
# 接收多条命令
pipe.multi()

# 减去用户a金额
pipe.hincrby('user_a', 'money', amount=-50)

# 主动抛出异常
raise Exception('异常了')

# 增加用户b金额
pipe.hincrby('user_b', 'money', amount=50)

# 一次性执行管道中的操作,出现异常不会执行
pipe.execute()

r.close()

14 django 中集成 redis

在 django 中集成 redis 有俩种方案

1、通用方案,写一个pool包

  • utils文件夹下,建立redis_pool.py
import redis
POOL = redis.ConnectionPool(max_connections=5, decode_responses=True)
  • 视图函数中使用:
from utlis.pool import POOL
from redis import Redis

class Test(APIView):
    def get(self, request):
        r = Redis(connection_pool=POOL)
        print(r.get('name'))
        return Response('ok')
        

2、安装 django-redis 模块

安装语句:pip3 install django-redis

  • 在 setting 里添加配置
# redis配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # "PASSWORD": "123",
        }
    }
}
  • 视图函数中使用
from django_redis import get_redis_connection

class Test(APIView):
    def get(self, request):
    	# default 为配置中设置的名称,可以修改
        r = get_redis_connection('default')
        # 相同的方式使用,但是返回的是没有被转换的二进制数值
        print(r.get('name'))
        return Response('ok')

3、注意点

一旦配置文件配置 CACHES 后,django的缓存框架(默认是内存),存储的位置也是 redis ,所以以后根本不需要会redis的操作,只需要使用

from django.core.cache import cache

cache.set('name',对象)
cache.get()

其强大之处在于不需要关注设置的类型,直接设置就行
因为它把 python 的对象,通过 pickle 序列化后,以 string 形式存到 redis 中了

储存后示例

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐