Redis的基础与django使用redis

     阅读:37

一、Redis的简介和安装

1.1 Redis简介

Redis是一个用c语言开发的非关系型(NoSQL)数据库,它将数据以key-value的形式存储在内存中,性能高并且开源、免费。

redis的应用场景:

  • 缓存系统;
  • 计数器:网站访问量、转发量、评论数……;
  • 消息队列(发布订阅,阻塞队列);
  • 排行榜(有序集合);
  • 实时系统:垃圾邮件处理系统(布隆过滤器);
  • ……

redis的其他特点:

  • 支持数据持久化,可以将数据保存到磁盘中,实现永久存储;
  • value支持多种数据类型:字符串Strings、链表Lists、集合Sets、有序集合Sorted Sets、哈希Hashes等等。
  • 支持主从模式,可以配置集群,能支撑起大型的项目。
  • ……

1.2 安装Redis

  • Ubuntu 下安装:

    在终端中执行:

    sudo add-apt-repository ppa:redislabs/redis
    sudo apt-get update
    sudo apt-get install redis
    
  • windows 下安装:

    官网下载安装包,直接安装即可。

  • 测试是否安装成功:

    redis-cli ping
    # 输出:PONG,则表示安装成功
    

    这是redis官方提供的简易redis客户端,可以执行redis的各种命令,要退出,输入:quit后回车。

    指定ip、端口和密码:

     redis-cli -h host -p port -a password
    

1.3 启动和关闭 Redis-server

三种启动方式:

  • 默认启动方式:

    redis-server
    
  • 指定参数启动:

    redis-server --port 6380  # 指定端口为6380
    

    redis 的默认端口为6379。

  • 指定配置文件启动:

    redis-server redis.conf    # 文件需要自行创建,文件名随意
    

    常用配置:

    # 是否以守护进程方式启动
    daemonize yes
    # 端口号
    port 6379
    # ip地址,默认的 127.0.0.1 不支持远程连接
    bind 0.0.0.0  
    # 工作目录
    dir "路径"
    # 日志位置
    logfile "路径"
    # 关闭保护模式
    protected-mode no
    # 设置密码
    requirepass 123456
    # 最大内存使用量,默认为0,表示无限制
    maxmemory 128M
    

关闭 redis-server:

redis-cli shutdown

二、python操作redis

使用python操作redis,可以安装一个第三方库,名字就叫做redis。它提供了一些接口,能够使我们更加方便的操作redis。

安装:

pip install redis

2.1 普通连接

python操作redis,需要通过一个redis连接对象来进行:

import redis

# 创建连接对象
r = redis.Redis(host='localhost', port=6379, db=0)

# 执行具体操作
r.set('foo', 'bar')  # 给key设置value
print(r.get('foo'))  # 根据key获取value
# 打印:b'bar'

默认情况下,Python 3中的所有响应都以字节的形式返回。默认的编码是utf-8,但这可以通过指定redis的encoding参数来定制。

2.2 连接池

连接池是一种提高性能的技术手段,它提前创建好一些连接并保存在池中。当有请求时,就从连接池中直接取出一个连接,用完再放回去。这样就免去了创建连接和销毁连接的过程。

import redis
# 创建连接池
pool = redis.ConnectionPool(host='localhost', port=6379,
                         db=0, max_connections=1000)
# 从连接池获取连接对象
r = redis.Redis(connection_pool=pool)

# 像普通连接一样使用即可

max_connections指的是请求池中的最大连接数,默认是 2 31 2^{31} 231

2.3 redis库的操作

redis库中的方法以及方法的参数与redis-cli的命令以及参数是一致的,方法名称对应命令,方法参数对应命令参数。因此,学会了redis-cli的命令,就学会了redis库的使用。

三、Redis基本操作

我们现在通过redis-cli 来学习一下redis的具体操作,它会提示参数,十分好用。

3.1 redis 通用命令

  • 通过 redis-cli 连接 redis-server:

    redis-cli [-p 端口 -h ip地址]    # 默认连接本地地址和6379端口
    
  • 如果设置了密码:

    redis-cli -a 密码
    

    也可以先正常连接,进入客户端后,输入auth回车,再输入密码,完成验证。

  • 退出 redis-cli:

    exit    # 或quit
    
  • 查看服务器详细信息 :

    info
    
  • 查看redis配置信息:

    config get *
    
  • 修改redis配置:

    config set requirepass 密码
    
  • 将所做的修改保存到配置文件:

    config rewrite
    
  • 查看所有连接到服务器的客户端信息:

    client list
    
  • 关闭客户端连接:

    client kill ip:端口
    
  • 清空所有数据库:

    flushall
    
  • 清空当前数据库:

    flushdb
    
  • 选择一个数据库:

    select 数字
    

    redis默认有16个数据库,编号0~15,默认的是第0个。

  • 实时监控服务器:

    monitor
    

    一般用于日志审计。

