Redis
1.非关系型内存数据(nosql;mongodb,redis),key-value的存储
2.单线程单进程,qps:10w
Mencached:多线程,支持的数据类型少,只支持字符串类型,不支持持久化
redis支持的5大数据类型
k1:'123' 字符串
k2:[1,2,3,4] 列表/数组
k3:{1,2,3,4} 集合:去重,爬虫去重
k4:{name:mcc,age:18} 字典/哈希表
k5:{('mcc',18),('zl',12)} 有序集合:游戏排行榜
redis支持持久化,两种持久化方案
python操作 redis
新建一个py文件 --安装 最新版本
使用
from redis import Redis # 实例化产生对象,就是拿到一个redis链接 conn=Redis(host='localhost',posr=6379) 现在都是默认的,不用写 操作redis(value部分都是以bytes的格式存储),所以要转一下 ret=conn.get('name') print(ret) str() bytes()
redis操作只连接池
from redis import Connection # 池子应该写成单列 写在模块中,然后引入直接用就好 pool=ConnectionPool(host='127.0.0.1',port=6379,max_connection=100) conn=Redis(connection_pool=pool) print(conn.get('name'))
redis操作之字符串
conn.set()
四个参数
ex:过期时间(秒)
px:过期时间(毫秒)
nx:默认是False,如果设置为True,则只有name不存在的时候,当前set对象才执行,若值存在,则修改不了,执行没有效果
xx:默认是False,如果设置为True,只有name存在的时候才会执行,不存在不会执行 -- 存在就会覆盖
示例
conn.set('name','egon',ex=5,xx=True) print(conn.get('name'))
setnx 默认nx=True
setex 默认ex=True
conn.setex('xxx',5,'ppp') name,time,value
批量设置 重点记忆
conn.mset(mapping) 传一个字典 conn.mset({'k1':'v1','k2':'v2'})
批量取值
conn.mget(keys,*args) keys是个列表 conn.mget(['k1','k2'])/conn.mget('k1','k2')
其他的一些方法
getrange(key,start,end) 取出字符串的一部分 其他语言不支持字符串取值,只能自己取 setrange 修改字符串内容,从指定的字符串后面开始替换 拿到的结果是字节 setrange(name,offset,value) name 是主键,offset 要替换的索引位置,value 替换成什么内容 setrange(egon,1,lxx) --elxx strlen --返回字符串的长度 其他语言计算比较复杂,所以用的多
重点
conn.incr('age') 自增
# 应用场景 文章阅读数 在线直播人数 conn.incr('age',amount=3) 指定增长为3,每一次 conn.incr('age',amount=-3) 指定自减为3
# 自减
conn.decr('age',amount=3)
追加
conn.append('age','xxx') 18xxx 注意,数字是可以自增和自减的,但是只限制是纯数字
redis之字典操作 --hash操作
conn.hset('hash1','k1','v1') hash1--类似表 k1是表中的key值 v1是表中的value值
conn.hsetnx nx:值存在就不修改
批量设值
conn.hmset('hash1',{'name':'mcc','age':18}) conn.hmget('hash1','k1')
批量取值
conn.hmget('hash1',['name','age']) conn.hmget('hash1','name','age')
取值 字典取值 获取所有
conn.hgetall('hash1',[b'name']) --b'mcc'
获取键值对的长度
conn.hlen('hash1') --就是一个表中有多少条数据 hkeys/hvalue/hexits conn.hdel('hash1','k1') 删除 conn.hincrby('hash1','k3') 增加值
重点
hscan 参数是游标,count,
hscan_iter 其实拿到的是一个生成器 内部是while 循环嵌套for循环,yidld
只支持一层的5大数据类型,也就是说字典的value只能是字符串,列表的value只能是字符串
redis之列表操作
conn.flushdb() 删掉所有库,不要做 conn.lpush('list1',10) 插入多个值,是插到上方,rpush是插入到下方 conn.llen('list1') # 获取长度 conn.linsert('list1','before',10,100) 对列表list1,在10的前面插入100,如果有多个10,是以第一个10为标准 conn.linsert('list1','after',10,100) conn.lset('list1','4',123) # 从0开始 索引**不是row,value值 row是软件做的,内部是从0开始 conn.lrem('list1',count,value) count是0代表所有全删 2代表从前往后删除2个 -2代表从后往前删除两个 conn.lpop() 从左侧pop出一个元素 # 如果一值移除,没有的话会给一个None conn.lrange() 获取从几到几的元素 前后都取,都是闭区间
重点 没有阻塞住,可以实现分布式
conn.blpop # 基于这个做一个生产者消费者模型 #这个是在取值的时候,如果没有值会一值在原地等待,所以我们可以起一个新项目,给他push值,这样就相当于完成了一个生产者消费者模型 print(conn.blpop('list1')) 没有原地等待 分布式的东西
添加值
conn.push('list1',10) 之后运行会发现 print(conn.blpop('list1')) --(b'list1',b'10')
带b就是阻塞
获取列表中所有值
conn.lrange('list1',start,end) for i in range(10000): conn.lpush('list1',i) print(conn.lrange('list1',0,conn,llen('list1'))) # 将所有的值都拿了出来,不太好,需要有一个类似于生成器的东西scan,只能自己写
自定义生成器
def scan_list(name,count=10): index = 0 while True: # count+index-1 是因为取得是自闭和的值,从0-9就是10条了 data_list = conn.lrange(name,index,count+index-1) if not data_list: return # 这里就是将所有的数据都取出后,列表空了,那就直接结束这个函数 # 下面是正常的逻辑 index = count # 这样的话下面再取的值的话就是从索引10 开始了 for data in data_list: yield data # 使用生成器直接将data一个一个的给出 print(conn.lrange('list1',0,100)) # 这个就是将100条全部取出 for i in scan_list('list1',5): print i # 和全部取出有了明显的对比,下面这个更省内存
redis其他操作--不管数据类型,通用操作
conn.delete() 根据key值删除 conn.exists() 返回0/1 conn.keys() 里面可以传正则 模糊匹配 expire conn.rename() 给key值重命名 conn.move() 移动数据库 randomkey() 随机获取一个key conn.type() 查看数据类型 scan,scan_iter
django中操作
管道-实现事务 pipe = conn.pipeline(transaction = True) pipe.multi() pipe.set('name','alex') pipe.set('role','sb') pipe.execute() # 这个才是真正的去执行
所有框架都能用的方式
-新建一个py文件,生成一个redis数据库连接池 from redis import ConnectionPool POOL = ConnectionPool(host='127.0.0.1',port=6379,max_connection=100)
在哪用,导过来
conn = Redis(connection_pool=POOL) conn.set('xxx','yyy') conn.get('name')
django中使用 django-redis
1.安装
2.在settings中做配置
# 缓存配置:采用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} } } }
3.使用:
from django-redis import get_redis_connection def index(request): conn = get_redis_connection() print conn.get('name') conn.set return HttpResponse('ok')