redis笔记(python、Django怎么配置使用redis)

常用指令(启动命令)

  • 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的值为20
  • hmget 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订阅fm1
  • subscribe fm1 fm2订阅fm1和fm2
  • subscribe 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对象的时候添加参数

python 复制代码
conn1 = 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记录

python 复制代码
data = [
    {"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模块的二次封装

用法大差不差

  • 下载

    bash 复制代码
    pip 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

    python 复制代码
    CACHES = {
        # 默认缓存
        "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秒过期

    python 复制代码
    from 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("手机号"))
相关推荐
梦帮科技2 小时前
第二十三篇:自然语言工作流生成:GPT-4集成实战
人工智能·python·机器学习·开源·gpt-3·极限编程
cnnews2 小时前
用OpenCV实现烟花动画
开发语言·python·opencv·pygame·cv2
love530love2 小时前
让 ComfyUI 官方 CLI 在 Windows CMD 里也能 Tab 补全 —— 实测与避坑记录
人工智能·windows·python·clink·comfy-cli·命令补全·clickcompletion
CodeCraft Studio2 小时前
国产化PDF处理控件Spire.PDF教程:在Java快速解析PDF文本、表格、图像和元数据
java·python·pdf·pdf解析·spire.pdf·元数据解析·java pdf解析
棒棒的皮皮2 小时前
【OpenCV】Python图像处理之形态学梯度运算
图像处理·python·opencv·计算机视觉
znhy_232 小时前
day43打卡
python
zore_c2 小时前
【数据结构】堆——超详解!!!(包含堆的实现)
c语言·开发语言·数据结构·经验分享·笔记·算法·链表
_codemonster2 小时前
python易混淆知识点(十五)迭代器
开发语言·windows·python
_Orch1d2 小时前
《网络攻击与防御》复习笔记
笔记·安全·php