3.2 Key的操作

Redis的key是二进制安全的,这意味着我们可以使用任何二进制序列作为key,从像"foo"这样的字符串到JPEG文件的内容,甚至是空字符串。key的大小最大允许 512 MB。

  • 删除指定的key:

    DEL key1 key2 ...
    

    key被删除,value也就不复存在。

  • 检查指定的key是否存在:

    EXISTS key1 key2 ...
    

    存在几个,就返回几。

  • 查看数据库中key的总数:

    DBSIZE
    
  • 给key设置过期时间:

    EXPIRE key 秒数
    

    到达指定秒数后,该key就会被删除(key删除则value跟着一起消失)。

  • 查看剩余有效期:

    TTL key
    
  • 去除过期限制:

    PERSIST key
    
  • 返回符合给定模式(pattern)的所有key:

    KEYS A*  # 返回以A开头的key
    KEYS *   # 返回所有key
    
  • 查看key所存储的value的数据结构类型:

    type key
    
  • 重命名key:

    RENAME OLD_KEY_NAME NEW_KEY_NAME
    
  • 移动key到指定数据库:

    MOVE key db
    
  • 随机返回一个key:

    RANDOMKEY
    

3.3 Value的操作(常用类型)

3.3.1 字符串(Strings)类型

string 是 redis 最基本的类型,它可以包含任何数据。比如jpg图片或者序列化的对象,string 类型的值最大能存储 512MB。

  • 为指定的key设置value:

    SET key value [EX 参数] [NX|XX]
    
    • EX:过期时间,单位为秒;
    • NX:仅当该key不存在时,设置该key;
    • XX:仅当该key存在时,设置该key;
  • 获取指定key的value:

    GET key
    
  • 为多个key设置多个value:

    MSET key1 value1 key2 value2 ...
    
  • 获取所有给定key的值:

    MGET key1 key2 ...
    
  • 给key设置一个新的value并返回旧的value:

    GETSET key value  # 返回旧value
    
  • 给指定key的value切片,然后返回子字符串:

    GETRANGE key 起始索引 结束索引
    
    SET key1 hello,world
    GETRANGE key1 0 4  # 返回"hello"
    GETRANGE key1 -5 -1  # 返回"world"
    
  • 重写指定位置后面的value值:

    SETRANGE key 起始位置 value
    
    SET key1 hello,world
    SETRANGE key1 4 ,redis
    GET key1  # 返回"hell,redis"
    
  • 将key的整数值增加1:

    INCR key
    

    key中的value不是整数或者字面值不是整数,则会报错

  • 将key的整数值减少1:

    DECR key
    
  • 在value后面追加内容:

    APPEND key 追加的内容
    

3.3.2 哈希(Hashes)类型

redis的哈希类型是一个==“字段-值(field-value)”的集合==,类似于python中的字典。

  • 设置key的内容:

    HSET key field1 value1 [field2 value2 ...]
    
  • 获取key中指定字段的内容:

    HGET key field
    
  • 获取key中多个字段的值:

    HMGET key field1 [field2 ...]
    
  • 删除一个或多个字段:

    HDEL key field1 [field2 ...]
    
  • 查看key中,指定字段是否存在:

    HEXIETS key field
    
  • 获取指定key的所有字段和值(慎用):

    HGETALL key
    
  • 迭代获取key中的所有字段和值(建议以此替代HGETALL):

    HSCAN key cursor  # 开始一次迭代时,cursor传入0
    

    返回值除了字段和值外,还有本次迭代后的游标(cursor)位置,我们需要在下一次调用中使用它作为游标参数。

    而在开始一次全新的迭代时,游标的值应该传入0;

  • 获取指定key中的所有字段:

    HKEYS key
    
  • 获取指定key中的所有值:

    HVALS key
    
  • 获取字段的数量:

    HLEN key
    
  • 让字段的整数值加上一个增量:

    HINCRBY key field 增量
    

    这个增量可以是负数,以此实现减少的效果。

3.3.3 链表(Lists)类型

Redis链表是根据插入顺序排序的字符串元素集合,它们是基于链表数据结构实现的。

  • 在链表前面(左面)添加一个或多个元素:

    LPUSH key element1 [element2 ...]
    
  • 在链表后面(右面)添加一个或多个元素:

    RPUSH key element1 [element2 ...]
    
  • 获取链表长度:

    LLEN key
    
  • 将元素插入链表的指定元素之前或之后:

    LINSERT key BEFORE|AFTER 指定元素 要插入的元素
    
  • 在指定位置放入元素:

    LSET key 索引 element
    

    新的元素会覆盖原来的元素。

  • 从链表移除元素:

    LREM key count element
    
    • count > 0:表示从左往右移除count个与指定元素相等的元素;

    • count < 0:表示从右往左移除count个与指定元素相等的元素;

    • count = 0:表示移除所有与指定元素相等的元素;

  • 移除并返回链表中的第一个或前几个元素:

    LPOP key [count]
    
  • 移除并返回链表中的最后一个或后几个元素:

    RPOP key [count]
    
  • 根据索引获取指定元素:

    LINDEX key index
    
  • 删除并返回链表中的第一个元素,没有可用的元素就阻塞,直到有可用的元素:

    BLPOP key [key ...] timeout
    

    timeout指阻塞的最大秒数,是一个双精度值,设置为0表示无时间限制。

