redis 核心原理、模型、淘汰策略

Redis的单线程和高性能

Redis 单线程为什么还能这么快?

因为它所有的数据都在内存中,所有的运算都是内存级别的运算,而且单线程避免了多线程的切换性能损耗问题。正因为 Redis 是单线程,所以要小心使用 Redis 指令,对于那些耗时的指令(比如keys),一定要谨慎使用,一不小心就可能会导致 Redis 卡顿。

Redis 单线程如何处理那么多的并发客户端连接?

Redis的IO多路复用:redis利用epoll来实现IO多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件分发给事件处理器。
Nginx也是采用IO多路复用原理解决C10K问题

持久化

RDB快照(snapshot)

在默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中。
你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:

# save 60 1000

AOF

快照功能并不是非常持久的:如果redis因为某些原因造成故障宕机,那么服务器将丢失最近写入、切仍为保存到快照中的那些数据,从1.1版本开始,Redis增加了一种完全耐用持久化方式:AOF持久化,讲修改的每一条指令记录增加近文件

你可以通过修改配置文件来打开AOF功能:

appendonly yes

设置后每当redis执行一行改变数据集的命令时,这个命令就会被追加到AOF文件的末尾。

这样的话,当redis重新启时,程序就可以通过重新执行AOF文件中的命令来达到重建数据集的目的

您可以配置redis多久才将数据fsync到磁盘一次

有三个选项:

每次有新命令追加到AOF文件时候就执行fsync:非常慢,也非常安全

每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。

从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。

RDB 和 AOF ,我应该用哪一个

如果你非常关心你的数,但仍然可以承受在分钟内的数据丢失,那么可以采用RDB持久化

很多用户只使用AOF持久化,但并不推荐:因为定时生成的RDB快照非常便于进行数据库别分,并且RDB恢复数据集的速度要比AOF恢复的速度要快

redis 4.0混合持久化

重启redis的时候,我们很少使用rdb来恢复内存状态,因为会丢失大量数据。我们通常使用APOF日志重放,但是重放AOF日志性能相对rdb来说要慢很多,这样在redis实例很大的情况下,启动需要花费很长时间,redis4.0为了解决这个问题,带来了一个新的持久化—混合持久化,APOF在重写时讲重写这一时刻之前的内存rdb快照文件的内容和增量AOF修改内存数据的命令文件存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换;

AOF根据配置规则在后台自动重写,也可以人为执行命令bgrewriteaof重写AOF。 于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。

开启混合持久化:

# aof-use-rdb-preamble yes    

混合持久化aof文件结构

缓存淘汰策略

当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap)。交换会让 Redis 的性能急剧下降,对于访问量比较频繁的 Redis 来说,这样龟速的存取效率基本上等于不可用。

在生产环境中我们是不允许 Redis 出现交换行为的,为了限制最大使用内存,Redis 提供了配置参数 maxmemory 来限制内存超出期望大小。

当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。

noeviction 不会继续服务写请求 (DEL 请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。这是默认的淘汰策略。

volatile-lru 尝试淘汰设置了过期时间的 key,最少使用的 key 优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。

volatile-ttl 跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。

volatile-random 跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。

allkeys-lru 区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。

allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。

volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的 key 进行淘汰。如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值