文章目录
一、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每次执行一个请求,需要经过以下步骤:
- 客户端向服务器发送一个查询,然后从套接字读取数据,通常以阻塞的方式获取服务器的响应。
- 服务器处理命令并将响应发送回客户端。
如果现在有一堆命令等待执行,发送完一个请求,等待响应再发送下一个请求……就会造成时间上的浪费。所以,我们希望能够一次就发送多条命令,以节省时间。而管道就能帮助我们实现这一需求。
通过管道可以在无需等待请求被响应的情况下,发送下一个请求。并且,通过管道还可以对事务进行部分支持(不支持回滚)。
使用方法(通过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")
-
更加详细的说明,请参考官方文档:传送门