1.连接方式
1.操作模式
import redis
# 方式1
r = redis.Redis(host='192.168.211.133', port=6379, password='foobared')
# 方式二 StrictRedis是Redis的子类 用于向后兼容旧版本的 redis-py
# r = redis.StrictRedis(host='192.168.211.133', port=6379, password='foobared')
r.set('foo', 'Bar')
print(r.get('foo'))
2.连接池
import redis
#避免每次建立、释放连接的开销
pool = redis.ConnectionPool(host='192.168.211.133', port=6379, password='foobared')
r = redis.Redis(connection_pool=pool)
print(r.get("age")) # b'99'
2.操作
1.String 操作
增
#set
r.set("name","ja",5)
#setx
setex("name","ja",5) #设置5s的过期时间
#mset
r.mset(k1='v1', k2='v2')
#append
r.append("name","1") #在ja的后面加1
删
#delete
r.delet("name")
改
使用增加时存在则修改
查
#get
r.get("name")
#mget
r.mget(['v1', 'v2'])
注意:
incr(“age”, amount=1) #将键为age的自增1
incrbyfloat(“age”, amount=1.0) #将键为age的自增1.0
decr(“age”, amount=1)#将键为age的自减1.0
2.keys操作
增
String,Hash,List,Set.Zset的增加即是key的增加
删
#delete
r.delete("name")
改
#expire
r.expire("name",10) # 为某个redis的某个name设置超时时间
查
#exists
r.exists("name")
#keys(pattern='*')
r.keys(pattern="k*") # 根据模型获取redis的name
#getrange
r.getrange("name",1,2)
#ttl
r.ttl("name") #返回给定 key 的剩余生存时间
3.Hash 操作
哈希表
哈希表也叫散列表,是存储Key-Value映射的集合.对于某一个Key,哈希表可以在接近O(1)的时间内进行读写操作,哈希表通过哈希函数实现Key和数组下标的转换,通过开放寻址法和链表法来解决哈希冲突
增
#设置单个属性
r.hset("user","name","ja")
#设置多个属性值
r.hmset('xx', {'k1':'v1', 'k2': 'v2'})
删
# 将name对应的hash中指定key的键值对删除
r.hdel("user","name")
r.del("user")
改
增加存在时即为设置
查
# 查询单个值
r.hget("infos","name")
# 查询多个值
r.hmget("infos",["name","age"]
# 查询所有值
r.hgetall("infos")
# 获取name对应的hash中所有的key的值
r.hkeys("infos")
# 遍历info下的所有键值
for i in r.hscan_iter("infos"):
print(i)
注意:
# 自增name对应的hash中的指定key的值,不存在则创建key=amount
r.hincrby("infos","age",2)
# 自增name对应的hash中的指定key的值,不存在则创建key=amount amount,自增数(浮点数)
r.hincrbyfloat("infos","age",2.0)
4.List 操作
1.增
# 在name对应的列表的某一个值前或后插入一个新值
r.lset("scores",1,98)
# 在左侧插⼊数据
r.lpush('oo', 11,22,33) # 查询后的顺序: 33,22,11
# 在右侧插⼊数据
rpushx(name, value) # 表示从右向左操作
# 在name对应的列表的某一个值前或后插入一个新值
r.linsert("scores","AFTER","34","44") #在34的后面插入44
删
# 删除指定的尾部元素
r.Rpop("scores")
#在name对应的列表中移除没有在start-end索引之间的值
r.lrem("scores",-1,83) #从score列表右侧开始删除1个83份
改
增加时存在则修改
查
# 在name对应的列表中根据索引获取列表元素
r.lindex("scores",3)
# 在name对应的列表分片获取数据
r.lrange("scores",0,-1)
5.Set 操作
增加
# name对应的集合中添加元素
r.sadd("name",1,2,3,4,5,6,6)
删
# 在name对应的集合中删除某些值
r.srem("name",5)
改
增加时存在则修改
查
# 获取name对应的集合的所有成员
r.smembers("score_set01")
# 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
for i in r.sscan_iter("score_set01"):
print(i)
5.Zset 操作
增加
# 在name对应的有序集合中添加元素
r.zadd("z",{"n1":1,"n2":2,"n3":3,"n4":4})
删
# 删除name对应的有序集合中值是values的成员
zrem('z', ['s1', 's2'])
# 根据分数范围删除
r.zremrangebyscore("z",1,7)
改
增加时存在则修改
查
# 按照索引范围获取name对应的有序集合的元素
'''参数:
name redis的name
start 有序集合索引起始位置
end 有序集合索引结束位置
desc 排序规则,默认按照分数从小到大排序
withscores 是否获取元素的分数,默认只获取元素的值
score_cast_func 对分数进行数据转换的函数
'''
r.zrange("z",0,1,desc=False,withscores=True,score_cast_func=int)
r.zrange("z",0,2)
#获取name对应有序集合中value对应的分数
r.zscore("z","n4")
# 根据排行范围删除
r.zremrangebyrank("z",0,1)
6.使用场景
针对各种数据类型使用场景如下:
类型 | 作用 |
---|---|
String | 最常规的 set/get 操作,value 可以是 String 也可以是数字。一般做一些复杂的计数功能的缓存,比如减少库存 |
hash | 这里 value 存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以 cookieId 作为 key,设置 30 分钟为缓存过期时间,能很好的模拟出类似 session 的效果。 |
list | 使用 List 的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用 lrange 命令,做基于 redis 的分页功能,性能极佳,用户体验好.本人还用一个场景,很合适 — 取行情信息.就也是个生产者和消费者的场景.LIST 可以很好的完成排队,先进先出的原则 |
set | 因为 set 堆放的是一堆不重复值的集合。所以可以做全局去重的功能。另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。 |
sorted set | sorted set 多了一个权重参数 score, 集合中的元素能够按 score 进行排列。可以做排行榜应用,取 TOP N 操作 |
3 管道
redis-py 默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用 pipline 实现一次请求指定多个命令,并且默认情况下一次 pipline 是原子性操作。
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
r = redis.Redis(connection_pool=pool)
# pipe = r.pipeline(transaction=False)
pipe = r.pipeline(transaction=True)
pipe.set('name', 'alex')
pipe.set('role', 'sb')
pipe.execute()
4 发布订阅
订阅者:
import redis
r=redis.Redis(host='127.0.0.1')
pub=r.pubsub()
pub.subscribe("fm104.5")
pub.parse_response()
while 1:
msg = pub.parse_response()
print(msg)
发布者:
import redis
r=redis.Redis(host='127.0.0.1')
r.publish("fm104.5", "Hi,yuan!")
应用场景
1.聊天系统
2.微博的订阅
5.集群
1.安装
pip install redis-py-cluster
2.使用
from rediscluster import RedisCluster
if __name__ == '__main__':
try:
# 构建所有的节点,Redis会使⽤CRC16算法,将键和值写到某个节点上
startup_nodes = [
{'host': '192.168.26.128', 'port': '7000'},
{'host': '192.168.26.130', 'port': '7003'},
{'host': '192.168.26.128', 'port': '7001'},
]
# 构建StrictRedisCluster对象
src=RedisCluster(startup_nodes=startup_nodes,decode_responses=True)
# 设置键为name、值为ja的数据
result=src.set('name','ja')
print(result)
# 获取键为name
name = src.get('name')
print(name)
except Exception as e:
print(e)
6.哨兵
# 导入redis sentinel包
from redis.sentinel import Sentinel
# 指定sentinel的地址和端口号
sentinel = Sentinel([('localhost', 26380)], socket_timeout=0.1)
# 测试,获取以下主库和从库的信息
sentinel.discover_master('mymaster')
sentinel.discover_slaves('mymaster')
# 配置读写分离
# 写节点
master = sentinel.master_for('mymaster', socket_timeout=0.1)
# 读节点
slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
# 读写分离测试 key
master.set('account', '123')
slave.get('account')
7.Django中的应用
1.单机应用
setting.py
CACHES = {
"default": { # 默认
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://192.168.103.143:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
"session": { # session
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://192.168.103.143:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
views.py
from django_redis import get_redis_connection
redis_conn = get_redis_connection('verify_code')