使用 Redis 缓存数据时,为了提高缓存命中率,需要保证缓存数据都是热点数据。可以将内存最大使用量设置为热点数据占用的内存量,然后启用allkeys-lru淘汰策略,将最近最少使用的数据淘汰
二、Redis持久化Redis是基于内存的,如果不想办法将数据保存在硬盘上,一旦Redis重启(退出/故障),内存的数据将会全部丢失。
我们肯定不想Redis里头的数据由于某些故障全部丢失(导致所有请求都走MySQL),即便发生了故障也希望可以将Redis原有的数据恢复过来,这就是持久化的作用。
Redis提供了两种不同的持久化方法来讲数据存储到硬盘里边:
RDB(基于快照),将某一时刻的所有数据保存到一个RDB文件中。
AOF(append-only-file),当Redis服务器执行写命令的时候,将执行的写命令保存到AOF文件中。
2.1RDB(快照持久化)RDB持久化可以手动执行,也可以根据服务器配置定期执行。RDB持久化所生成的RDB文件是一个经过压缩的二进制文件,Redis可以通过这个文件还原数据库的数据。
有两个命令可以生成RDB文件:
SAVE会阻塞Redis服务器进程,服务器不能接收任何请求,直到RDB文件创建完毕为止。
BGSAVE创建出一个子进程,由子进程来负责创建RDB文件,服务器进程可以继续接收请求。
Redis服务器在启动的时候,如果发现有RDB文件,就会自动载入RDB文件(不需要人工干预)
服务器在载入RDB文件期间,会处于阻塞状态,直到载入工作完成。
除了手动调用SAVE或者BGSAVE命令生成RDB文件之外,我们可以使用配置的方式来定期执行:
在默认的配置下,如果以下的条件被触发,就会执行BGSAVE命令
save 900 1 #在900秒(15分钟)之后,至少有1个key发生变化, save 300 10 #在300秒(5分钟)之后,至少有10个key发生变化 save 60 10000 #在60秒(1分钟)之后,至少有10000个key发生变化原理大概就是这样子的(结合上面的配置来看):
struct redisServer{ // 修改计数器 long long dirty; // 上一次执行保存的时间 time_t lastsave; // 参数的配置 struct saveparam *saveparams; };遍历参数数组,判断修改次数和时间是否符合,如果符合则调用besave()来生成RDB文件
总结:通过手动调用SAVE或者BGSAVE命令或者配置条件触发,将数据库某一时刻的数据快照,生成RDB文件实现持久化。
2.2AOF(文件追加)上面已经介绍了RDB持久化是通过将某一时刻数据库的数据“快照”来实现的,下面我们来看看AOF是怎么实现的。
AOF是通过保存Redis服务器所执行的写命令来记录数据库的数据的。
比如说我们对空白的数据库执行以下写命令:
redis> SET meg "hello" OK redis> SADD fruits "apple" "banana" "cherry" (integer) 3 redis> RPUSH numbers 128 256 512 (integer) 3Redis会产生以下内容的AOF文件:
这些都是以Redis的命令请求协议格式保存的。Redis协议规范(RESP)参考资料:
https://www.cnblogs.com/tommy-huang/p/6051577.html
AOF持久化功能的实现可以分为3个步骤:
命令追加:命令写入aof_buf缓冲区
文件写入:调用flushAppendOnlyFile函数,考虑是否要将aof_buf缓冲区写入AOF文件中
文件同步:考虑是否将内存缓冲区的数据真正写入到硬盘