常用指令(启动命令)
-
redis-cli启动(可以理解为进入redis) -
systemctl restart redis重启redis服务 -
keys *打印所有的键(高危命令,实际中可能有几亿条数据会导致卡死)高危命令 -
dbsize返回键值对的个数 -
type k1返回k1的值的类型 -
exists k1返回某个键值对是否存在(可以写多个,返回的值就是存在的个数) -
rename k1 k11对键进行改名 -
flashall删除所有的键值对高危命令 -
ttl k1返回键的生存时间(返回-1就是存在且永不过期,-2就是不存在,其他就是还剩多少秒过期) -
expore k1 20设置k1还有20秒过期,到期自动删除 -
persist k1把设置了过期时间但是还没过期的k1取消定时过期
字符串
-
setex k1 v1 300设置值的时候同时设置过期时间 -
get k1获取值 -
mset k1 v1 k2 v2同时设置多个键值对 -
mget k1 k2 k3同时获取多个键值对的值 -
getset k1 v111如果k1的值存在的话,就把k1的值设置为新的值,如果k1的值不存在那就返回空nil -
set k1 v1 ex 10设置键值对并且设置10秒的超时时间 -
setex k1 10 v1设置键值对并且设置10秒的超时时间 -
setnx k1 v1如果不存在的话就设置k1的值为v1 -
del k1 k2删除指定的键值对(一个或者多个)(返回删除成功的个数) -
append k1 v1如果k1不存在那就相当于set指令直接设置值,如果k1存在那就把v1与原来的值进行拼接 -
setrange k1 3 w把k1下标为3的位置处的元素替换为w -
strlen k1返回k1的字符串长度 -
getrange k1 0 4返回k1的索引0-4的值(切片)闭区间 -
incr num每次调用incr时对应的值加一(如果该键不存在则自动创建为0且把值加一) -
incrby num 100一次性给num加100 -
decr num每次调用时给对应的值减一(如果该键不存在则自动创建为0且把该值减一) -
decrby num 100一次性给num减100
列表
-
lpush l1 a b c如果l1存在则在前面插入,不存在l1的话就自动创建l1 -
lpushx l1 vvv在l1前面插入vvv这个元素,如果l1不存在则不插入 -
rpush l1 a b c如果l1存在则在后面插入,不存在l1的话就自动创建l1 -
rpushx l1 vvv在l1后面插入这个元素,如果l1不存在的话则不插入注意插入的时候是把a b c按顺序一个一个的从前面或后面插进去
-
linsert l1 a before a1在l1里面的a元素的前面插入一个a1 -
linsert l1 a after a1在a元素的后面插入一个a1 -
lrange l1 0 -1取出l1里面的索引0到索引-1的值(从头取到尾就是取出整个列表) -
lrange l1 1 2闭区间取出值(单边超出索引就取到尽头为止,两边都超出索引的话就就爆empty) -
lindex l1 2返回l1的索引为2的下标对应的元素 -
del l1删除整个列表 -
lpop l1删除最左边的一个元素 -
rpop l1删除最右边的一个元素 -
rpoplpush l1 l2把l1的最右边的元素删除后从l2的左边插进去 -
lrem l1 2 a把l1里面的元素a从左到右删两个(最多删两个,不够的话就都删,有三个的话也删两个) -
lset l1 2 bbb把l1里面索引为2的元素的值替换为bbb
hash
hmset user:1 name zhangsan age 20设置键名为user:1字段name的值为zhangsan字段age的值为20hmget user:1 name age取user:1中name和age字段的值hgetall user:1取出user:1里面的所有字段和值hlen user:1获取user:1里面的字段的个数(键值对的个数)hexists user:1 name判断user:2里面有没有name字段exists user:1判断user:2是否存在hincrby user:1 age 20为数字添加值(注意是基础上添加)hset user:1 name jelee把user:1里面的name字段的值换成jelee
集合
sadd s1 a a b创建一个集合并且设置元素为a a b(集合会自动去重)smembers s1查看集合的值scard s1获取集合中元素的个数srandmember s1随机返回集合中的一个元素srandmember s1 2随机返回集合中的两个元素sismember s1 v判断s1中的v元素是否存在spop s1随机删除s1中的一个元素spop s1 2随机删除s1中的两个元素smove s1 s2 a把元素a从s1移动到s2中sinter s1 s2求集合s1和s2的交集sinterstore tem s1 s2求集合s1和s2的交集并且把所求结果保存到tem新集合(如果集合存在则覆盖)sunion s1 s2求集合s1和s2的并集sunionstore tem s1 s2求集合s1和s2的并集并且把所求结果保存到tem新集合(如果集合存在则覆盖)sdiff s1 s2求集合s1和s2的差集sdiffstore tem s1 s2求集合s1和s2的差集并且把所求结果保存到tem新集合(如果集合存在则覆盖)
有序集合
从有序集合中取出东西一定是有序的
所以返回的索引范围内的东西是指排序后的索引范围内的
而不是原生的索引范围内的
-
zadd top 0 xuwei 0 zhoujielun创建有序集合top[ 分数 名称 ] -
zscore top xuwei获取对应名称的分数值 -
zrange top 0 -1把里面的值按照分数升序 -
zrange top 0 -1 withscores把里面的值按照分数升序(附带分数) -
zrank top xuwei返回对应的名称的索引值 -
zcard top返回top里面的集合元素的个数 -
zrangescore top -inf +inf把里面的所有元素默认按照分数升序排序(-inf表示起始元素+inf表示结束元素) -
zrangescore top -inf +inf withscores把里面的所有元素默认按照升序排序(附带分数) -
zrevrange top 0 -1把top里面的元素按照分数从大到小排序 -
zrevrange top 0 -1 withscores把索引范围内的元素按照分数从大到小排序(附带分数) -
zrevrangebyscore top 300 30把分数范围内的元素按照分数从大到小排序 -
zrevrangebyscore top 300 30 withscores把分数范围内的元素按照分数从大到小排序(附带分数) -
zcount top 30 300返回top中分数在30到300之间的成员个数 -
zrangebyscore top 30 300返回top中分数在30到300之间的成员 -
zrangebyscore top 30 300 withscores返回top中分数在30到300之间的成员(附带分数) -
zadd top 40 item为item重新赋值40 -
zincrby top 30 item给item的分数加30 -
zremrangebyscore top 0 5删除分数在0-5之间的成员并返回删除的成员数量 -
zremrangebyrank top 0 1删除索引在0-1之间的成员并返回删除的成员数量
消息订阅
subscribe fm1订阅fm1subscribe fm1 fm2订阅fm1和fm2subscribe fm*订阅fm开头的所有publish fm1 "hello"fm1发布消息
python操作redis
快速上手
- 下载redis模块
pip install redis==4.6.0
python
import redis
# 两种连接方式
conn1 = redis.Redis(host='192.168.207.100', port=6379)
# conn1 = redis.Redis.from_url("redis://:@192.168.207.100:6379/0")
conn1.set('k1', 'v1')
print(conn1.get('k1').decode('utf-8'))
第二种连接方式的格式:
redis://:密码@ip地址:端口号/数据库号
默认拿到的是bytes类型的数据,需要decode
或者:
在创建redis对象的时候添加参数
pythonconn1 = redis.Redis(host='192.168.207.100', port=6379, decode_responses=True)可以自动的转换编码
最佳实践:
python
import redis
conn1 = redis.Redis(host='192.168.207.100', port=6379, decode_responses=True)
conn1.set('k1', 'v1')
print(conn1.get('k1'))
连接池
创建连接池用于让连接可以复用,不用每次使用完成之后都销毁,可以放在连接池中以便以后复用
注意
decode_responses=True需要写在连接池里面,不能写在redis创建处
python
import redis
pool = redis.ConnectionPool(
host='192.168.207.100',
port=6379,
db=0, # 设置数据库号
max_connections=100, # 允许的最大连接数量
decode_responses=True
)
conn1 = redis.Redis(connection_pool=pool)
conn1.set('k1', 'v1')
print(conn1.get('k1'))
通用全局命令
python
print(conn1.keys('k*')) # ['k4', 'k1', 'k3', 'k2']
print(conn1.get('k1')) # v1
print(conn1.rename('k1','k11')) # True
print(conn1.exists('k1')) # 0
print(conn1.type('k11')) # String
print(conn1.delete('k1')) # 删除 k1
print(conn1.expire('k1', 10)) # 设置过期时间
print(conn1.persist('k3')) # 取消设置过期时间
print(conn1.ttl('k1')) # 查看设置的过期时间
print(conn1.dbsize()) # 获取数据总大小(总数量)
print(conn1.flushall()) # 删除数据库中的所有数据
str操作
python
conn1.set('k1', 'v1', ex=10) # 设置过期时间为10秒
conn1.setex('k1', 10, 'v1') # 设置过期时间为10秒
conn1.getset('k1', 'v1111') # 不存在返回 None 存在返回上一次的值 然后在设置一个新的值
conn1.setnx('k1', 'v1') # 如果存在的话就什么都不做 如果不存在的话就设置为 v1
d = {'a': 'b', 'c': 'd', 'e': 'f'}
conn1.mset(mapping=d) # 批量设置值
print(conn1.mget(d.keys())) # 批量获取值
print(conn1.mget('a', 'c')) # 批量获取值
print(conn1.strlen('k1')) # 获取值的长度
python
conn1.set('num', 10)
conn1.incr('num') # 每次调用都让值加1
python
conn1.set('num', 10)
conn1.incrby('num', 10) # 累加固定的值
python
conn1.decr('num') # 自减1
conn1.decrby('num', 10) # 一次性减去固定的值
hash操作
python
conn1 = redis.Redis(connection_pool=pool)
d = {'id': 1, 'name': 'jelee', 'age': 21}
conn1.hset('user',mapping=d) # 给hash设置值
print(conn1.hget('user', 'name')) # 获取值
python
conn1.hset('user', key='name', value='jelee')
print(conn1.hget('user', 'name'))
conn1.hset('user', 'name', '重新赋值') # 为自定字段重新赋值
python
print(conn1.hgetall('user')) # 获取user中的所有数据
python
print(conn1.hkeys('user')) # 获取user中的所有字段名
print(conn1.hvals('user')) # 获取user中的所有字段值
print(conn1.hexists('user', 'name')) # 判断user中的name字段是否存在
python
print(conn1.hlen('user')) # 获取字段的长度(键值对的数量)
print(conn1.hincrby('user', 'age', 10)) # 累加器 加10
python
conn1.hsetnx('user', 'name', 'jack') # 不存在的话就重新赋值 存在的话就什么也不做 不存在的话返回1
模拟MySQL记录
pythondata = [ {"id": 1, "name": "jelee1", "age": 18}, {"id": 2, "name": "jelee2", "age": 18}, {"id": 3, "name": "jelee3", "age": 18}, {"id": 4, "name": "jelee4", "age": 18} ] for item in data: conn1.hset(f'user:{item["id"]}', mapping=item) print(conn1.hgetall(f'user:{item["id"]}'))
列表操作
注意redis中的范围和python中的切片不同
redis中的范围都是闭区间
而python切片中是左闭右开
python
l1 = ['a', 'b', 'c']
conn1.lpush('l1', *l1) # 从左往右插入元素
print(conn1.lrange('l1', 0, -1)) # ['c', 'b', 'a']
conn1.lpushx('l1', 'b') # 如果l1存在则插入元素,如果l1不存在那就什么都不做
python
conn1.linsert('l1','before','a','v') # 在a元素前面插入v元素
conn1.linsert('l1','after','a','v') # 在a元素后面插入v元素
python
conn1.rpush('l1', 'a') # 在列表的尾部增加元素a 可以写多个元素 就算添加整形也会自动的转换成str类型
conn1.rpushx('l1', 'a') # 如果l1存在的话就把元素a追加到末尾 如果不存在就什么都不做
python
conn1.lindex('l1', 4) # 根据索引的下标返回对应的元素
conn1.lrange('l1', 1, 3) # 返回l1中的索引位置1到3的元素
python
conn1.llen('l1') # 返回列表的长度
conn1.lpop('l1') # 抛出列表最左边的元素
conn1.rpop('l1') # 抛出列表最右边的元素
conn1.rpoplpush('l1', 'l2') # 把l1中的最末尾的元素拿出来从l2的开头插进去
conn1.lrem('l1', 2, 'a') # 从左到右删除两个a元素
conn1.ltrim('l1', 2, 4) # 保留索引2到4的元素,其余删除
conn1.delete('l1') # 删除列表l1
python
conn1.lset('l1', 0, 'w') # 把0索引位置的值设置为w
集合操作
集合自带去重功能
python
s1 = {'a', 'v', 'c', 1, 2, 3, 4}
conn1.sadd('s1', *s1) # 向集合中插入元素
print(conn1.smembers('s1')) # 获取集合中的元素
print(conn1.scard('s1')) # 返回集合中的元素个数
print(conn1.srandmember('s1')) # 随机返回集合中的一个元素
print(conn1.sismember('s1', 'a')) # 判断集合中的a元素是否存在
print(conn1.smove('s1', 's2', 'a')) # 把s1中的a元素移动到s2中 如果没有那个元素 则什么也不做
有序集合
从有序集合中取出东西一定是有序的
所以返回的索引范围内的东西是指排序后的索引范围内的
而不是原生的索引范围内的
python
data = {
"jack": 19,
"marry": 20,
"jelee": 21
}
conn1.zadd('z1', mapping=data) # 创建一个有序集合
print(conn1.zrange('z1', 0, -1, withscores=True)) # 让索引范围内的元素升序排序 带分数
print(conn1.zrevrange('z1', 0, -1, withscores=True)) # 同上 降序
print(conn1.zrank('z1', 'jack')) # 返回对应元素的索引下标
print(conn1.zrank('z1', 'jack')) # 返回成员的总数量
print(conn1.zrangebyscore('z1', '-inf', '+inf', withscores=True)) # 把固定分数范围内的升序排列
print(conn1.zrevrangebyscore('z1', '+inf', '-inf', withscores=True)) # 把固定分数范围内的降序排列
print(conn1.zcount('z1', 20, 21)) # 返回指定范围内的元素的个数
print(conn1.zscore('z1','jack')) # 有序集合中获取指定成员的分数
print(conn1.zadd('z1', mapping={'jack': 100})) # 修改指定成员的分数 可以同时修改多个 无则增
print(conn1.zincrby('z1', 10, 'jack')) # 为指定成员增加固定的分数 返回增加后的值
print(conn1.zremrangebyscore('z1', 20, 21)) # 删除指定分数范围内的成员
print(conn1.zremrangebyrank('z1', 0, 1)) # 删除指定索引范围内的成员
print(conn1.zrem('z1', *{'jack', 'jelee'})) # 删除指定的成员名称对应的成员
print(conn1.delete('z1')) # 删除整个有序集合
Django中使用redis
Django中使用redis与纯python中使用redis用法差不多
django-redis模块实际上就是对redis-py模块的二次封装
用法大差不差
-
下载
bashpip install django-redis -
配置session(在settings.py中)
可以在源码中看到

