redis
介绍
win安装redis win版本下载地址
# 最新5.x版本 https://github.com/tporadowski/redis/releases/
# 最新3.x版本 https://github.com/microsoftarchive/redis/releases
- 关系型数据库
PostgreSQL,MySQL,sqlserver,oracle...
sql语句都是通用的
- 非关系型数据库 no sql
redis,MongoDB,clickhouse,elasticsearch...
缓存
redis是开源使用c编写的cs架构软件
- clint : 客户端:命令创建,桌面软件resp,Navicat,Python代码,Go,Java,Node
- server : 服务端:一台服务器,一直运行,监听
6379
端口 - 使用key-value形式存储,vaule有5种数据类型
字符串
,列表
,hash
,集合
,有序集合
- 三个特点
纯内存存储
:速度非常快,适合用于高并发场景可以持久化
:永久保存数据操作
:单进程,单线程架构,没有锁IO多路复用的模型
:并发量高
redis客户端
-1 cmd命令中的reids-cli
-redis-cli # 默认链本地的6379
-redis-cli -h 地址 -p 端口
redis服务启动和停止
-1 使用服务--》点击启动,停止即可
-net start redis
-net stop redis
-2 使用命令:(启动server)
-redis-server 配置文件启动
-redis-server ./redis.windows-service.conf
-ctrl c
-3 关闭:在客户端
shutdown :友好关闭
python操作redis
普通连接
pip install redis
import redis
conn = redis.Redis(
host='localhost',
port='6379',
db=0,
)
conn.set('name','heart')
conn.close()
连接池连接
import redis
# 1 做一个连接池
# decode_responses: 使用UTF-8解码
POOL = redis.ConnectionPool(max_connections=10, host='127.0.0.1', port=6379,decode_responses=True)
# 2 从池中拿连接
# connection_pool: 绑定连接池
conn = redis.Redis(connection_pool=POOL)
# 3 使用连接操作redis
res = conn.get('name')
print(res)
# 4 关闭,把连接放回池中
conn.close()
做一个单例的池,全局只有这一个对象
pool.py
import redis
POOL = redis.ConnectionPool(max_connections=10,host='127.0.0.1', port=6379, decode_responses=True)
test.py
import redis
from pool import POOL
conn = redis.Redis(connection_pool=POOL)
res = conn.get('name')
print(res)
conn.close()
redis之字符串
set(name, value, ex=None, px=None, nx=False, xx=False)
ex
: 多少秒过期,被清理掉
px
: 多少毫秒过期,被清理掉
nx
: 只有name不存在时,当前set操作才执行,值存在,修改不了,执行没效果
xx
: 只有name存在时,当前set操作才执行,值存在,才能修改,值不存在不会设置新值
conn.set('age',18)
setnx(name,value)
只有name不存在时,当前set操作才执行,值存在,修改不了,执行没效果
conn.setnx('height',181)
setex(name,value,time)
多少秒过期,被清理掉
conn.setex('name','heart',10)
psetex(name,time_ms,value)
多少毫秒过期,被清理掉
conn.psetex('name',1000,'heart')
mset(*args,**kwargs)
批量设置
conn.mset({'name': 'heart', 'age': 19, 'height': 180, 'hobby': 'soccer'})
mget(keys,*args)
根据name批量取值
res = conn.mget('name', 'age')
res = conn.mget('name', 'age', 'height', 'hobby')
print(res) # ['heart', '19', '180', 'soccer']
getset(name,value)
获取值然后设置新值
res = conn.getset('name', 'god')
print(res) # heart
getrange(key,start,end)
获取起始和结束位置的字符串,前闭后闭,取字节
# heartgod
res = conn.getrange('name', 0, 1)
print(res) # he
setrange(name,offset,value)
在从offset开始偏移的开始设置字符串,用字节排
# heartgod
conn.setrange('name',8,'xxx')
# heartgodxxx
setbit(name,offset,value)
getbit(name,offset)
bitcount(key,start=None,end=None)
bitop(operation,dest,*keys)
strlen(name)
统计字节长度
# heartgodxxx
res = conn.strlen('name')
print(res) # 11
incrby(self,name,amount)
自增,做计数器,性能高,单线程,没有并发安全问题,不会出错乱
conn.incrby('age',2) # 执行一次+2
incrbyfloat(self,name,amount=1.0)
增加小数
conn.incrbyfloat('age',amount=1.1)
decrby(self,name,amount=1)
每执行一次就减少
conn.decrby('age',3) # 执行一次-3
append(key,value)
每执行一次就追加
conn.append('name','sss') # heartgodxxxsss
redis之hash
hset(name, key, value)
name是存入的名字,后面是k:v所对应的值
conn.hset('user-info-01','name','heart')
hset(name, mapping)
使用mapping一次性设置
conn.hset('user-info-01',mapping={'name','heart','age':18,'height':180})
hget(name,key)
获取值
res = conn.hget('user-info-01','name')
print(res) # heart
*hmget(name, keys, args)
批量获取值
res = conn.hmget('user-info-01', 'name', 'age')
print(res) # ['heart', '19']
hgetall(name)
获取所有k:v值
res = conn.hgetall('user-info-01')
print(res) # {'name': 'heart', 'age': '19', 'hobby': '篮球'}
hlen(name)
统计字典大小
res = conn.hlen('user-info-01')
print(res) # 3
hkeys(name)
获取所有的key
res = conn.hkeys('user-info-01')
print(res) # ['name', 'age', 'hobby']
hvals(name)
获取所有的value
res = conn.hvals('user-info-01')
print(res) # ['heart', '19', '篮球']
hexists(name, key)
判断key是否存在
res = conn.hexists('user-info-01','name')
print(res) # True
hdel(name,*keys)
删除key
res = conn.hdel('user-info-01','age')
print(res) # 1
hincrby(name, key, amount=1)
设置自增
conn.hincrby('user-info-01','age',amount=2)
hincrbyfloat(name, key, amount=1.0)
自增小数
conn.hincrbyfloat('user-info-01','age',amount=2.2)
hscan(name, cursor=0, match=None, count=None)
如果hash存的数据量很大,不能使用hgetall一次性全取回来,需要分批取
hscan不单独用,count是取的条数,但是有时候上下会差一点点,有浮动
cursor写上一次返回的值,接着按那个游标的位置拿数据
res = conn.hscan('map_demo',count=10)
hscan_iter(name, match=None, count=None)
取出所有值,但是分批取
for item in conn.hscan_iter('name',count=10):
print(item)
redis之list
lpush(name, values)
从左向右操作,放到列表的最右边
conn.lpush('girls','刘亦菲')
conn.lpush('girls','迪丽热巴')
conn.lpush('girls','小红')
**rpush(name, values) **
从右向左操作,放到列表的最左边
conn.rpush('girls','小紫')
lpushx(name, value)
在name对应的list中添加元素,只有name存在时,值添加到列表的最左边
conn.lpushx('girls','小绿')
**rpushx(name, value) **
在name对应的list中添加元素,只有name存在时,值添加到列表的最右边
conn.rpushx('girls','小蓝')
llen(name)
查看列表大小
res = conn.llen('girls')
print(res) # 6
linsert(name, where, refvalue, value))
插入值,where是插哪,前面就写before,后面就写after,refvalue指定要插它前面的值,value就是要插入的值
conn.linsert('girls','before','刘亦菲','小黄')
r.lset(name, index, value)
按照索引设置对应的值
conn.lset('girls',0,'xx') # 索引为0的位置的值设置成xx
r.lrem(name, value, num)
conn.lrem('girls', count=1, value='xx') # 从左侧删除一个符合条件
conn.lrem('girls', count=-1, value='xx') # 从右侧删除一个符合条件
conn.lrem('girls', count=0, value='xx') # 删除所有符合条件的值
lpop(name)
从列表最左侧弹出一个值
conn.lpop('girls')
**rpop(name) **
从列表最右侧弹出一个值
conn.rpop('girls')
lindex(name, index)
按索引取值
res = conn.lindex('girls',1)
print(res) # 迪丽热巴
lrange(name, start, end)
按起始和结束位置取出值
res = conn.lrange('girls', 0, 2)
print(res) # ['小红', '迪丽热巴', '小黄']
ltrim(name, start, end)
留下来起始和结束位置的值
conn.ltrim('girls', 0, 2)
rpoplpush(src, dst)
右侧的弹出,推到左侧
blpop(keys, timeout)
r.brpop(keys, timeout)
从右向左获取数据
brpoplpush(src, dst, timeout=0)
其他操作
delete(*names)
删除name所对应的
conn.delete('name','user-info-01')
exists(name)
判断是否存在
print(conn.exists('age1'))
keys(pattern='*')
取出所有符合的key
print(conn.keys('user*'))
expire(name ,time)
设置时间
conn.expire('age',5)
rename(src, dst)
改名
conn.rename('girls','hobby01')
move(name, db))
移动name到别的库
conn.move('hobby01',3)
randomkey()
随机一个库
print(conn.randomkey())
django中使用redis
通用方式
# 写个pool.py
import redis
POOL = redis.ConnectionPool(max_connections=10, decode_responses=True)
# 在哪里用,导入用即可
from utils.pool import POOL
import redis
class RedisView(ViewSet):
def list(self, request):
conn = redis.Redis(connection_pool=POOL)
conn.incrby('count')
count = conn.get('count')
return APIResponse(msg='您是第%s个访问的' % count)
django-redis
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}
# "PASSWORD": "123",
}
}
}
# 在使用的位置
from django_redis import get_redis_connection
class RedisView(ViewSet):
def list(self, request):
conn = get_redis_connection() # 从池中获取一个链接
conn.incrby('count')
count = conn.get('count')
return APIResponse(msg='您是第%s个访问的' % count)
django的缓存
from django.core.cache import cache
django内置的,可以直接操作缓存,缓存的位置在内存,只要项目一重启,数据就没了
后期我们要把缓存数据放到redis中,redis可以持久化,项目停止,但redis还运行,数据就不会丢
配置文件配好后,以后只要使用cache.set
和cache.get
去redis设置和取
cache.set()
: 设置缓存
cache.get()
: 获取缓存
优势:redis 分数据类型,只能设置5种数据类型,但是用django的缓存,不限制类型,可以放python的任意类型
django cache 底层是基于:把存储的类型使用pickle序列化转成bytes格式,然后当redis的字符串形式存到redis中,以后咱们做redis的操作,可以直接使用django的缓存, 不需要考虑类型
from rest_framework.viewsets import GenericViewSet
from django.core.cache import cache
class RedisView(GenericViewSet):
def list(self, request):
cache.set('name', 'heart')
res = cache.get('name')
print(res) # heart
return APIResponse(msg=f'{res}')
标签:name,res,redis,value,print,conn
From: https://www.cnblogs.com/ssrheart/p/18214893