Redis知识必备
一、Redis基础简介
Redis是一个高性能的NOSQL的key-value免费开源内存型数据库,支持多种数据结构,比如string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。Redis数据库常用来做缓存、数据库、消息代理,支持数据持久化存储和集群化,在很多项目中都能看到redis的身影。
二、Redis数据类型
上面我们有说道Redis支持以下五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
1、string(字符串)
string类型是Redis最基本的数据类型,值最大能存储512MB,普通的key/value存储都可以归为此类。redis操作实例如下:
redis 127.0.0.1:6379> SET stdudent "张三" //设置key键stdudent的值为张三 OK redis 127.0.0.1:6379> GET stdudent //获取key键值 "张三"
- 常用redis字符串命令
2、hash(哈希)
Redis hash是一个string类型的field(字段)和value(值)的映射表,特别适合用于存储对象,类似Python中的dict。每个hash可以存储232-1键值对(40多亿)。redis操作实例如下:
- 常用redis hash命令
3、list(列表)
列表是简单的字符串列表,根据插入顺序排序像Python列表一样,你可以在列表的头或尾添加元素。一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素redis操作实例如下:
redis 127.0.0.1:6379> LPUSH stdudents 张三 //将张三插入到列表students中 (integer) 1 redis 127.0.0.1:6379> LPUSH stdudents 李四 (integer) 2 redis 127.0.0.1:6379> LPUSH stdudents 王一 (integer) 3 redis 127.0.0.1:6379> LRANGE stdudents 0 4 //获取列表stdudents 0-4内的元素 1) "张三" 2) "李四" 3) "王一"
- 常用redis列表命令
4、set(集合)
Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是intset或者hashtable,集合中最大的成员数为232-1(4294967295, 每个集合可存储40多亿个成员)。redis操作实例如下:
redis 127.0.0.1:6379> SADD language python //将python插入集合language (integer) 1 redis 127.0.0.1:6379> SADD language java (integer) 1 redis 127.0.0.1:6379> SADD language c++ (integer) 1 redis 127.0.0.1:6379> SADD language c++ //由于集合language已经有元素c++,再次添加失败 (integer) 0 redis 127.0.0.1:6379> SMEMBERS language //列出集合language所有元素 1) "python" 2) "java" 3) "c++"
- 常用redis集合命令
5、zset(sorted set:有序集合)
有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。redis操作实例如下:
redis 127.0.0.1:6379> ZADD language 1 python //将python插入集合language并将分数设置为1 (integer) 1 redis 127.0.0.1:6379> ZADD language 2 java (integer) 1 redis 127.0.0.1:6379> ZADD language 3 c++ (integer) 1 redis 127.0.0.1:6379> ZADD language 4 c++ //将c++插入集合language并将分数更新为4 (integer) 0 redis 127.0.0.1:6379> ZADD language 5 c++ (integer) 0 redis 127.0.0.1:6379> ZRANGE language 0 10 WITHSCORES //列出集合language所有元素及其分数,由于c++元素更新了分数,所以显示最新分数 1) "python" 2) "1" 3) "java" 4) "2" 5) "c++" 6) "5"
- 常用redis有序集合命令
三、Redis事务
1、基础介绍
Redis事务本质上是一组命令的集合,支持一次性执行多个任务。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中,具有排他性。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务(multi)
- 命令入队
- 执行事务(exec)
redis操作实例如下:
(1)mutil开始一个事务,设置language1、language2、language3值操作命令,exec执行操作命令
redis 127.0.0.1:6379> multi OK redis 127.0.0.1:6379> set language1 python QUEUED redis 127.0.0.1:6379> set language2 java QUEUED redis 127.0.0.1:6379> set language3 c++ QUEUED redis 127.0.0.1:6379> exec 1) OK 2) OK 3) OK
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。就这个示例来说,如果set language2 java失败,上一句执行的set language1 python会生效,下一句set language3 c++也会继续执行。
(2)mutil开始一个事务,设置language值,discard取消事务,language设置失败
redis 127.0.0.1:6379> multi OK redis 127.0.0.1:6379> set language python QUEUED redis 127.0.0.1:6379> discard 1) OK redis 127.0.0.1:6379> get language redis 127.0.0.1:6379>
四、redis内存
redis之所以快是因为redis是个内存型的数据库,读写数据在内存中,如果数据过大,内存满了怎么办呢?有以下几种方案:
- 物理处理,加内存
- 将单点redis优化为集群,在多台服务器上部署redis,搭建集群,这其实也是一种物理加内存的方法
- 启用redis内存淘汰机制(面试可能会问到的点),从根本上减少数据存储
五、Redis应用
1、应用场景
- 缓存系统
redis是基于内存型的数据存储系统,读写性能优秀,读写qps能达到10w左右,使用redis可以提高系统负载能力和响应速度。这是在项目中经常可以看到的应用场景。 - 消息系统
redis的Pub/Sub(发布及订阅)功能用作简单的消息系统,比如在celery中就把redis当做消息队列中间件。 - 分布式场景
redis支持数据持久化和集群化,支持扩容以及高可用,可以满足分布式场景需求。 - 秒杀
redis数据持久化和并发能力可以满足秒杀活动高qps需求,活动结束后将数据落地。
2、redis在Python中的应用
缓存某接口token值,五秒钟后过期
import time import redis # 导入redis模块,通过python操作redis 也可以直接在redis主机的服务端操作缓存数据库 # 连接redis host = '127.0.0.1' port = 6379 pool = redis.ConnectionPool(host=host, port=port, decode_responses=True) r = redis.Redis(connection_pool=pool) # 设置token值,5分钟后过期 # key为token,值为adfegcyed5t,ex过期时间,单位为秒。另外px也可设置过期时间,单位为毫秒 r.set('token', 'adfegcyed5t', ex=5) # r.set('token', 'adfegcyed5t', px=50) token_value = r.get('token') print(token_value) time.sleep(5) print(token_value)
运行结果 adfegcyed5t None # 五分钟后key token的值已经过期