1、 redis

一、 redis简介

1、什么是redis

1  redis 是一个非关系型数据库(区别于mysql关系型数据库,关联关系,外键,表),nosql数据库(not only sql:不仅仅是SQL),数据完全内存存储(速度非常快)

2  redis就是一个存数据的地方

3  redis是 key--value的存储形式---》value类型有5大数据类型---》字符串,列表,hash(字典),集合,有序集合

redis={
        k1:'123',      字符串
        k2:[1,2,3,4],   列表/数组
        k3:{1,2,3,4}     集合
        k4:{name:lqz,age:12}  字典/哈希表
        k5:{('lqz',18),('egon',33)}  有序集合
}
复制代码
1. 使用Redis有哪些好处?

(1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)

(2) 支持丰富数据类型,支持string,list,set,sorted set,hash

(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行

(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除


2. redis相比memcached有哪些优势?

(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型

(2) redis的速度比memcached快很多

(3) redis可以持久化其数据


3. redis常见性能问题和解决方案:

(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件

(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次

(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内

(4) 尽量避免在压力很大的主库上增加从库

(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2 <- Slave3...

这样的结构方便解决单点故障问题,实现Slave对Master的替换。如果Master挂了,可以立刻启用Slave1做Master,其他不变。



 

4. MySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据

 相关知识:redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。redis 提供 6种数据淘汰策略:

voltile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据

 

5. Memcache与Redis的区别都有哪些?

1)、存储方式

Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

Redis有部份存在硬盘上,这样能保证数据的持久性。

2)、数据支持类型

Memcache对数据类型支持相对简单。

Redis有复杂的数据类型。


3),value大小

redis最大可以达到1GB,而memcache只有1MB



6. Redis 常见的性能问题都有哪些?如何解决?

 

1).Master写内存快照,save命令调度rdbSave函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以Master最好不要写内存快照。


2).Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响Master重启的恢复速度。Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。

 
3).Master调用BGREWRITEAOF重写AOF文件,AOF在重写的时候会占大量的CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。

4). Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内




7, redis 最适合的场景


Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?

       如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

     1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
     2 、Redis支持数据的备份,即master-slave模式的数据备份。
     3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

(1)、会话缓存(Session Cache)

最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗?

幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。

(2)、全页缓存(FPC)

除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。

再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。

此外,对WordPress的用户来说,Pantheon有一个非常好的插件  wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

(3)、队列

Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。

如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。

(4),排行榜/计数器

Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可:

当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。

(5)、发布/订阅

最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统!(不,这是真的,你可以去核实)。

Redis提供的所有特性中,我感觉这个是喜欢的人最少的一个,虽然它为用户提供如果此多功能。
View Code
复制代码

2、 redis的优势和特点

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

3、redis的适用场景

redis 最适合的场景就是做缓存,因此它又叫缓存数据库

(1)会话缓存(Session Cache)---》存session---》速度快
(2)接口,页面缓存---》把接口数据,存在redis中
(3)队列--->celery使用
(4)排行榜/计数器--->个人页面访问量
(5)发布/订阅

4、 redis为什么这么快

https://zhuanlan.zhihu.com/p/358163330

1 纯内存操作
2 使用了高性能的网络模型,io多路复用,理论并发量的峰值 10w/s---》6w


项目并发量多少?

指得是1s内能处理的并发请求数,通过多加机器(多进程),多进程,多线程,协程,可以提高并发量


django项目没有开过进程,线程吧,那他如何实现的并发?

1s内10个人访问/index,并不是django框架中在做,而是符合wsgi协议的web服务器做,uwsgi/wsgiref--->这也是为什么项目上线要使用uwsgi,测试阶段使用wsgiref,因为uwsgi并发量高
      -django项目的并发量高低取决于,web服务器,uwsgi
      -正常业务平均下来,100--200,业务复杂一些 100以内
      -双十一,30-40w笔/s
      -某个接口的并发量----》1.6w--->麦当劳小程序
      -软件指标:用户量:几百万用户,日活月活,几十万的日活----》1s内,同时有多少人在刷某个接口1w多的并发
      -你们的项目百级别

