快速上手非关系型数据库Redis

一、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的字符串中。

猜你喜欢

转载自blog.csdn.net/BLee_0123/article/details/130441889