Redis进阶
一、Redis.conf详解
- 基本配置信息
- INCLUDES(导入配置文件)
- NetWork (网络)
绑定的ip: bind 127.0.0.1
保护模式: protected-mode yes
绑定的端口号: port 6379
- General(通用)
后台运行,默认no,需要设为yes: daemonize no
后台运行需要指定pid文件: pidfile /var/run/redis_6379.pid
默认数据库个数: databases 16
是否总是显示logo: always-show-logo yes
日志级别:
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing) 测试开发阶段
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 重要通知,生产环境
# warning (only very important / critical messages are logged) 关键信息
loglevel notice # 日志的文件位置名
- SNAPSHOTTING(快照)
持久化操作
# 900s内,1个key进行了修改,我们进行持久化操作
save 900 1
# 300内,10个key进行了修改,我们进行持久化操作
save 300 10
# 60s内,10000个key进行了修改,我们进行持久化操作
save 60 10000
# 持久化出错,是否继续工作
stop-writes-on-bgsave-error yes
# 是否压缩rdb(持久化文件)文件
rdbcompression yes
#保存rdb文件,错误校验
rdbchecksum yes
# rdb持久化存储文件
dbfilename dump.rdb
# rdb文件保存目录
dir ./
- REPLICATION(主从复制)
- SECURITY(安全)
# 设置密码 默认没有密码
requirepass 1234
命令设置密码:
CONFIG SET requirepass 1234
命令获取密码:
CONFIG GET requirepass
密码登陆:
AUTH 1234
- CLIENTS(限制)
# 最大客户端连接数
maxclients 10000
# 最大内存容量
maxmemory <bytes>
# 内存到达上线的处理策略
maxmemory-policy noeviction
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误
- APPEND ONLY MODE (模式)
# 默认不开启aof模式,默认rdb模式,大多数情况是够用的
appendonly no
# 持久化文件名称
appendfilename "appendonly.aof"
# appendfsync always # 修改一次执行一次
appendfsync everysec # 每秒执行一次,sync可能会丢失
# appendfsync no # 自己同步
二、持久化
RDB
-
rbd存储文件:dbfilename dump.rdb
如果这个目录下存在.rdb文件,启动会自动恢复其中的数据
127.0.0.1:6379> CONFIG GET dir
-
优点:
- 适合大规模数据恢复
- 对数据完整性要求不高
-
缺点:
- 需要一定时间间隔,如果redis意外关闭,最后一次的修改无法保存
- fork进程会占用内存控件
AOF
将所有执行的命令全部记录
- 手动修改为 :appendonly yes (默认no)重启会自动创建
- 优点
- 每次修改都会同步,完整性好
- 实时同步
- 缺点
- 数据文件来说,aof大于rdb,恢复速度很慢
三、发布订阅
- 订阅
SUBSCRIBE [频道]
- 发布
PUBLISH [频道] [message]
- 实时监听发布的数据
四、主从复制
- 一主二从策略
- 指定跟随的主机:slaveof [主机端口号码]
- 查看主从配置:info replication
- 配置slave
- 依次执行
cp redis.conf redis80.conf
cp redis.conf redis81.conf- 将redis80.conf和redis81文件中的,prot、log、pid、rdb,文件修改为新主机的prot(如需配置文件中设置机,修改replication的,如下图)
- 数据复制原理
slave启动成功后会向master发送一个sync同步指令。
master接收到指令,就在后台将所有的数据文件传送给slave,一次同步。
- 全量复制:在slave服务接收到数据库文件后,将其加载到内存中。
- 增量复制:master执行一条存储的命令依次传送给slvae,完成同步。
五、缓存穿透缓存雪崩
(1)缓存穿透
产生原因:key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
解决:若redis和数据库数据都不存在,呢就给这个Key缓存一个NULL设置5分钟过期时间。
(2)缓存击穿
产生原因:key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
解决:伪代码如下:
def get(key)
# 1、获取key
cats = $redis_4.get(key)
# 2、判断当前key是否存在
if cats.nil?
# 2-1、不存在key
# 3、抢锁,如果抢到锁设置设置成功返回1,,抢锁失败返回0
if $redis_4.setnx("cat:nx", 1, 300) == 1 # 等于1说明设置成功,否则等于0说明key已经存在
# 4-1、抢锁成功
# 获取数据
cats = ProjectCategory.all.map{|c| {id: c.id, name_cn: c.name_cn}}.to_json
# 存到redis中
$redis_4.set(key, cats)
$redis_4.expire(key, 60*60*24)
# 删除锁key
$redis_4.del("cat:nx")
else
# 4-2、抢锁失败
# 休眠50ms
sleep(50)
# 回掉函数,重新获取
get(key)
end
else
# 2-2、存在key直接返回
return cats
end
end
(3)缓存雪崩
产生原因:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。
解决:网上有很多解决方案,比如二级缓存什么的,但是笔者觉得比较靠谱,但是对程序侵入性不大的一个方案就是,不要让热点数据一起过期,给热点数据设置过期时间最好加上个随机时间,避免大量热点数据同一时间过期。
六、Redis淘汰策略和删除策略
(1)淘汰策略
LRU:最近最少使用
LFU:使用频率最少
random:随机
ttl:设置ttl权重
- volatile-lru:从已设置过期时间的数据集,中挑选最近最少使用的数据淘汰(需要注意,如果没有设置过期时间,则该key不会被淘汰)
基于lru算法,这个key如果被访问到,之后被访问到的几率非常大,参考:lru算法原理
-
volatile-ttl:从已设置过期时间的数据集,中挑选将要过期的数据淘汰,ttl值越大优先淘汰
-
volatile-random:从已设置过期时间的数据集,中任意选择数据淘汰
-
allkeys-lru:从数据集中,挑选最近最少使用的数据淘汰(适合部分访问频率高部分频率低的数据)
-
allkeys-random:从数据集中,任意选择数据淘汰(内存中数据使用频率相等的情况)
-
no-enviction(驱逐):禁止驱逐数据,内存不够,继续写入新数据就会报错
-
volatile-lfu:全部的key
-
allkeys-lfu:设置过期时间的key
(2)删除策略
- 定时删除:
创建一个定时器,当设置的key到达到期时间时,由定时器任务立即执行对key的删除操作 - 惰性删除:
数据到期时不做删除,下次访问时进行删除 - 定期删除:
1、每秒钟执行server.hz次serverCron()(对服务器进行定时轮询)→ databasesCron()(对redis中每一个库进行访问)→activeExpireCycle()
2、activeExpireCycle()对每一个expires[]逐一进行检测,每次执行250ms/server.hz
3、对某一个过期时间检测时,随机挑选W个key检测
如果key超时,删除key
如果一轮中删除的key数量>W25%,继续检测该expires(循环该过程)
如果一轮中删除的key数量<=W*25%,则检查下一个expires
七、慢查询日志
-
查看慢查询日志
CONFIG GET slowlog-log-slower-than
输出 =》- “slowlog-log-slower-than”
- “100”
-
查看慢查询sql
SLOWLOG GET
输出 =》-
- (integer) 1
- (integer) 1614143721
- (integer) 621
-
- “set”
- “aa”
- “aa”
- “127.0.0.1:59735”
-