REDIS高级特性
redis持久化机制
RDB(Redis DataBase)
什么是rdb
RDB:每隔一段时间,把内存中的数据写入磁盘的临时文件,作为快照,恢复的时候把快照文件读进内存中。如果宕机重启,那么内存里的数据肯定会没有的,那么再次启动redis后,则会恢复。
备份与恢复
内存备份–>磁盘临时文件
临时文件–>恢复到内存
优势和劣势
优势:
1.每隔一段时间备份,全量备份
2.灾备简单,可以远程传输
3.子进程备份的时候,主进程不会有任何io操作(不会有写入或者删除),保证备份数据的完整性。
4.相对AOF来说,当有更大文件的时候可以快速重启恢复
劣势:
1.发生故障时,可能会丢失最后一次的备份数据
2.子进程所占用的内存会和主进程一模一样,会造成cpu负担
3.由于定时全量备份是重量级操作,所以对于实时备份,就无法处理了
RDB的配置
1.保存位置,可以在redis.conf自定义:
/usr/local/redis/working/dump.rdb
2.保存机制
save 900 1 save 300 10 save 60 10000 save 10 3 * 如果1个缓存更新,则15分钟后备份 * 如果10个缓存更新,则5分钟后备份 * 如果10000个缓存更新,则1分钟后备份 * 演示:更新3个缓存,10秒后备份 * 演示:备份dump.rdb,删除重启
1.stop-writes-on-bgsave-error
yes:如果save过程中出错,则停止写操作
no:可能造成数据不一致
2.rdbcompression
yes:开启rdb压缩模式
no:关闭,会节约CPU损耗,但是文件会很大,道理通nginx
3.rdbchecksum
yes:使用CRC64算法校验rdb进行数据校验,大约有10%性能损耗
no:不校验
AOF
什么是AOF
1.以日志的形式来记录用户请求的写操作。读操作不会记录,因为写操作才会存储。
2.文件以追加的形式而不是修改的形式。
3.redis的aof恢复其实就是把追加的文件从开始到结尾读取执行写操作。
优势和劣势
优势
1.aof更加耐用,可以以秒级别为单位备份,如果发生问题,也只会丢失最后一秒的数据,大大增加了可靠性和数据完整性。所以AOF可以每秒备份一次,使用fsync操作。
2.以log日志形式追加,如果磁盘满了,会执行redis-check-aof工具。
3.当数据太大的时候,redis可以在后台自动重写aof。当redis继续把日志追加到老的文件中去时,重写也是非常安全的,不会影响客户端的读写操作。
4.AOF日志包含的所有写操作,会更加便于redis的解析恢复。
劣势
1.相同的数据,同一份数据,AOF比RDB大。
2.针对不同的同步机制,AOF会比RDB慢,因为AOF每秒都会备份做写操作,这样相对与RDB来说就略低。每秒备份fsync没毛病,但是如果客户端的每次写入就做一次备份fsync的话,那么redis的性能就会降。
3.AOF发生过bug,就是数据恢复的时候数据不完整,这样显得AOF会比较脆弱,容易出现bug,因为AOF没有RDB那么简单,但是呢为了防止bug的产生,AOF就不会根据旧的指令去重构,而是根据当前缓存中存在的数据指令去做重构,这样就更加健壮和可靠了。
配置
下面展示一些 内联代码片
。
# AOF 默认关闭,yes可以开启
appendonly no
# AOF 的文件名
appendfilename "appendonly.aof"
# no:不同步
# everysec:每秒备份,推荐使用
# always:每次操作都会备份,安全并且数据完整,但是慢性能差
appendfsync everysec
# 重写的时候是否要同步,no可以保证数据安全
no-appendfsync-on-rewrite no
# 重写机制:避免文件越来越大,自动优化压缩指令,会fork一个新的进程去完成重写动作,新进程里的内存数据会被重写,此时旧的aof文件不会被读取使用,类似rdb
# 当前AOF文件的大小是上次AOF大小的100% 并且文件体积达到64m,满足两者则触发重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
持久化选择
如果你能接受一段时间的缓存丢失,那么可以使用RDB
如果你对实时性的数据比较care,那么就用AOF
使用RDB和AOF结合一起做持久化,RDB做冷备,可以在不同时期对不同版本做恢复,AOF做热备,保证数据仅仅只有1秒的损失。当AOF破损不可用了,那么再用RDB恢复,这样就做到了两者的相互结合,也就是说Redis恢复会先加载AOF,如果AOF有问题会再加载RDB,这样就达到冷热备份的目的了。
Redis主从复制原理
主从复制可以理解为读写分离。一主二从是最常用的主从模式,主从同步一定要开启数据持久化
全量同步
Redis全量复制一般发生在Slave初始化阶段,这时Slave需要将Master上的所有数据都复制一份。具体步骤如下:
- 从服务器连接主服务器,发送SYNC命令;
- 主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
- 主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
- 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
- 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
增量同步
Redis增量复制是指Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程。
增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令。
无磁盘化复制
主Redis生成的RDB文件不落在磁盘上,而是直接在内存中通过网络发送;而从Redis也不是将RDB下载到磁盘,而是直接获取在内存中。
无磁盘化的传输方式,以内存方式的传输,通过socket,内网速度快可以用这种方式
repl-diskless-sync yes 开启无磁盘化复制
缓存过期与内存淘汰
缓存过期
(主动)定期删除
redis.conf
hz 10 配置检测时间
2、(被动)惰性删除
当客户端请求到已经过期的key 这时候redis会检测是否过期,如果已经过期,则会清除
以上是针对设置了expire过期的数据
内存淘汰管理机制
memory management
maxmemory 最大内存阈值,到达阈值之后,redis会自动清理。
内存淘汰机制
memory management
maxmemory 最大内存阈值,到达阈值之后,redis会自动清理,
自动清理有几种算法
maxmemory policy
- noeviction:旧缓存永不过期,新缓存设置不了,返回错误
- allkeys-lru:清除最少用的旧缓存,然后保存新的缓存(推荐使用)
- allkeys-random:在所有的缓存中随机删除(不推荐)
- volatile-lru:在那些设置了expire过期时间的缓存中,清除最少用的旧缓存,然后保存新的缓存
- volatile-random:在那些设置了expire过期时间的缓存中,随机删除缓存
- volatile-ttl:在那些设置了expire过期时间的缓存中,删除即将过期的
哨兵机制
什么是哨兵机制
sentinel(哨兵)用于监控Redis集群中的Master状态的工具,是Redis高可用解决方法,哨兵可以监视一个或多个redis master服务,以及这些master服务的所有从服务;当某个master服务宕机后,会把这个master下的某个从服务升级为master来替代一宕机的master继续工作。
master挂了之后,由于哨兵监控,剩余slave会进行选举,选举后其中一个成为master,当原来的master恢复后,他会成为slave。
sentinal 配置
port 26379
pidfile "/usr/local/redis/sentinel/redis-sentinel.pid"
dir "/usr/local/redis/sentinel"
daemonize yes
protected-mode no
logfile "/usr/local/redis/sentinel/redis-sentinel.log"
# 核心配置
# 配置哨兵
sentinel monitor mymaster 127.0.0.1 6379 2
# 密码
sentinel auth-pass <master-name> <password>
# master被sentinel认定为失效的间隔时间
sentinel down-after-milliseconds mymaster 30000
# 剩余的slaves重新和新的master做同步的并行个数
sentinel parallel-syncs mymaster 1
# 主备切换的超时时间,哨兵要去做故障转移,这个时候哨兵也是一个进程,如果他没有去执行,超过这个时间后,会由其他的哨兵来处理
sentinel failover-timeout mymaster 180000
######## 启动哨兵
redis-sentinal sentinal.conf
redis缓存穿透与雪崩
缓存穿透
什么是缓存穿透
Key在缓存中查询为空,转而在数据库中也查询也为空。因为数据查询结果为空,所以没有将key存入缓存中,导致多次请求都是穿过缓存,直接请求到数据库。
解决方案
1.不管查询出来的数据是否为空,直接放到缓存中去。判断是否为空,为空的话,设置超时时间。
2.使用布隆过滤器
雪崩
什么是雪崩
某个时间点大面积的key失效,刚好又有很大的流量涌入,所有的请求都打在数据库,数据库的压力就非常大可能会宕机。
缓存雪崩没有好的解决方案,重在预防发生雪崩。
解决方案
永不过期,需要更新数据的话,采用手动过期
过期时间错开 初始化缓存的时间错开,前后隔几分钟
多种缓存结合 相当于在其他缓存中备份,但过期时间更长
采购第三方Redis 购买高可用的redis主从备份