redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步
支持的数据类型:
string 字符串
list 列表
set 集合
hash 哈希
zset 有序集合
redis={
k1:'123', 字符串
k2:[1,2,3,4], 列表/数组
k3:{1,2,3,4} 集合
k4:{name:lqz,age:12} 字典/哈希表
k5:{('lqz',18),('egon',33)} 有序集合
}
redis最适合的场景
做缓存
session数据
游戏排行榜
对速度要求比较高的数据的存储
做消息队列
比较redis和Memcached
redis 支持5大数据类型
redis支持持久化
单线程,单进程,速度是非常快
Memcached不能持久化,只支持字符串
import redis
# 拿到redis的连接
conn = redis.Redis(host='192.168.32.100',port=6379,password='redis')
conn.set('age','18')
age = conn.get('age')
# redis中存的都是byte格式
print(age)
# 首先新建一个模块
import redis
POOL = redis.ConnectionPool(host='192.168.32.100',port=6379,password='redis',max_connections=1000)
# 使用连接池
from conn_pool import POOL
# 每次执行这句话,从池子中取一个链接
conn = redis.Redis(connection_pool=POOL)
print(conn.get('name'))
set(name,value,ex=None,px=None,nx=False,xx=False)
conn = redis.Redis(host='192.168.32.100',port=6379,password='redis')
# nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
conn.set('name','egon',nx=True)
print(conn.get('name'))
# ex,过期时间(秒)
conn.set('height','180',ex=5)
setex(name,value,time)
# 设置值
conn.setex('k1',5,'k1')
mset(*args,**kwargs)
# 批量设置值
conn.mset({'name':'lqz','age':18})
mget(keys,*args)
# 批量获取
print(conn.mget(['name','age']))
getset(name,value)
# 设置新值并获取原来的值
print(conn.getset('name','egon'))
getrange(key,start,end)
# 获取子序列 start起始位置 end结束位置
print(conn.getrange('name',0,2))
setrange(name,offset,value)
# 修改字符串内容,从指定字符串索引开始向后替换(新值太长时,则向后添加)
conn.setrange('name',1,'ppppppp')
strlen(name)
# 返回name对应值的字节长度(一个汉字3个字节)
print(conn.strlen('name'))
print(len(conn.get('name')))
incr(self,name,amount=1)
# 自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增
conn.incr('age',amount=4)
decr(self,name,amount=1)
# 自减 name对应的值,当name不存在时,则创建name=amount,否则,则自减。
conn.decr('age')
append(key,value)
# 在redis name对应的值后面追加内容
conn.append('age','pp')
lpush(name,values)
# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
conn.lpush('l1',*[1,2,3,'asdfasdf'])
conn.lpush('l2',1,2,3)
# 表示从右向左操作
rpush(name, values)
lpushx(name,value)
# 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
conn.lpushx('l2','555')
linsert(name,where,refvalue,value)
# 在name对应的列表的某一个值前或后插入一个新值
conn.linsert('l2','BEFORE','3','pppp')
lset(name,index,value)
# 对name对应的list中的某一个索引位置重新赋值
conn.lset('l2',1,'77777')
lrem(name,value,num)
# 在name对应的list中删除指定的值
conn.lrem('l2',-1,'1')
lpop(keys,timeout)
# 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
print(conn.lpop('l2'))
lindex(name,index)
# 在name对应的列表中根据索引获取列表元素
print(conn.lindex('l2',2))
lrange(name,start,end)
# 在name对应的列表分片获取数据
print(conn.lrange('l2',0,1))
ltrim(name,start,end)
# 移除不在0--2之间的值
conn.ltrim('l2',0,2)
blpop(keys,timeout)
# 将多个列表排列,按照从左到右去pop对应列表的元素
print(conn.blpop('l2'))
hset(name,key,value)
# name对应的hash中设置一个键值对(不存在,则创建;否则,修改)
conn.hset('n1','name','lqz')
hmset(name,mapping)
# 在name对应的hash中批量设置键值对
conn.hmset('n2',{'name':'lqz','age':18})
hget(name,key)
# 在name对应的hash中获取根据key获取value
print(conn.hget('n2','name'))
hmget(name,keys,*args)
# 在name对应的hash中获取多个key的值
print(conn.hmget('n2',['name','age']))
print(conn.hmget('n2','name','age'))
print(conn.hmget('n2','name'))
hgetall(name)
# 获取name对应hash的所有键值
print(conn.hgetall('n2'))
hlen(name)
# 获取name对应的hash中键值对的个数
print(conn.hlen('n2'))
hkeys(name)
# 获取name对应的hash中所有的key的值
print(conn.hkeys('n2'))
hvals(name)
# 获取name对应的hash中所有的value的值
print(conn.hvals('n2'))
hexists(name,key)
# 检查name对应的hash是否存在当前传入的key
print(conn.hexists('n2','ddd'))
hdel(name,*keys)
# 将name对应的hash中指定key的键值对删除
conn.hdel('n2','name','age')
hincrby(name,key,amount=1)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount
conn.hincrby('n1','age')
hscan_iter(name,match=None,count=None)
# 利用yield封装hscan创建生成器,实现分批去redis中获取数据
for i in conn.hscan_iter('n1',count=10000):
print(i)
自定义增量迭代(因为列表中没有增量迭代)
def l_scan(name,count=1000):
cursor=0
while True:
if cursor>=conn.llen(name):
break
ret=conn.lrange(name,cursor,count+cursor-1)
cursor+=count
for i in ret:
yield i
delete(*names)
# 根据删除redis中的任意数据类型
conn.delete('age','name')
exists(name)
# 检测redis的name是否存在
ret=conn.exists('n1')
print(ret)
keys(pattern=‘*’)
# 模糊查询key值
ret=conn.keys('n?')
ret=conn.keys('n*')
ret=conn.keys('n[1n]')
print(ret)
管道(模拟事务)
pipe = conn.pipeline(transaction=True)
pipe.multi()
pipe.set('name', 'alex')
pipe.set('role', 'sb')
pipe.execute()
方式一:
新建redis_pool.py
import redis
POOL = redis.Redis(host='192.168.32.100',port=6379,password='redis',max_connections=1000)
视图函数中使用:
import redis
from django.shortcuts import render,HttpResponse
from utils.redis_pool import POOL
def index(request):
conn = redis.Redis(connection_pool=POOL)
conn.hset('kkk','age',18)
return HttpResponse('设置成功')
def order(request):
conn = redis.Redis(connection_pool=POOL)
conn.hget('kkk','age')
return HttpResponse('获取成功')
方式二:
安装django-redis模块
在settings里配置
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.shortcuts import render,HttpResponse
from django_redis import get_redis_connection
def test(request):
conn=get_redis_connection('default')
ret=conn.get('n123')
return HttpResponse('%s'%ret)