Redis 知识点总结
Redis 是 Java 程序员在面试过程中绕不开的知识点,我们这篇文章对于 Redis 的知识点做一个总结。
什么是 Redis
Redis 是使用 C 语言写成的,高性能的基于内存的 key-value 型数据库。Redis 支持多种数据类型(String,list,set,zset 和 hash),对于 key-value 的操作都是原子性的。Redis 会周期性将内存中的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。
Redis 于 Memcached 的区别于比较
- Memcached 只支持简单的数据类型,String。Redis 除了支持 String 之外,还支持 list,set,zset 和 hash 等数据结构。
- Redis 支持数据备份,即主从模式的数据备份。
- Redis 支持数据持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载。而 Memcached 数据不支持持久化。
- Redis 的速度比 Memcached 快很多。
- Memcached 是多线程的非阻塞 IO 复用的网络模型,Redis 使用但线程的 IO 复用模型。
Redis 的好处
- 速度快,数据在内存中,类似于 HashMap ,HashMap 的优势就是查找和操作的时间复杂度都是 O(1)。
- 支持丰富的数据类型,支持 String,list,set,sorted set,hash。
- 支持事务,后面会详细介绍。
- 丰富的特性,可用于缓存,消息,按 key 设置过期时间,过期后会自动删除。
- 支持数据持久化,不丢失数据。AOF(保存命令),RDB(文件快照)。
Redis 常见数据结构使用场景
String
常用命令:set,get,decr,incr,mget 等。
适合场景:
- 缓存:保存查询结果。
- 计数:redis 内部对 int 做了优化,在做加减时开销很小。
- 共享数据:用作分布式架构信息在多个节点之间共享。
- 限速:当短信验证码计时这类需求时,用 redis 也非常好。对键设置一个过期时间,当查询不到键时,就可以再次发送短信了。
Hash
常用命令:hget,hset,hgetall。
适合场景:
Hash 是一个 String 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。比如用哈希来存储用户信息,商品信息等等。
List
常用命令:lpush,rpush,lpop,rpop,lrange 等等。
list 就是链表,Redis list 的应用场景非常多,也是 Redis 最重要的数据结构之一,比如微博的关注列表,粉丝列表,最新消息排行等功能都可以用 Redis 的 list 结构来实现。
适用场景:
消息队列(不推荐)。
分页,列表是有序的,可以利用范围来获取元素。
Redis list 的实现为一个双向链表,既可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
Set
常用命令:sadd,spop,smembers,sunion 等。
set 对外提供的功能与 list 类似,也是一个列表的功能,特殊之处在于 set 是可以自动排重的。当你需要存储一个列表数据,又不希望出现重复,set 是一个很好的选择,并且 set 提供了判断某个成员是否存在的接口。
在微博应用中,可以将一个用户所有的关注人存在一个集合中,将所有粉丝存在一个集合。Redis 可以轻松实现共同关注,共同喜好,二度好友等功能(交集,并集,差集)。
使用场景:
- 抽奖
Sorted Set
常用命令:zadd,zrange,zrem,zcard 等。
与 set 相比,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列。
在直播系统中,实时排行信息包含直播间的在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。
适用场景:
- 用户赞。
- 排名。
几个问题
MySQL 里面有 2000w 数据,Redis 中只有 20w 的数据,如何保证 Redis 中的都是热点数据?
Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。Redis 提供了 6 种数据淘汰策略:
- volatile-lru:从设置过期时间的数据集中挑选最近最少使用的数据淘汰。
- volatile-ttl:从已设置过期时间的数据集中挑选要过期的数据淘汰。
- volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
- allkeys-lru:从所有数据集中挑选最近最少使用的数据淘汰。
- allkeys-random:从所有数据集中任意选择数据淘汰。
- no-enviction:禁止数据驱逐。
Redis 的并发竞争问题如何解决?
Redis 为单进程单线程模式,采用队列模型将并发访问变为串行执行。Redis 本身并没有锁的概念,Redis 对于多个客户端连接并不存在竞争。竞争问题存在与客户端自身。在客户端的角度,为了保证每个客户端间正常有序与 Redis 进行通信,对连接进行池化,同时对客户端读写加锁。