目录
[1. String](#1. String)
[2. List](#2. List)
[3. Hash](#3. Hash)
[4. Set](#4. Set)
[5. Sorted Set](#5. Sorted Set)
一、简单介绍Redis
Redis就是一个使用C语言开发的数据库,数据存在内存中,Redis 除了做缓存之外,Redis 也经常用来做分布式锁,甚至是消息队列。
二、缓存数据处理流程

-
如果用户请求的数据在缓存中就直接返回。
-
缓存中不存在的话就看数据库中是否存在。
-
数据库中存在的话就更新缓存中的数据。
-
数据库中不存在的话就返回空数据。
三、为什么用Redis/为什么用缓存
-
提升用户体验
-
同成本应对更多用户

四、Redis常见的数据结构
1. String
String 数据结构是简单的 key-value 类型。虽然 Redis 是用 C 语言写的,但是 Redis 并没有使用 C 的字符串表示,而是自己构建了一种简单动态字符串(simple dynamic string,SDS)。不光可以保存文本数据还可以保存二进制数据,并且获取字符串长度复杂度为 O(1)(C 字符串O(N))。
**应用场景:**一般常用在需要计数的场景,比如用户的访问次数、热点文章的点赞转发数量等等。
2. List
Redis 的 List 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。
**应用场景:**发布与订阅或者说消息队列、慢查询。
3. Hash
Hash 类似于 JDK1.8 前的 HashMap,内部实现也差不多(数组 + 链表)。不过,Redis 的 hash 做了更多优化。
应用场景:
4. Set
Set 类似于 Java 中的 HashSet 。Redis 中的 Set 类型是一种无序集合,集合中的元素没有先后顺序。
**应用场景:**需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景。
5. Sorted Set
和 Set 相比,Sorted Set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。
**应用场景:**需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。
五、Redis没有使用多线程?
Redis是单线程模型,在4.0之后的版本加入了对多线程的支持。但在6.0之前主要还是单线程处理。6.0之前为什么不使用多线程?原因如下:
-
单线程编程容易并且更容易维护;
-
Redis 的性能瓶颈不再 CPU ,主要在内存和网络;
-
多线程就会存在死锁、线程上下文切换等问题,甚至会影响性能。
Redis6.0 引入多线程主要是为了提高网络 IO 读写性能。
六、过期数据的删除策略
- **惰性删除:**只会在取出key的时候才对数据进行过期检查。这样对CPU最友好,但是可能会造成太多过期 key 没有被删除。
- **定期删除:**每隔一段时间抽取一批 key 执行删除过期key操作。并且,Redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。
定期删除对内存更加友好,惰性删除对CPU更加友好。所以,Redis采用的是定期删除+惰性删除。
七、内存淘汰机制
Redis提供6种淘汰策略:
-
**volatile-lru(least recently used):**从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
-
**volatile-ttl:**从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
-
**volatile-random:**从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
-
**allkeys-lru(least recently used):**当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
-
**allkeys-random:**从数据集(server.db[i].dict)中任意选择数据淘汰
-
**no-eviction:**禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!
4.0版本后增加两种:
-
**volatile-lfu(least frequently used):**从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰
-
**allkeys-lfu(least frequently used):**当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key