补充:其他语言的

  java:hashMap  存key-value形式
  go:maps      存key-value形式

二、 redis的安装和使用

1、 版本问题

  redis最新稳定版版本6.x
  win:作者不支持windwos,

本质原因:redis很快,使用了io多路复用中的epoll的网络模型,这个模型不支持win,所以redis不支持win(看到高性能的服务器基本上都是基于io多路复用中的epoll的网络模型,nginx)

微软基于redis源码,自己做了个redis安装包,但是这个安装包最新只到3.x,又有第三方组织做到最新5.x的安装包

2、下载与安装

redis是c语言写的开源软件,官方提供源码,如果是在mac或linux上需要 编译,安装。具体:

mac:安装包---》编译完成的可执行文件---》下一步安装

linux:linux--》make成可执行文件---》make install 安装

win:下载安装包,一路下一步安装

  最新5.x版本 https://github.com/tporadowski/redis/releases/
  最新3.x版本 https://github.com/microsoftarchive/redis/releases

3、redis的图形化客户端rdb

mysql中有个图形化客户端-Navicat。
redis 也有很多,推荐用rdb

地址:https://github.com/uglide/RedisDesktopManager/releases

收费,99元永久

4、redis服务的启动与关闭

方式一:win上,就在服务中了,把服务开启即可,在服务中启动关闭
方式二:命令启动,等同于mysqld
  redis-server redis.windows-service.conf
  redis-server 配置文件

5、客户端连接redis

方式一:

  命令行:redis-cli -p 端口 -h 地址

  或者:redis-cli(常用)
方式二:

  客户端 :rdb连接(图形化界面连接)

三、 python连接redis

1、安装模块

pip install redis

2、python连接redis

1)普通连接

from redis import Redis

# 1 普通连接
conn = Redis(host="localhost", port=6379, db=0, password=None)  # 实例化Redis类得到conn对象
conn.set('name', "lqz")  # 通过对象调用方法,在redis中存入name为laz的数据
res = conn.get('name')  # 取出name
print(res)  # b'lqz'

2)连接池连接

1.新建py文件redis_pool放置连接池

import redis

# 实例化类生成连接池POOL
POOL = redis.ConnectionPool(max_connections=10, host='localhost', port=6379)

2.模块导入实现连接池的单例连接

# 2 连接池连接(以模块导入的方式实现单例)
import redis
from redis_pool import POOL  # 导入连接池,

# 由于python中无论模块导入多少次,都以第一次导入为准,所以POOL只会是同一个POOL(连接池)
conn = redis.Redis(connection_pool=POOL)  # 从池中拿一个连接
conn.set('name', "lqz")
print(conn.get('name'))  # b'lqz'

3)连接池多线程演示

1.新建py文件redis_pool放置连接池

import redis

# 实例化类生成连接池POOL
POOL = redis.ConnectionPool(max_connections=10, host='localhost', port=6379)

2.for循环多线程演示

复制代码
# 3 多线程演示
import redis  # 导入redis模块
from threading import Thread  # 导入线程
import time

from redis_pool import POOL  # 导入自制连接池


def get_name():
    conn = redis.Redis(connection_pool=POOL)
    print(conn.get('name'))


for i in range(10):
    t = Thread(target=get_name)
    t.start()

time.sleep(2)

# 十个 b'lqz'
复制代码

补充1:pycharm导入爆红/执行文件不能使用相对导入

1 py作为脚本运行,不能使用相对导入
2 只能使用绝对导入
3 从环境变量中开始到导起,要遵循最短路径导入
4 在pycharm中右键运行的脚本所在的目录,就会被加入到环境变量

补充2:django中没有连接池

django中一个请求就会创建一个mysql连接,但是django并发量不高,所以mysql数据库能撑住,
想在django中使用连接池,有第三方:https://www.cnblogs.com/wangruixing/p/13030755.html