在原生的Django中
session中的数据默认存储在
django_session表中python# session配置 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 设置session保存的位置对应的缓存配置项 SESSION_CACHE_ALIAS = 'session' # 过期时间 SESSION_COOKIE_AGE = 60 * 60 * 24 * 7通过配置SESSION_ENGINE
将session保存在redis数据库中
速度会有质的变化
session的用法不变
-
配置cache
pythonCACHES = { # 默认缓存 "default": { "BACKEND": "django_redis.cache.RedisCache", # 项目上线时,需要调整这里的路径 # "LOCATION": "redis://:密码@IP地址:端口/库编号", "LOCATION": "redis://:@127.0.0.1:6379/0", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 10} } }, # 提供给admin运营站点的session存储 "session": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://:@127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 10}, } }, # 提供存储短信验证码 "sms_code":{ "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://:@127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "CONNECTION_POOL_KWARGS": {"max_connections": 10}, } } }-
连接池配置
python# cache缓存 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://:@127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", # 连接池的配置都在CONNECTION_POOL_KWARGS对应的字典中 "CONNECTION_POOL_KWARGS": { "max_connections": 100, "encoding": "utf-8", "decode_responses": True, "timeout": 5, } } } }
-
-
示例使用
存储验证码设置60秒过期
pythonfrom django_redis import get_redis_connection # 先通过别名拿到Redis连接对象,get_redis_connection(alias) # alias:可以是Django的settings中CACHES中配置的多个别名 # conn = get_redis_connection() # 不传值,默认使用的是default conn = get_redis_connection('sms_code') # 最基本的用法,获取连接对象,并设置值,同时指定过期时间,单位: 秒 conn.set('手机号', '8842', ex=10) # 在需要的地方在通过连接对象获取值 print(conn.get("手机号"))