Redis缓存
redis作为缓存的要求:redis作为缓存,由于内存有限,要求存储热点数据
按照业务逻辑设置
设置合理内存大小
- 使用配置文件中maxmemory参数设置
- 一般内存大小设置为1-10G
设置数据过期时间
1. set命令
格式:set key value ex num
含义:给key设置num秒的存活时间
2. expire命令
格式:expire key num
含义:重置存活时间
3. expireat命令
格式:expireat key 时间戳
含义:重新设置过期时间,具体知道什么时候过期时使用
注意:
get命令不会重置过期时间,但是set命令会删除过期时间的设置
过期数据删除机制
- 被动删除:数据存活时间到了,不会立即删除,当有请求访问才会删除
- 主动删除:
- 随机选择某些数据,删除其中的过期数据
- 如果过期数据占这些数据超过25%,重复步骤1
按照业务运行设置
设置合理删除策略
以下删除机制是在内存满了情况下
- 使用配置文件中maxmemory-policy参数
- 一般会设置成allkeys-lru或者volatile-lru
lru和lfu的区别
- lru:按照访问时间判断是否为热点数据。如果是最近访问过,认为是热点数据;很久没有访问过,认为是冷数据
- lfu:按照访问次数判断是否为热点数据。如果访问次数很多,认为是热点数据,反之是冷数据
触发时刻:当redis内存不够使用的时候触发
Redis的数据持久化
数据持久化知识
存储层数据复制:
- 快照机制:周期性的将数据备份一份,等待数据恢复时使用
- 日志备份:日志文件中存储的是操作命令,要恢复数据只需要将命令从头到尾执行一遍
父子进程:在一个进程中创建另一个进程,这两个进程是父子进程。常规下,父子进程有自己的独立资源,不共享内存空间
fork()系统调用:写时复制技术。为一个进程创建子进程,父子进程指向同一块内存空间,所以子进程的创建速度很快。只有当增删改操作发生时,父进程或者子进程才会将数据复制到另一个内存空间操作。对于Redis来说,当要进行数据落盘时,调用系统的fork方法快速创建子进程,让子进程进行落盘。在此期间,父进程依然可以对客户端做出响应。如果父进程要修改内存中的数据,会发生写时复制,父进程会复制一份内存中将要修改的数据,存储到内存其他区域,然后进行修改,子进程是感知不到的,所以,子进程落盘的数据是子进程创建出来的那一刻的数据。
如下图中,父进程P在fork出Q子进程后,两个进程会共用一个内存空间,当父进程P修改页面3的数据时,系统会拷贝出一个页面3的副本,这样父进程就会修改页面3的副本数据,而不会对子进程有影响,实现进程间数据的隔离。
fork()的好处是:
- 创建子进程速度快
- 创建子进程内存消耗少
- 父子进程对数据进行修改,互相无法感知
RDB持久化
底层原理
使用的快照技术
配置文件设置
save 900 1
save 300 10
save 60 10000
含义:
1.如果60s后,超过10000条数据被修改,发生一次RDB持久化
2.如果300s后,超过10条数据被修改,发生一次RDB持久化
3.如果900s后,超过1条数据被修改,发生一次RDB持久化
触发时刻
执行save命令
关机时执行,因为执行此命令,redis无法响应客户端的请求
执行bgsave命令
按照配置文件设置执行,系统调用fork(),子进程负责持久化,父进程负责响应客户端请求,互相不干扰。配置文件中的save配置项条件满足时,redis调用的是bgsave命令。
主从复制时触发
优劣势
优势:持久化以及恢复速度很快
劣势:
1.只有一个dump.rdb文件,没有过往版本,需要人为保存
2.持久化时间点之间的窗口数据容易丢失
AOF持久化
底层原理
使用日志文件中的命令,恢复数据
特点
- 可以同时打开RDB和AOF方式
- 同时打开的情况下,恢复数据只会用AOF,因为AOF数据全面
- AOF机制丢失的数据少
AOF方式的劣势和解决方案
劣势:
- AOF文件随时间推移,不停的增大
- AOF文件变大后,恢复时间变长
解决方案:
- 4.0版本前,删除AOF文件中抵消命令和重复命令
- 4.0版本后,AOF文件是个混合文件。前面是RDB文件内容,后面是增量命令
- 需要注意,只有在发生重写的情况下,AOF文件才会变成混合文件
配置项设置:
- 开启混合aof:aof-use-rdb-preamble yes
- 自动触发重写机制:
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb
- 解释:在aof文件大小超过64M,且比上次重写后aof文件大小大一倍以上,发生重写。如果上次没有发生重写,那就比没有发生重写的aof文件大一倍以上
- 执行命令bgrewriteaof手动触发重写
配置文件设置
开启aof:
appendonly yes
持久化频率:
appendfsync always
appendfsync everysec
appendfsync no
数据写到磁盘前,内核会开辟一块buffer空间,数据要先写到buffer中。这三个配置项决定buffer中的数据什么时候写到磁盘
操作系统内核提供了两个方法write和fsync。write方法支持应用程序将数据写到内核缓存中,什么时候落盘由系统调用决定;fsync方法是针对单个文件,支持应用程序将数据写入文件中落盘。这个方法是阻塞的,直到落盘完成才会返回。
appendfsync always:redis每次增删改操作都会调用fsync方法,这会导致redis性能有所下降
appendfsync everysec:redis每次增删改操作都会调用write方法写入缓存中,但是每隔1秒会调用fsync方法
appendfsync no:redis每次增删改操作只会调用write方法,什么时候落盘由操作系统内核决定
持久化文件格式
RDB文件格式:开头是REDIS,表示是RDB文件
aof文件格式:由(*数字)、($数字)以及各种命令组成

aof混合文件格式:首先这个文件中存在rdb内容和aof内容,rdb内容在前,aof内容在后。文件会以REDIS开头,表示rdb内容。rdb内容结束后,某一行会以*开头,表示后面都是aof内容
持久化文件可以被修改,修改自然影响历史数据,可以通过这种方式修正历史数据
数据恢复
aof文件存储的是操作命令,数据量大,所以redis通过启动一个子进程去执行aof文件中的命令来恢复数据
子进程恢复数据时,父进程依然可以对客户端的请求作出响应,redis处于可用状态。但是,在此期间的操作命令,父进程会存入aof缓存队列中,这个队列是在子进程创建时一同被创建出来的。等子进程完成数据恢复,父进程再把队列中的数据同步到新的aof文件中。