3.3.4 集合(Sets)类型

Redis的Sets是唯一的无序的字符串元素的集合,不能出现重复的数据。

  • 向集合添加一个或多个成员:

    SADD key member [memebr1 ...]
    
  • 获取一个集合中成员的数量:

    SCARD key
    
  • 返回集合中的所有成员:

    SMEMBERS key
    
  • 判断给定的值是否是集合的成员:

    SISMEMBER key member
    
  • 返回多个集合的交集:

    SINTER key [key ...]
    
  • 返回多个集合的并集:

    SUNION key [key ...]
    
  • 返回一个集合与给定集合的差集的元素:

    SDIFF key1 key2
    
  • 从集合中随机返回一个成员并从集合中移除:

    SPOP key [count]
    

    count用来设置随机返回的数量,不写就是1个。

  • 从集合中删除指定成员:

    SREM key member [member ...]
    

3.4.5 有序集合(Sorted Sets)类型

Redis的Sorted Sets类似于上面的Sets,但每个字符串元素都与一个名为score的浮点数值相关联。与Sets不同,Sorted Sets中的元素是按照它们的score从小到大排序,因此它可以检索一个范围内的元素(例如,获取前10个或下10个)。

  • 向有序集合添加一个或多个成员,如果已经存在,则更新其score:

    ZADD key [NX|XX] score member
    
    • NX:只添加新元素。不要更新已经存在的元素。
    • XX:只更新已经存在的元素。不要添加新元素。
  • 从有序集合中删除若干个元素:

    ZREM key member [member ……]
    
  • 获取成员的score:

    ASCORE key member
    
  • 增加成员的score值:

    ZINCRBY key 增量 member
    
  • 迭代有序集合中的元素:

    ZSCAN key 游标
    
  • 获取有序集合中的成员数:

    ZCARD key
    
  • 按照索引获取一个范围内的成员:

    ZRANGE key min max
    
  • 按照score获取一个范围内的成员:

    ZRANGEBYSCORE min max
    
  • 获取成员的索引(从0开始):

    ZRANK key member
    

更多redis 命令请参考官方文档:传送门

四、管道(Pipelining)

Redis是一个使用客户端-服务器模型的TCP服务器,也被称为请求/响应协议。也就是说,redis每次执行一个请求,需要经过以下步骤:

  1. 客户端向服务器发送一个查询,然后从套接字读取数据,通常以阻塞的方式获取服务器的响应。
  2. 服务器处理命令并将响应发送回客户端。

如果现在有一堆命令等待执行,发送完一个请求,等待响应再发送下一个请求……就会造成时间上的浪费。所以,我们希望能够一次就发送多条命令,以节省时间。而管道就能帮助我们实现这一需求。

通过管道可以在无需等待请求被响应的情况下,发送下一个请求。并且,通过管道还可以对事务进行部分支持(不支持回滚)。

使用方法(通过python的redis库):

import redis

conn = redis.Redis("127.0.0.1", 6379)
pipe = conn.pipeline(transaction=True)  # 参数代表使用事务

# 开启事务块
pipe.multi()
pipe.set('key', 'value') 
# ......
# 执行事务块
pipe.execute()

五、在django中使用redis

django是不支持redis作为缓存的,但我们可以使用上面的redis库,也可以使用专门的django-redis库添加支持。下面简单说一下django-redis的使用方法。

  • 安装django-redis:

    pip install django-redis
    
  • 在项目配置文件中,配置CACHES后端:

    CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
    }
    

    LOCATION支持三种参数:

    • 创建一个正常的TCP套接字连接:

      redis://[[username]:[password]]@localhost:6379/0

    • 创建一个SSL封装的TCP套接字连接:

      rediss://[[username]:[password]]@localhost:6379/0

    • 创建一个unix domain套接字连接:

      unix://[[username]:[password]]@/path/to/socket.sock?db=0

    如果有密码,在OPTIONS中设置"PASSWORD":"密码"

  • 使用方法有两种:

    • 使用django提供的接口:

      from django.core.cache import cache
      
      cache.set("key", value, timeout=30)
      cache.get("key", default="默认值")
      
    • 使用django-redis:

      from django-redis import get_redis_connection
      conn = get_redis_connection("default")
      conn.hgetall("key")
      

更加详细的说明,请参考官方文档:传送门