专注于Java领域优质技术,欢迎关注作者:孤独烟

正文
持久化套路一般我们在生产上采用的持久化策略为
(1)master关闭持久化(2)slave开RDB即可,必要的时候AOF和RDB都开启该策略能够适应绝大部分场景,绝大部分丛集架构。
为什么是绝大部分场景?
因为这套策略存在部分的资料丢失可能性。redis的主从复制是异步的,master执行完客户端请求的命令后会立即返回结果给客户端,然后异步的方式把命令同步给slave。因此master可能还未来得及将命令传输给slave,就宕机了,此时slave变为master,资料就丢了。
幸运的是,绝大部分业务场景,都能容忍资料的部分丢失。假设,真的遇到快取雪崩的情况,程式码中也有熔断器来进行资源保护,不至于所有的请求都转发到数据库上,导致我们的服务崩溃!
ps:这里的快取雪崩是指同一时间来了一堆请求,请求的key在redis中不存在,导致请求全部转发到数据库上。
为什么是绝大部分丛集架构?
因为在丛集中存在redis读写分离的情况,就不适合这套方案了。
幸运的是,由于采用redis读写分离架构,就必须要考虑主从同步的延迟性问题,徒增系统复杂度。目前业内采用redis读写分离架构的专案,真的太少了。
为什么这么做
(1)master关闭持久化
原因很简单,因为无论哪种持久化方式都会影响redis的效能,哪一种持久化都会造成CPU卡顿,影响对客户端请求的处理。为了保证读写最佳效能,将master的持久化关闭!
RDB持久化
RDB持久化是将当前程序中的资料生成快照储存到硬盘(因此也称作快照持久化),储存的档案字尾是rdb;当Redis重新启动时,可以读取快照档案恢复资料。
那么RDB持久化的过程,相当于在执行bgsave命令。该命令执行过程如下图所示
如图所示,主执行绪需要呼叫系统函式fork(),构建出一个子程序进行持久化!很不幸的是,在构建子程序的过程中,父程序就会阻塞,无法响应客户端的请求!
而且,在测试中发现,fork函式在虚拟机器上较慢,真机上较快。考虑到现在都是部署在docker容器中,很少部署在真机上,为了效能,master不建议开启RDB持久化!
AOF持久化
RDB持久化是将程序资料写入档案,而AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志档案中。
随着时间的流逝,你会发现这个AOF档案越来越大,于是redis有一套rewrite机制,来缩小AOF档案的体积。然而,在rewrite的过程中也是需要父程序来fork出一个子程序进行rewrite操作。至于fork函式的影响,上面提到过了。
还有一个就是刷盘策略fsync,这个值推荐是配everysec,也就是Redis会预设每隔一秒进行一次fsync呼叫,将缓冲区中的资料写到磁盘。
然而,如果磁盘效能不稳定,fsync的呼叫时间超过1秒钟。此时主执行绪进行AOF的时候会对比上次fsync成功的时间;如果距上次不到2s,主执行绪直接返回;如果超过2s,则主执行绪阻塞直到fsync同步完成。
因此AOF也是会影响redis的效能的。
ps:linux函式中,wrtie函式将资料写入档案的时候,是将资料写入操作系统的缓冲区,还并未刷入磁盘。而fsync函式,可以强制让操作系统将缓冲区资料刷入磁盘。
综上所述,我们为了保证读写效能最大化,将master的持久化关闭。
(2)slave开RDB即可,必要的时候AOF和RDB都开启
首先,我先说明一下,我不推荐单开AOF的原因是,基于AOF的资料恢复太慢。
你要想,我们已经做了主从复制,资料已经实现备份,为什么slave还需要开持久化?
因为某一天可能因为某某工程,把机房的电线挖断了,就会导致master和slave机器同时宕机。
那么这个时候,我们需要迅速恢复丛集,而RDB档案档案小、恢复快,因此灾难恢复常用RDB档案。
其次,官网也不推荐单开AOF,地址如下:
https://redis.io/topics/persistence截图如下
所以,如果实在对资料安全有一定要求,将AOF和RDB持久化都开启。
另外,做好灾难备份。利用linux的scp命令,定期将rdb档案拷贝到云服务器上。
ps:scp是secure copy的简写,用于在Linux下进行远端拷贝档案的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。





























