Redis的应用
1.什么是Redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,数据是保存在内存里面的. 官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
- 字符串类型 string(最常用)
- 散列类型 hash
- 列表类型 list
- 集合类型 set
- 有序集合类型 sortedset
2.redis的应用场景
- 缓存(数据查询、短连接、新闻内容、商品内容等等)
- 任务队列。(秒杀、抢购、12306等等)
- 数据过期处理(可以精确到毫秒, 短信验证码)
- 分布式集群架构中的session分离 session 服务器里面
- 聊天室的在线好友列表
- 应用排行榜
- 网站访问统计
3.小结
Redis: 由C语言编写的一种NoSQL, 以key-value存在, 数据保存在内存里面 性能比较高
Redis应用场景:
- 缓存(eg: 电商项目里面首页的轮播图)
- 队列(eg: 秒杀)
- 数据过期处理(eg: 短信验证码...)
- 分布式集群架构中的session分离
4.Redis的数据类型
redis中存储的数据是以key-value的形式存在的.其中value支持5种数据类型 .在日常开发中主要使用比较多的有字符串、哈希、字符串列表、字符串集合四种类型,其中最为常用的是字符串类型。
字符串(String)
哈希(hash) 类似HashMap
字符串列表(list)
字符串集合(set) 类似HashSet
有序的字符串集合(sorted-set或者叫zset)
1.字符串(String)
string是redis最基本的类型,用的也是最多的,一个key对应一个value。 一个键最大能存储512MB.
命令 | 描述 |
---|---|
SET key value(重点) | 设置指定 key 的值 |
GET key(重点) | 获取指定 key 的值 |
DEL key | 删除key |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
SETEX key seconds value(重点) | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
SETNX key value | 只有在 key 不存在时设置 key 的值。 |
INCR key(重点) | 将 key 中储存的数字值增一。 |
INCRBY key increment | 将 key 所储存的值加上给定的增量值(increment) 。 |
DECR key | 将 key 中储存的数字值减一。 |
DECRBY key decrement | key 所储存的值减去给定的减量值(decrement) 。 |
1.1使用string的问题
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下: 保存、更新: User对象 ==> json(string) ==>redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题
2.哈希(Hash)
Redis中hash 是一个键值对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis存储hash可以看成是String key 和String value的map容器. 也就是说把值看成map集合.
它它特别适合存储对象相比较而言,将一个对象类型存储在Hash类型里要比存储在String类型里占用更少的内存空间并方便存取整个对象
命令 | 命令描述 |
---|---|
hset key filed value | 将哈希表 key 中的字段 field 的值设为 value |
hmset key field1 value1 [field2 value2]...(重点) | 同时将多个 field-value (字段-值)对设置到哈希表 key 中 |
hget key filed | 获取存储在哈希表中指定字段的值 |
hmget key filed1 filed2 (重点) | 获取多个给定字段的值 |
hdel key filed1 [filed2] (重点) | 删除一个或多个哈希表字段 |
hlen key | 获取哈希表中字段的数量 |
del key | 删除整个hash(对象) |
HGETALL key (重点) | 获取在哈希表中指定 key 的所有字段和值 |
HKEYS key | 获取所有哈希表中的字段 |
HVALS key | 获取哈希表中所有值 |
2.1小结
- Hash 是键值对存在的 类似Java里面的HashMap
- 特别适合存对象, 方便操作对象里面的某一个字段
3.列表(List)
3.1List类型
ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要涉及到位移操作,所以比较慢。
LinkedList使用双向链表方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快。然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。
3.2概述
列表类型(list)可以存储一个有序的字符串列表(链表)
,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
3.3应用场景
如好友列表,粉丝列表,消息队列,最新消息排行等。
rpush方法就相当于将消息放入到队列中,lpop/rpop就相当于从队列中拿去消息进行消费
3.4常见命令
命令 | 命令描述 |
---|---|
lpush key value1 value2...(重点) | 将一个或多个值插入到列表头部(左边) |
rpush key value1 value2...(重点) | 在列表中添加一个或多个值(右边) |
lpop key(重点) | 左边弹出一个 相当于移除第一个 |
rpop key(重点) | 右边弹出一个 相当于移除最后一个 |
llen key | 返回指定key所对应的list中元素个数 |
LINDEX key index | 通过索引获取列表中的元素 |
LINSERT key BEFORE| AFTER pivot value | 在列表的元素前或者后插入元素 |
3.5小结
1.List是一个字符串链表,left、right都可以插入添加;
2. 如果key不存在,创建新的链表;
如果键已存在,新增内容;
如果值全移除,对应的键也就消失了。
链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就一般.
4.集合(Set)
4.1概述
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的时间复杂度都是O(1)。集合中最大的成员数为 2的32次方 -1 (4294967295, 每个集合可存储40多亿个成员)。
Redis还提供了多个集合之间的交集、并集、差集的运算
特点:无序+唯一
4.2应用场景
投票记录
共同好友、共同兴趣、分类标签
4.3.常见命令
命令 | 命令描述 |
---|---|
sadd key member1 [member2] (重点) | 向集合添加一个或多个成员 |
srem key member1 [member2] | 移除一个成员或者多个成员 |
smembers key | 返回集合中的所有成员,查看所有 |
SCARD key | 获取集合的成员数 |
SPOP key | 移除并返回集合中的一个随机元素 |
SDIFF key1 [key2] (重点) | 返回给定所有集合的差集(key1有key2没有的) |
SUNION key1 [key2] (重点) | 返回所有给定集合的并集(两个合并返回,重复的只算一个) |
SINTER key1 [key2] (重点) | 返回给定所有集合的交集(返回两个重复的部分) |
4.4应用举例
共同好友
- A的好友
- B的好友
- A和B的共同好友
4.5小结
- Redis里面的Set 无效+唯一的, 类似Java里面的HashSet
- 应用
- 投票的记录
- 求差值
5.有序集合(sorted set)zset
5.1概述
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
特点: 有序(根据分数排序)+唯一
5.2应用场景
排行榜:例如视频网站需要对用户上传的视频做排行榜.
5.3常见命令
命令 | 命令描述 |
---|---|
ZADD key score member [score member ...](重点) | 增加元素 |
ZSCORE key member | 获取元素的分数 |
ZREM key member [member ...] | 删除元素 |
ZCARD key | 获得集合中元素的数量 |
ZRANGE key start stop[WITHSCORES] (重点) | 获得排名在某个范围的元素列表 |
ZREVRANGE key start stop (重点) | 按照分数从高到低排序 |
5.4小结
- ZSet: 有序的Set
- 特点: 有序+唯一的
- 应用场景: 排行榜
Redis通用的操作
1.通用操作
-
keys *: 查询所有的key
-
exists key:判断是否有指定的key 若有返回1,否则返回0
-
expire key 秒数:设置这个key在缓存中的存活时间 (重要)
-
ttl key:展示指定key的剩余时间
若返回值为 -1:永不过期
若返回值为 -2:已过期或者不存在
-
del key:删除指定key (重要)
-
rename key 新key:重命名
-
type key:判断一个key的类型
-
ping :测试连接是否连接
2.多数据库性
redis默认是16个数据库, 编号是从0~15. 【默认是0号库】
- select index:切换库
- move key index: 把key移动到几号库(index是库的编号)
- flushdb:清空当前数据库
- flushall:清空当前实例下所有的数据库
3.小结
- exists key 判断是否有这个key
- expire key 秒数 设置这个key在缓存中的存活时间
- ttl key 展示指定key的剩余时间
- select index 切换库
Redis的持久化【面试】
1.目标
Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘(文件)中,这一过程就是持久化。
Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。
2.路径
- RDB持久化机制
- AOF持久化机制
- 两种持久化机制比较
3.1RDB持久化机制
3.1.1概述
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。 这种方式是默认已经开启了,不需要配置.
3.1.2 RDB持久化机制的配置
- 在redis.windows.conf配置文件中有如下配置:
其中,上面配置的是RDB方式数据持久化时机:
关键字 | 时间(秒) | key修改数量 | 解释 |
---|---|---|---|
save | 900 | 1 | 每900秒(15分钟)至少有1个key发生变化,则dump内存快照 |
save | 300 | 10 | 每300秒(5分钟)至少有10个key发生变化,则dump内存快照 |
save | 60 | 10000 | 每60秒(1分钟)至少有10000个key发生变化,则dump内存快照 |
3.2 AOF持久化机制
3.2.1概述
AOF持久化机制会将每一个收到的写命令都通过write函数追加到文件中,默认的文件名是appendonly.aof。 这种方式默认是没有开启的,要使用时候需要配置.
3.2.2AOF持久化机制配置
3.2.2.1开启配置
- 在redis.windows.conf配置文件中有如下配置:
将appendonly修改为yes, 但是启动redis的时候需要指定该文件,也就是意味着不能直接点击了, 需要输入命令启动:
redis-server.exe redis.windows.conf
开启aof持久化机制后,默认会在目录下产生一个appendonly.aof文件
3.2.2.2配置详解
- 上述配置为aof持久化的时机,解释如下:(在redis.windows.conf配置)
| 关键字 | 持久化时机 | 解释 |
| ----------- | ---------- | ------------------------------ |
| appendfsync | always | 每执行一次更新命令,持久化一次 |
| appendfsync | everysec | 每秒钟持久化一次 |
| appendfsync | no | 不持久化 |
4,小结
4.1RDB
优点
- RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快(因为其文件要比AOF的小)
- RDB的性能要比AOF更好
缺点
- RDB的持久化不够及时(一定时间间隔),可能会存在数据丢失
- RDB持久化时如果文件过大可能会造成服务器的阻塞,停止客户端请求
4.2AOF
优点
- AOF的持久性更加的耐久(可以每秒 或 每次操作保存一次)
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。
- AOF是增量操作
缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB.
4.3选择
- 如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失,选择RDB 持久化。
- 如果对数据的完整性要求比较高, 选择AOF