四、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
"""
常用操作
复制代码

1、redis字符串操作

复制代码
import redis

conn = redis.Redis()

# 1 set(name, value, ex=None, px=None, nx=False, xx=False)
# conn.set('age', 19)  # 新增age:19

# ex,过期时间(秒)---->过期时间
# px,过期时间(毫秒) ---->过期时间
# conn.set('wife', 'lyf', ex=3)  # 3s过期

# nx,如果设置为True,则只有name不存在时,当前set操作才执行, 值存在,就修改不了,执行没效果
# conn.set('wife', 'dlrb', nx=True)  

# xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
# conn.set('wife', 'dlrb', xx=True)

# 2 setnx(name, value)--->等同于conn.set('wife','dlrb',nx=True)
# 3 setex(name, value, time)--->conn.set('wife','lyf',ex=3)
# 4 psetex(name, time_ms, value)--->conn.set('wife','lyf',px=3)

# 5 mset(*args, **kwargs)--》批量设置
# conn.mset({'name1': 'pyy', 'age1': 20})

# 6 get(name)  取值
# print(conn.get('age1'))

# 7 mget(keys, *args)
# print(conn.mget(['age1', 'age']))
# print(conn.mget('name', 'age', 'age1'))

# 8 getset(name, value)
# print(conn.getset('name', 'dsb'))  # 它跟get,再set有什么区别?

# 9 getrange(key, start, end)
# print(conn.getrange('name', 0, 1))  # 取字节 ,前闭后闭

# 10 setrange(name, offset, value)
# conn.setrange('name', 1, 'qqq')  # dsb--->dqqq

# 11 setbit(name, offset, value) ---》后面再聊---》独立用户统计---》用户量过亿---》日活
# conn.setbit('name', 1, 0)  # 改的是比特位,d 一个byte占8个比特位--》2进制---》10进制---》字符

# 12 getbit(name, offset)
# print(conn.getbit('name', 1))

# 13 bitcount(key, start=None, end=None)
# print(conn.bitcount('name', 0, 1))  # 数字指的是字节,不是比特位

# 14 strlen(name)
# 字节(一个byte)和字符(中  ?  a  都是一个字符)
# 面试题:mysql中utf8和utf8mb4有什么区别?
# utf8---》不是咱们任务的utf-8,mysql字节的,两个字节表示一个字符---》生僻字,表示存不了
# utf8mb4--》utf-8,最多4个字节表示一个字符---》存标签,存生僻字

# print(conn.strlen('name'))  # 字节--》9--》gbk编码一个中文占2个字节  utf-8编码 大部分一个中文占3个字节,生僻字可能占4

# 15 incr(self, name, amount=1)--->做计数器--》记录博客访问量--》博客表的文章上加个访问量字段,一旦有一个人访问,数字+1
# conn.incr('age') # 不存在并发安全的问题---》redis6.0之前是单线程架构,并发访问操作,实际只排着队一个个来

# 16 incrbyfloat(self, name, amount=1.0)

# 17 decr(self, name, amount=1)
# conn.decr('age')


# 18 append(key, value)
# conn.append('name','nb')
字符串操作
复制代码

2、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)
'''
import redis
conn=redis.Redis()
# 1 hset(name, key, value)
# conn.hset("userinfo",'name','彭于晏')
# conn.hset("userinfo_01",mapping={'name':"刘亦菲",'age':18})

# 2 hmset(name, mapping)---》弃用了-->直接使用hset即可
# conn.hmset("userinfo_02",mapping={'name':"刘亦菲",'age':18})

# 3 hget(name,key)
# print(str(conn.hget('userinfo_01','name'),encoding='utf-8'))
# print(str(conn.hget('userinfo_01','age'),encoding='utf-8'))

# 4 hmget(name, keys, *args)
# print(conn.hmget('userinfo_01',['name','age']))
# print(conn.hmget('userinfo_01','name','age'))


# 5 hgetall(name)--->慎用,有可能数据量很大,会撑爆内存-->一般我们redis服务器使用内存很大的服务器,应用服务器内存小一些
# print(conn.hgetall('userinfo_01'))

# 6 hlen(name)
# print(conn.hlen('userinfo_01')) # 2

# 7 hkeys(name)
# print(conn.hkeys('userinfo_01'))  # [b'name', b'age']
# 8 hvals(name)
# print(conn.hvals('userinfo_01'))  # [b'\xe5\x88\x98\xe4\xba\xa6\xe8\x8f\xb2', b'18']

# 9 hexists(name, key)
# print(conn.hexists('userinfo_01','name'))
# print(conn.hexists('userinfo_01','height'))


# 10 hdel(name,*keys)
# conn.hdel('userinfo_01','name')

# 11 hincrby(name, key, amount=1)
# conn.hincrby('userinfo_01','age')

# 12 hincrbyfloat(name, key, amount=1.0)


# 因为hgetall不安全,有可能数据量过大,所以尽量使用,迭代取值
# 13 hscan(name, cursor=0, match=None, count=None)   hash类型无序----》python 字典在3.6以后有序了,如何实现的?
# for i in range(1000):
#     conn.hset('hash_test','id_%s'%i,'鸡蛋%s号'%i)

# 分批获取,但是由于没有顺序,返回一个cursor,下次基于这个cursor再继续获取
# res=conn.hscan('hash_test',0,count=20)
# print(res)
# res=conn.hscan('hash_test',352,count=20)
# print(res)
# print(len(res[1]))
# 14 hscan_iter(name, match=None, count=None)  #全取出所有值,分批取,不是一次性全取回来,减小内存占用
# res=conn.hscan_iter('hash_test',count=10)  # generator
# # print(res)
# for item in res:
#     print(item)
#
print(conn.hgetall('hash_test'))


# hset  hget  hlen  hexists
hash操作
复制代码

3、redis之列表操作

复制代码
'''
1 lpush(name,values)
2 lpushx(name,value)
3 llen(name)
4 linsert(name, where, refvalue, value))
4 r.lset(name, index, value)
5 r.lrem(name, value, num)
6 lpop(name)
7 lindex(name, index)
8 lrange(name, start, end)
9 ltrim(name, start, end)
10 rpoplpush(src, dst)
11 blpop(keys, timeout)
12 brpoplpush(src, dst, timeout=0)

'''

import redis
conn=redis.Redis()

# 1 lpush(name,values)
# conn.lpush('girls','lyf','dlrb')  # 图形界面看到的 上面是左, 下面是右
# conn.rpush('girls','杨颖')

# 2 lpushx(name,value)  在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
# conn.lpushx('girls','杨颖1')
# conn.lpushx('girl','杨颖1')

# 3 llen(name)
# print(conn.llen('girls'))

# 4 linsert(name, where, refvalue, value))
# conn.linsert('girls','before','lyf','张杰')
# conn.linsert('girls','after','lyf','lqz')

# 4 r.lset(name, index, value)  对name对应的list中的某一个索引位置重新赋值
# conn.lset('girls',1,'lqz')

# 5 r.lrem(name, count,value)
# conn.lrem('girls',1,'lqz')  # 从左侧删第一个
# conn.lrem('girls',-1,'lqz')  # 从右侧删第一个
# conn.lrem('girls',0,'lqz')  # 全删


# 6 lpop(name)
# res=conn.lpop('girls')
# print(res)

# r=b'\xe6\x9d\xa8\xe9\xa2\x961'
# print(str(r,encoding='utf-8'))


# 7 lindex(name, index)
# print(conn.lindex('girls',1))

# 8 lrange(name, start, end)
# print(conn.lrange('girls',0,1))  # 前闭后闭

# 9 ltrim(name, start, end)  ---》修剪,只保留起始到终止
# conn.ltrim('girls',1,2)

# 10 rpoplpush(src, dst)  # 从第一个列表的右侧弹出,放入第二个列表的左侧

# 11 blpop(keys, timeout)  # 阻塞式弹出--》可以做消息队列 -->block-->如果没有值,会一直阻塞
# 作用,可以实现分布式的系统---》分布式爬虫
# 爬网页,解析数据,存入数据库一条龙,一个程序做
# 写一个程序,专门爬网页---》中间通过redis的列表做中转
# 再写一个程序专门解析网页存入数据库
# print(conn.blpop('girls',timeout=1))

# 12 brpoplpush(src, dst, timeout=0)


# lpush   lpop  linsert  llen  blpop
列表操作
复制代码

4、redis通用操作

复制代码
'''
delete(*names)
exists(name)
keys(pattern='*')
expire(name ,time)
rename(src, dst)
move(name, db))
randomkey()
type(name)

'''
import redis
conn=redis.Redis()
# delete(*names)
# conn.delete('name','name1','hash1')

# exists(name)
# print(conn.delete('name'))
# print(conn.delete('age'))

# keys(pattern='*')  # 打印所有key      * 和  ?
# print(conn.keys())
# print(conn.keys('us*'))
# print(conn.keys('age?'))

# expire(name ,time)
# conn.expire('age',3)

# rename(src, dst)
# conn.rename('wife','girl')

# move(name, db))
# conn.move('girl',3)

# randomkey()  # 随机返回一个key
# print(conn.randomkey())

# type(name)
# print(conn.type('age1'))
# print(conn.type('userinfo'))
通用操作
复制代码

5、通过管道实现事务

redis本身是不支持事务的,但是有的时候我们要实现类似这种功能:张三-100块钱,李四+100块钱

通过管道可以实现类似事物的功能:把多次操作的命令放到一个管道中,一次性执行,要么都执行了,要么都不执行

复制代码
import redis

pool = redis.ConnectionPool()  # 创建连接池
conn = redis.Redis(connection_pool=pool)  # 连接连接池

pipe = conn.pipeline(transaction=True)  # 创建事务
pipe.multi()  # 连接事务

# 以后用pipe代替conn操作
pipe.set('name', 'lqz')
# raise Exception('asdfasdf')  # 如果此处抛出异常,name和role都不会执行,反之都会执行
pipe.set('role', 'nb')

# 只是往管道中放了命令,还没执行
pipe.execute()  # 一次性执行多条命令
复制代码

五、django中使用redis

方式一:使用连接池

1.util文件夹中新建pool.py文件,存放连接池

import redis

POOL = redis.ConnectionPool(max_connections=10, host='localhost', port=6379)

2.django中任意位置导入使用

复制代码
# 测试视图
class TestView(APIView):
    def get(self, request):
        import redis
        from utils.pool import POOL

        conn = redis.Redis(connection_pool=POOL)
        print(conn.get('age'))  # b'19'
        return Response('ok')
复制代码

方式二:使用第三方  djagno-redis

 1、安装

pip install django-redis

2、在项目配置文件中

复制代码
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",
        }
    }
}
复制代码

3、在需要位置使用

复制代码
from django_redis import get_redis_connection

class TestView(APIView):
    def get(self, request):
        # 使用django配置的redis
        conn = get_redis_connection()
        print(conn.get('name'))

        # 这种方式django的缓存可以缓存到redis中,以后推荐直接这种方式
        cache.set('asdfasd', 'asdfas')  # 缓存到redis
        cache.set('wife', ['dlrb', 'lyf'])  # value值可以放任意数据类型

        return Response('ok')
复制代码

4、补充

复制代码
# 1、一旦这么配置了,以后django的缓存也缓存到reids中了
cache.set('asdfasd','asdfas')

# 2、以后在django中,不用使用redis拿连接操作了,直接用cache做就可以了
# 3、不需要关注设置的值类型是什么 cache.set('wife',['dlrb','lyf']) # value值可以放任意数据类型
# 4、底层原理,把value通过pickle转成二进制,以redis字符串的形式存到了redis中
复制代码

 

posted @   三三得九86  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示