内存策略
1. 内存淘汰有哪些,分别适用于哪些场景
Redis 过期策略是:定期删除+惰性删除。
- 消极方法(passive way),在主键被访问时如果发现它已经失效,那么就删除它。
- 主动方法(active way),定期从设置了失效时间的主键中选择一部分失效的主键删除。
2. 有哪些删除失效key的方法
noeviction
- 当内存使用达到阈值的时候,所有引起申请内存的命令会报错。这是 Redis 默认的策略。allkeys-lru
- 在主键空间中,优先移除最近未使用的 key。allkeys-random
- 在主键空间中,随机移除某个 key。volatile-lru
- 在设置了过期时间的键空间中,优先移除最近未使用的 key。volatile-random
- 在设置了过期时间的键空间中,随机移除某个 key。volatile-ttl
- 在设置了过期时间的键空间中,具有更早过期时间的 key 优先移除。
3. 如何选择淘汰策略
- 如果**数据呈现幂等分布(存在热点数据,部分数据访问频率高,部分数据访问频率低),则使用
allkeys-lru
**。 - 如果**数据呈现平等分布(数据访问频率大致相同),则使用
allkeys-random
**。 - 如果希望**使用不同的 TTL 值向 Redis 提示哪些 key 更适合被淘汰,请使用
volatile-ttl
**。 volatile-lru
和volatile-random
适合既应用于缓存和又应用于持久化存储的场景,然而我们也可以通过使用两个 Redis 实例来达到相同的效果。- 将 key 设置过期时间实际上会消耗更多的内存,因此建议使用
allkeys-lru
策略从而更有效率的使用内存。
4. 设计一个LRU算法
可以继承 LinkedHashMap,并覆写 removeEldestEntry 方法来实现一个最简单的 LRUCache
内存淘汰要点
- 最大缓存 - Redis 允许通过
maxmemory
参数来设置内存最大值。 - 失效时间 - 作为一种定期清理无效数据的重要机制,在 Redis 提供的诸多命令中,
EXPIRE
、EXPIREAT
、PEXPIRE
、PEXPIREAT
以及SETEX
和PSETEX
均可以用来设置一条键值对的失效时间。而一条键值对一旦被关联了失效时间就会在到期后自动删除(或者说变得无法访问更为准确)。 - 淘汰策略 - 随着不断的向 Redis 中保存数据,当内存剩余空间无法满足添加的数据时,Redis 内就会施行数据淘汰策略,清除一部分内容然后保证新的数据可以保存到内存中。内存淘汰机制是为了更好的使用内存,用一定得 miss 来换取内存的利用率,保证 Redis 缓存中保存的都是热点数据。
- 非精准的 LRU - 实际上 Redis 实现的 LRU 并不是可靠的 LRU,也就是名义上我们使用 LRU 算法淘汰键,但是实际上被淘汰的键并不一定是真正的最久没用的。
持久化
不同持久化方式的特性和原理是什么?
Redis 会周期性生成 RDB 文件。
生成 RDB 流程:Redis fork 一个子进程,负责生成 RDB;生成 RDB 采用 Copy On Write 模式,此时,如果收到写请求,会在原副本上操作,不影响工作。
RDB 只能恢复生成快照时刻的数据,之后的数据无法恢复。生成 RDB 的资源开销高昂。RDB 适合做冷备。
AOF 会将写命令不断追加到 AOF 文本日志末尾。
AOF 丢数据比 RDB 少,但文件会比 RDB 文件大很多。
一般,AOF 设置 appendfsync
同步频率为 everysec
即可。
建议同时使用 RDB 和 AOF。用 AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。
Redis 管道
Redis 是一种基于 C/S 模型以及请求/响应协议的 TCP 服务。Redis 支持管道技术。管道技术允许请求以异步方式发送,即旧请求的应答还未返回的情况下,允许发送新请求。这种方式可以大大提高传输效率。使用管道发送命令时,Redis Server 会将部分请求放到缓存队列中(占用内存),执行完毕后一次性发送结果。如果需要发送大量的命令,会占用大量的内存,因此应该按照合理数量分批次的处理。