redis单线程、持久化、过期策略及其内存淘汰策略
原理:
redis使用的是单线程为什么还能这么快?
因为redis 数据都在内存中,是内存级别的运算处理,而且单线程避免了多线程切换的性能损耗问题。
redis处理数据的时间是纳秒级别
redis单线程如何处理那么多的并发客户端?
redis采用epoll来实现IO多路复用(linux本身的内核技术),将连接信息和事件放到队列中,依次放到文件事件分派器,事件分派器将事件发送给事件处理器
传统数据库中的ACID:
原子性
一致性
独立性
持久性
持久化
redis持久化之RDB
能够在指定的时间间隔内对数据进行快照存储
可以人为设置rdb触发条件:在N秒内key至少有M次变化
redis单独创建(fork)一个子进程来进行持久化,会将数据写入到一个临时文件中(dump.rdb),待持久化过程都结束了,再用这个临时文件替换上次持久化号的文件。
整个过程中主进程不进行IO操作(为了确保高性能)
优点:适用于需要大规模恢复并且对数据恢复完整性不敏感的情况
缺点:宕机后持久化后的数据可能丢失
默认触发生成dump.rdp的情况:
1.900秒内(15分钟)key发生一次改变
2.300秒内(五分钟)key发生10次改变
3.60秒内(一分钟)key发生10000次改变
redis持久化之AOF
以日志形式追加记录redis的每个写操作到appendonly.aof文件中
启动时会读取该文件重新构建数据
防止文件越写越大,增加重写机制,当AOF文件大小超过阈值,redis启动AOF文件压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof
指定redis多久生成一次aof文件
1.每秒同步,异步操作,每秒记录,如果一秒内宕机,有数据丢失
2.每修改同步(默认使用),每次发生数据发生变更都会被记录到磁盘中,性能差但是数据完整性比较好
3.不同步,从不同步,更快但是不安全
缺点:
1.相同数据下,AOF文件远大于RDB文件,
2.恢复速度也比RDB慢
只做缓存:
如果只希望数据在服务器运行的时候存在,也可以不使用任何持久化方式
混合持久化方式
AOF在重写时将重写这一刻之前的内存RDB快照文件和增量的AOF修改内存数据的命令日志文件放在一起,都写入新的AOF文件中,新的文件一开始不叫appendonly.aof文件,等到重写完毕,在进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换
AOF根据配置规则在后台自动重写,也可以人为执行命令bgrewriteaof重写AOF。 于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升。
过期策略
当redis中缓存的key过期后的操作
- 定时过期:给key设置定时器,到时间清除
- 惰性过期:只有在使用到key的时候,判断其有无过期,过期则清除
- 定期过期(定时过期+惰性过期):每隔一段时间,扫描数据库中一定数量的key,清除其中已经过期的key
内存淘汰策略
当redis用于缓存的内存不足时的操作
- noeviction(默认),只读不可写,导致线上业务不能运行
- volatile-lru,优先淘汰设置了过期时间后使用最少的key,不淘汰没设置过期时间的
- volatile-ttl,优先淘汰设置了过期后剩余寿命最少的key,不淘汰没设置过期时间的
- volatile-random,淘汰设置了过期后中随机的key,不淘汰没设置过期时间的
- allkeys-lru,淘汰所有key中使用最少的key
- allkeys-random,随机淘汰所有key中的key
如果想同时使用Redis中的持久化功能,就使用volatile-***,可以保留没有设置过期时间的key