一、Redis介绍
1.非关系型数据库,纯内存操作,key-value
存储,性能很高,可持久化(内存---->保存到硬盘上)
2.缓存,计数器,验证码,geo地理位置信息,发布订阅,独立用户统计
3.五大数据类型:字符串,列表,hash,集合,有序集合
4.6.x之前版本是单线程、单进程
qps(每秒查询量):10w并发,实际6w并发
为什么这么快?
- 纯内存操作
- 使用了
io多路复用的模型
,epoll(select,poll,epoll) - 避免了线程间切换的浪费
5.安装
官方提供了源码(C语言),编译安装
编译型语言,如果要执行,需要在不同平台编译成不同平台的可执行文件
linux版本安装:
编译(gcc),编译成可执行文件,就可以运行
1、官网下载:安装包或是绿色面安装
2、安装并配置环境变量
官网,下载完是源代码:C语言源码
最稳定:6.x,最新7.x
中文网,最新只到5.x
wget http://download.redis.io/releases/redis-3.0.6.tar.gz
tar xzf redis-3.0.6.tar.gz
cd redis-3.0.6
make
# 启动服务端
src/redis-server
# 启动客户端
src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
windows版本安装:
不支持windows,但有人在原来的基础上编写了windows版本
下载3.x版本或5.x版本 ,下载完一路下一步即可
windows上自动做成服务,启动关闭服务,监听的端口是:6379
连接方式:
- 使用命令启动服务端
redis-server 配置文件
- 客户端连接:命令窗口
redis-cli
- python代码连接
- 图形化客户端,有很多
redis-desktop-manager
:安装一路下一步
可以连远端
6.QT(平台):使用C/C++语言在平台上开发---->图形化界面软件(GUI)
pyqt:在qt平台上使用python代码写图形化界面
Tkinter
7.django 2.0.7以后,如果还使用pymysql连mysql,源码不兼容,改源码
mysqlclient:什么都不用配,直接用,不需要改源码
8.软件运行,会监听某个端口,客户端通过ip+端口访问
2的16次方 = 一共65535个
1-1024 系统使用
9.redis的key和string类型value限制均为512MB
10.redis VS mysql
redis: 内存数据库(读写快)、非关系型(操作数据方便、数据固定)
mysql: 硬盘数据库(数据持久化)、关系型(操作数据间关系、可以不同组合)
大量访问的临时数据,才有redis数据库更优
11.redis VS memcache
redis: 操作字符串、列表、字典、无序集合、有序集合 | 支持数据持久化(数据丢失可以找回(默认持久化,主动持久化save)、可以将数据同步给mysql) | 高并发支持
memcache: 操作字符串 | 不支持数据持久化 | 并发量小
12.启动服务
前提:前往一个方便管理redis持久化文件的逻辑再启动服务:dump.rdb
1)前台启动服务
>: redis-server
2)后台启动服务
>: redis-server --service-start
注)Linux系统后台启动(或是修改配置文件,建议采用方式)
>: redis-server &
3)配置文件启动前台服务
>: redis-server 配置文件的绝对路径
4)配置文件启动后台服务
注)windows系统默认按Redis安装包下的redis.windows-service.conf配置文件启动
>: redis-server --service-start
注)Linux系统可以完全自定义配置文件(redis.conf)后台启动
>: redis-server 配置文件的绝对路径 &
"""
"""
windows系统
1)前台启动
i)打开终端切换到redis安装目录
>: cd C:\Apps\Redis
ii)启动服务
>: redis-server redis.windows.conf
2)后台启动
i)打开终端切换到redis安装目录
>: cd C:\Apps\Redis
ii)启动服务(后面的配置文件可以省略)
>: redis-server --service-start redis.windows-service.conf
13.密码管理
1)提倡在配置文件中配置,采用配置文件启动
requirepass 密码
2)当服务启动后,并且连入数据库(redis数据库不能轻易重启),可以再改当前服务的密码(服务重启,密码重置)
config set requirepass 新密码
3)已连入数据库,可以查看当前数据库服务密码
config get requirepass
14.连接数据库
1)默认连接:-h默认127.0.0.1,-p默认6379,-n默认0,-a默认无
>: redis-cli
2)完整连接:
>: redis-cli -h ip地址 -p 端口号 -n 数据库编号 -a 密码
3)先连接,后输入密码
>: redis-cli -h ip地址 -p 端口号 -n 数据库编号
>: auth 密码
15.切换数据库
1)在连入数据库后执行
>: select 数据库编号
16.关闭服务
1)先连接数据库,再关闭redis服务
>: redis-cli -h ip地址 -p 端口号 -n 数据库编号 -a 密码
>: shutdown
2)直接连接数据库并关闭redis服务
>: redis-cli -h ip地址 -p 端口号 -n 数据库编号 -a 密码 shutdown
17.清空redis数据库
1)连接数据库执行
>: flushall
18.数据持久化
1)配置文件默认配置
save 900 1 # 超过900秒有1个键值对操作,会自动调用save完成数据持久化
save 300 10 # 超过300秒有10个键值对操作,会自动调用save完成数据持久化
save 60 10000 # 超过60秒有10000个键值对操作,会自动调用save完成数据持久化
2)安全机制
# 当redis服务不可控宕机,会默认调用一下save完成数据持久化(如果数据量过大,也可能存在部分数据丢失)
3)主动持久化
>: save # 连入数据库时,主动调用save完成数据持久化
>
注:数据持久化默认保存文件 dump.rdb,保存路径默认为启动redis服务的当前路径
19.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 密码
20.Redis数据类型
"""
数据操作:字符串、列表、哈希(字典)、无序集合、有序(排序)集合
有序集合:游戏排行榜
字符串:
set key value
get key
mset k1 v1 k2 v2 ...
mget k1 k2 ...
setex key exp value
incrby key increment
列表:
rpush key value1 value2 ...
lpush key value1 value2 ...
lrange key bindex eindex
lindex key index
lpop key | rpop key
linsert key before|after old_value new_value
哈希:
hset key field value
hget key field
hmset key field1 value1 field2 value2 ...
hmget key field1 field2
hkeys key
hvals key
hdel key field
集合:
sadd key member1 member2 ...
sdiff key1 key2 ...
sdiffstore newkey key1 key2 ...
sinter key1 key2 ...
sunion key1 key2 ...
smembers key
spop key
有序集合:
zadd key grade1 member1 grade2 member2 ...
zincrby key grade member
zrange key start end
zrevrange key start end
"""
二、Python操作Redis之普通连接和连接池
安装redis模块:
pip install redis
1.redis之普通连接
import redis
# 拿到一个连接,通过连接操作数据
conn = redis.Redis()
conn = redis.Redis(host='localhost', port=6379)
conn.set('name','lqz')
conn.close()
2.redis连接池
redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
pool.py
import redis
POOL = redis.ConnectionPool(max_connections=10)
redis.py
import redis
# 创建池,池的大小是10,最多放10个连接
# 池需要做成单例,整个项目全局只有一个
# Python 的模块就是天然的单例模式
from pool import POOL
# 从池中获取连接
conn=redis.Redis(connection_pool=POOL)
conn.set('age',14)
conn.close()
redis连接池原理:
创建一个池,池中比如10个连接,池先和redis连接,现在过来1个连接,直接去池里拿,如果过来11个连接,多出来的1个连接必须等待其中1个释放,才可以拿,这样避免了频繁操作redis,导致redis资源暴涨甚至崩溃。
三、Python操作Redis之字符串操作
# import redis
# conn = redis.Redis()
## 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# ex,过期时间(秒)px,过期时间(毫秒)
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
# conn.set('hobby', '篮球', ex=8)
# conn.set('name', 'lqz')
# conn.set('name', 'egon', nx=True)
# conn.set('name', 'egon')
# conn.set('name', 'dlrb', xx=True)
# conn.set('name1', 'dlrb', xx=True)
## 2 setnx(name, value)
# conn.setnx('name','ddd')
# conn.setnx('name1','ddd')
## 3 setex(name, time, value)
# conn.setex('age',18,5)
##4 psetex(name, time_ms, value) 以毫秒过期时间
# conn.psetex('xx',3000,'ss')
## 5 mset(*args, **kwargs) # 批量设置和一次次设置有什么区别?一次网络请求
# conn.mset({'name2':'egon','name3':'lyf'})
## 6 get(name) # byte格式
# print(conn.get('name2'))
## 7 mget({'k1': 'v1', 'k2': 'v2'})
# res=conn.mget('name1','name2')
# res=conn.mget(['name1','name2'])
# 8 getset(name, value)
# res=conn.getset('name1','ppp')
# print(res)
# 9 getrange(key, start, end) # 前闭后闭区间,以unicode编码存储,取字节
# res=conn.getrange('name1',0,5)
# print(res.decode('utf-8'))
# 10 setrange(name, offset, value)
# conn.setrange('name1',10,'pppppp')
# 10111111 ---> 112--->p
# 11 setbit(name, offset, value)
# conn.setbit('name1',2,0)
# getbit(name, offset)
# print(conn.getbit('name1',2))
# 12 bitcount(key, start=None, end=None)
# 13 strlen(name)
# print(conn.strlen('name1'))
# 14 incr(self, name, amount=1) ****** 页面访问量
# conn.incr('name1') # 自增1
# 15 decr(self, name, amount=1) #自减
# 16 incrbyfloat(self, name, amount=1.0)
# conn.incrbyfloat('name1',1.2)
# print(res)
# conn.close()
# 记住的
'''
get
set
mget
mset
strlen
incr
'''
四、Python操作Redis之hash操作
# import redis
# conn = redis.Redis()
# 1 hset(name, key, value)
# conn.hset('hash1','name','lqz')
# conn.hset('hash1', 'age', '19')
# 2 hget(name,key)
# print(conn.hget('hash1','age'))
# 3 hmset(name, mapping) # 弃用了,但是还可以用 批量设置
# conn.hmset('user_1_info', {'name': 'lyf', 'age': 33,'hobby':'篮球'})
# conn.hset('user_2_info', mapping={'name': 'lyf', 'age': 33,'hobby':'篮球'})
# 4 hmget(name, keys, *args) 批量获取
# res=conn.hmget('user_2_info','age','hobby')
# res = conn.hmget('user_2_info', ['age', 'hobby'])
# print(res)
# 两种传值方式
# from redis.client import list_or_args
# conn.hmget('user_2_info','age','hobby')
# res = list_or_args('age', ['hobby', ])
#res = conn.hmget('user_2_info', ['age', 'hobby'])
# res = list_or_args(['age', 'hobby'],[])
# print(res)
# 5 hgetall(name) 获取所有 ,慎用,生产环境中,尽量不要用
# res=conn.hgetall('user_2_info')
# print(res)
# 6 hlen(name)
# res=conn.hlen('user_2_info')
# print(res)
# 7 hkeys(name)
# res=conn.hkeys('user_2_info')
# print(res)
# 8 hvals(name)
# res=conn.hvals('user_2_info')
# print(res)
# 9 hexists(name, key)
# res=conn.hexists('user_2_info','name1')
# print(res)
# 10 hdel(name,*keys)
# res=conn.hdel('user_2_info','name')
# print(res)
# 11 hincrby(name, key, amount=1) age自增1
# conn.hincrby('user_2_info','age')
# 12 hincrbyfloat(name, key, amount=1.0)
# 13 hscan(name, cursor=0, match=None, count=None) # 不要使用hgetall
# 由于无序,这个方法咱们一般不同,给hscan_iter,从hash中取出一部分值,会以count为基准,但不完全是count
# res=conn.hscan('test_hash',count=11)
# print(len(res[1]))
# 14 hscan_iter(name, match=None, count=None)
# hash 类型本身就无序
# for i in range(1000):
# conn.hset('test_hash','%s_key'%i,'鸡蛋_%s'%i)
# res=conn.hgetall('test_hash')
# 取出所有数据,跟hgetall比,更节省内存 √√√推荐使用
# for key in conn.hscan_iter('test_hash',count=100): # 生成器
# print(key)
# conn.close()
# 记住的
'''
hset
hget
hmset
hmget
hlen
hexists
hincrby
hscan_iter:分批获取数据
'''
五、Python操作Redis之列表操作
# import redis
# conn = redis.Redis()
# 1 lpush(name,values) # 从列表的左侧插入值
# conn.lpush('names','lqz','egon')
# conn.lpush('names','lyf','dlrb')
# conn.lpush('names','pyy')
# conn.rpush('names','mrzh') # 从右侧往里推数据
# 2 lpushx(name,value) # 只能key存在,才能放进去
# conn.lpushx('names','999')
# conn.lpushx('names1','999') #不存在的放不进去
# 3 llen(name)
# print(conn.llen('names'))
# 4 linsert(name, where, refvalue, value))
# where:before或者after,大小写都可以
# conn.linsert('names','after','egon','fengjie')
# conn.linsert('names','BEFORE','egon','rh')
# 5 r.lset(name, index, value) #位置从零开始
# conn.lset('names',5,'l_egon')
# r.lrem(name, num,value ) # 删除元素
# conn.lrem('names',0,'lqz') #把内部所有lqz都移除
# conn.lrem('names',1,'lqz') #从左往右移除一个符合
# conn.lrem('names', -1, 'lqz') # 从右往左移除一个符合
# 6 lpop(name)
# conn.lpop('names') # 从左侧弹出一个
# conn.rpop('names') # 从右侧弹出一个
# 7 lindex(name, index) # 拿某个位置的值,从0开始
# res=conn.lindex('names',1)
# print(res)
# 8 lrange(name, start, end)
# res=conn.lrange('names',1,conn.llen('names')) # 获取起始到结束位置的值,前闭后闭
# print(res)
# 9 ltrim(name, start, end) # 修剪
# res=conn.ltrim('names',2,4) # 只保留2--4之间的,其他全删除
# 10 rpoplpush(src, dst) # 两个列表
# conn.lpush('names1','xx','yy')
# conn.rpoplpush('names','names1')
# 11 blpop(keys, timeout) # 阻塞式弹出,有值可以弹,没有值就夯住,直到有值,
# 基于它可以做消息队列,如果是简单的消息队列,就可以使用redis的list类型
# res=conn.blpop('names',4) # 4为超时时间
# print(res)
# IPC:进程间通信
# 12 brpoplpush(src, dst, timeout=0)
# 一次性把list中值全取出来
# res = conn.lrange('names', 0, conn.llen('names'))
# 自定义增量迭代取值(哪个地方用过生成器)
# 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])
# 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
#
#
# for item in scan_list('test',2):
# print(item)
# conn.close()
# 记住的
'''
lpush
llen
lrem
lindex
lpop
lrange
'''
六、Python操作Redis之set操作
Set操作,Set集合就是不允许重复的列表
sadd(name,values)
# name对应的集合中添加元素
scard(name)
获取name对应的集合中元素个数
sdiff(keys, *args)
在第一个name对应的集合中且不在其他name对应的集合的元素集合
sdiffstore(dest, keys, *args)
# 获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中
sinter(keys, *args)
# 获取多一个name对应集合的并集
sinterstore(dest, keys, *args)
# 获取多一个name对应集合的并集,再讲其加入到dest对应的集合中
sismember(name, value)
# 检查value是否是name对应的集合的成员
smembers(name)
# 获取name对应的集合的所有成员
smove(src, dst, value)
# 将某个成员从一个集合中移动到另外一个集合
spop(name)
# 从集合的右侧(尾部)移除一个成员,并将其返回
srandmember(name, numbers)
# 从name对应的集合中随机获取 numbers 个元素
srem(name, values)
# 在name对应的集合中删除某些值
srem(name, values)
# 在name对应的集合中删除某些值
sunion(keys, *args)
# 获取多一个name对应的集合的并集
sunionstore(dest,keys, *args)
# 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None)
# 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name, *args, **kwargs)
# 在name对应的有序集合中添加元素
# 如:
# zadd('zz', 'n1', 1, 'n2', 2)
# 或
# zadd('zz', n1=11, n2=22)
zcard(name)
# 获取name对应的有序集合元素的数量
zcount(name, min, max)
# 获取name对应的有序集合中分数 在 [min,max] 之间的个数
zincrby(name, value, amount)
# 自增name对应的有序集合的 name 对应的分数
r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)
复制代码
# 按照索引范围获取name对应的有序集合的元素
# 参数:
# name,redis的name
# start,有序集合索引起始位置(非分数)
# end,有序集合索引结束位置(非分数)
# desc,排序规则,默认按照分数从小到大排序
# withscores,是否获取元素的分数,默认只获取元素的值
# score_cast_func,对分数进行数据转换的函数
# 更多:
# 从大到小排序
# zrevrange(name, start, end, withscores=False, score_cast_func=float)
# 按照分数范围获取name对应的有序集合的元素
# zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
# 从大到小排序
# zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)
复制代码
zrank(name, value)
# 获取某个值在 name对应的有序集合中的排行(从 0 开始)
# 更多:
# zrevrank(name, value),从大到小排序
zrangebylex(name, min, max, start=None, num=None)
复制代码
# 当有序集合的所有成员都具有相同的分值时,有序集合的元素会根据成员的 值 (lexicographical ordering)来进行排序,而这个命令则可以返回给定的有序集合键 key 中, 元素的值介于 min 和 max 之间的成员
# 对集合中的每个成员进行逐个字节的对比(byte-by-byte compare), 并按照从低到高的顺序, 返回排序后的集合成员。 如果两个字符串有一部分内容是相同的话, 那么命令会认为较长的字符串比较短的字符串要大
# 参数:
# name,redis的name
# min,左区间(值)。 + 表示正无限; - 表示负无限; ( 表示开区间; [ 则表示闭区间
# min,右区间(值)
# start,对结果进行分片处理,索引位置
# num,对结果进行分片处理,索引后面的num个元素
# 如:
# ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga
# r.zrangebylex('myzset', "-", "[ca") 结果为:['aa', 'ba', 'ca']
# 更多:
# 从大到小排序
# zrevrangebylex(name, max, min, start=None, num=None)
复制代码
zrem(name, values)
# 删除name对应的有序集合中值是values的成员
# 如:zrem('zz', ['s1', 's2'])
zremrangebyrank(name, min, max)
# 根据排行范围删除
zremrangebyscore(name, min, max)
# 根据分数范围删除
zremrangebylex(name, min, max)
# 根据值返回删除
zscore(name, value)
# 获取name对应有序集合中 value 对应的分数
zinterstore(dest, keys, aggregate=None)
# 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
# aggregate的值为: SUM MIN MAX
zunionstore(dest, keys, aggregate=None)
# 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
# aggregate的值为: SUM MIN MAX
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float)
# 同字符串相似,相较于字符串新增score_cast_func,用来对分数进行操作
七、Python操作Redis之其他操作(通用操作)
# import redis
# conn=redis.Redis()
# 1 delete(*names)
# # 根据删除redis中的任意数据类型
# conn.delete('test_hash')
# 2 exists(name)
# # 检测redis的name是否存在
# res=conn.exists('names')
# print(res) # 1 表示存在 0表示不在
# 3 keys(pattern='*') 获取所有的key值,可以过滤
# res=conn.keys(pattern='n*')
# res=conn.keys(pattern='nam?')
# print(res)
# 4 expire(name ,time)
# # 为某个redis的某个name设置超时时间
# conn.expire('names1',9)
#5 rename(src, dst)
# # 对redis的name重命名为
# conn.rename('test','test1')
#6 move(name, db))
# # 将redis的某个值移动到指定的db下
# conn.move('hash1',5)
# 7 randomkey()
# 随机获取一个redis的name(不删除)
# res=conn.randomkey()
# print(res)
# 8 type(name) 查看key的类型 5 大数据类型
# res=conn.type('user_1_info')
# res=conn.type('name1')
# print(res)
# conn.close()
八、管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
# redis是非关系型数据库,不支持事务
# 管道,我们可以通过管道来模拟事务----》要么都成功,要么都失败:一个事务
# import redis
# conn = redis.Redis()
# 创建一个管道
# pipe = conn.pipeline(transaction=True)
# 开启事务
# pipe.multi()
# 向管道中放入命令
# pipe.decrby('egon_money',50)
# raise Exception('ssss')
# pipe.incrby('lqz_money',50)
#让管道中的命令执行
# pipe.execute()
九、Django中使用Redis
1.通用方案
创建pool.py文件:
import redis
POOL = redis.ConnectionPool(max_connections=1000)
在使用的位置添加:
from .pool import POOL
import redis
def test(request):
conn = redis.Redis(connection_pool=POOL)
res=conn.get('name')
print(res)
return HttpResponse('ok')
2.django方案,第三方模块
下载模块:
pip install django-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}
}
}
}
使用的位置:
from django_redis import get_redis_connection
def test(request):
conn = get_redis_connection() #从连接池中拿一个连接
res=conn.get('name')
print(res)
return HttpResponse('ok')
一旦使用了它,后续的django缓存,都缓存到redis中
cache.set('name','xxx')
django的缓存很高级,可以缓存python中所有的数据类型,包括对象---->把对象通过pickle序列化成二进制,存到redis的字符串中。