# Java_Study_Routes **Repository Path**: Harmony_TL/JavaStudyDemo ## Basic Information - **Project Name**: Java_Study_Routes - **Description**: Java_Study_Routes是JavaSE一些常用的API、集合、IO、多线程的使用。 - **Primary Language**: Java - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-08-13 - **Last Updated**: 2022-10-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 项目架构之传统三层架构和领域模型三层架构 http://www.uml.org.cn/zjjs/202010224.asp 三层架构到DDD分层架构的演变 https://blog.csdn.net/wulex/article/details/112402710 1 、AOF 持久化 Redis是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了两种持久化方式,RDB和AOF。我们先来介绍AOF。 AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。Redis默认情况是不开启AOF的。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。 AOF是执行完命令后才记录日志的。为什么不先记录日志再执行命令呢?这是因为Redis在向AOF记录日志时,不会先对这些命令进行语法检查,如果先记录日志再执行命令,日志中可能记录了错误的命令,Redis使用日志回复数据时,可能会出错。 正是因为执行完命令后才记录日志,所以不会阻塞当前的写操作。但是会存在两个风险: 1.更执行完命令还没记录日志时,宕机了会导致数据丢失 2.AOF不会阻塞当前命令,但是可能会阻塞下一个操作。 这两个风险最好的解决方案是折中妙用AOF机制的三种写回策略 appendfsync: 1.always,同步写回,每个子命令执行完,都立即将日志写回磁盘。 2.everysec,每个命令执行完,只是先把日志写到AOF内存缓冲区,每隔一秒同步到磁盘。 3.no:只是先把日志写到AOF内存缓冲区,有操作系统去决定何时写入磁盘。 always同步写回,可以基本保证数据不丢失,no策略则性能高但是数据可能会丢失,一般可以考虑折中选择everysec。 如果接受的命令越来越多,AOF文件也会越来越大,文件过大还是会带来性能问题。日志文件过大怎么办呢?AOF重写机制!就是随着时间推移,AOF文件会有一些冗余的命令如:无效命令、过期数据的命令等等,AOF重写机制就是把它们合并为一个命令(类似批处理命令),从而达到精简压缩空间的目的。 AOF重写会阻塞嘛?AOF日志是由主线程会写的,而重写则不一样,重写过程是由后台子进程bgrewriteaof完成。 • AOF的优点:数据的一致性和完整性更高,秒级数据丢失。 • 缺点:相同的数据集,AOF文件体积大于RDB文件。数据恢复也比较慢。 2 RDB持久化 因为AOF持久化方式,如果操作日志非常多的话,Redis恢复就很慢。有没有在宕机快速恢复的方法呢,有的,RDB! RDB,就是把内存数据以快照的形式保存到磁盘上。和AOF相比,它记录的是某一时刻的数据,,并不是操作。 什么是快照?可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。 RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。RDB触发机制主要有以下几种:经典面试题:Redis 持久化有哪几种方式,怎么选?-开源基础软件社区RDB通过bgsave命令的执行全量快照,可以避免阻塞主线程。basave命令会fork一个子进程,然后该子进程会负责创建RDB文件,而服务器进程会继续处理命令请求 快照时,数据能修改嘛? Redis接住操作系统的写时复制技术(copy-on-write,COW),在执行快照的同时,正常处理写操作。 虽然bgsave执行不会阻塞主线程,但是频繁执行全量快照也会带来性能开销。比如bgsave子进程需要通过fork操作从主线程创建出来,创建后不会阻塞主线程,但是创建过程是会阻塞主线程的。可以做增量快照。 • RDB的优点:与AOF相比,恢复大数据集的时候会更快,它适合大规模的数据恢复场景,如备份,全量复制等 • 缺点:没办法做到实时持久化/秒级持久化。 Redis4.0开始支持RDB和AOF的混合持久化,就是内存快照以一定频率执行,两次快照之间,再使用AOF记录这期间的所有命令操作。 3 如何选择RDB和AOF • 如果数据不能丢失,RDB和AOF混用 • 如果只作为缓存使用,可以承受几分钟的数据丢失的话,可以只使用RDB。 • 如果只使用AOF,优先使用everysec的写回策略。 面试官:看你简历介绍,对redis比较熟悉哦? 小萌(看着面试官诡异的笑容,微微一颤) :恩,还算熟悉的 面试官:好,那我们说说redis的持久化机制呗 小萌(还好,这个了解) :经典的redis的持久化机制分为两种:rdb和aof;4.0之后,redis又提供了一种混合型的持久化机制 面试官:恩,好的,分别详细说说各自的实现机制,优缺点 小萌:rdb就是把某时刻的数据以二进制的形式固化到磁盘上,优点是二进制存储,结构压缩紧凑,方便传输,适用于备份容灾,缺点是实时性不高,单纯rdb,很难保证数据的可靠性,容易造成数据丢失; 小萌:aof则是以日志的形式记录数据的变更信息,相对于rdb,其数据实时性较高,一定程度上保证了数据的安全可靠,但是,其文件大小容易暴增,如果aof刷盘频繁的话,还会影响redis性能; 小萌(一口气说了这么多,稍微休息下):而混合型则是在一个文件中同时使用rdb和aof格式,集上述两种的优势于一身 面试官:恩恩,那rdb备份一般什么时候进行呢? 小萌:rdb有三种触发方式。第一种,save命令触发,这种是堵塞式的,一般不推荐使用;第二种是bgsave命令触发,执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求;第三种就是根据业务情况自动触发,在某个固定时间段内,如果出现了指定次数的数据变更则进行rdb... 面试官: 恩恩,那说说aof吧? 小萌:恩,好的 (稍微回忆了下...) aof是redis的另一种持久化机制,核心思想是以日志的形式记录所有写操作,这样,当redis宕机重启后,可以根据日志文件快速恢复数据; 面试官:恩,那按照你这么说,这个日志文件会越来越大? 小萌:恩,如果不做任何处理,是会越来越大的;针对这个问题,redis通过其aof文件重写机制来解决了这个问题 面试官:咦,有点兴趣了,能介绍下这个重写机制么?我也学习学习... 小萌(...装,你就装吧, 我可不敢随便说...) 小萌:恩,aof重写机制是这样的。当有命令触发或aof达到一定大小后,会触发aof文件重写。重写时,redis会fork一个子进程出来,在子进程中,将内存中所有数据通过redis写命令写入到一个新的aof文件;aof写完后,再删除旧的aof文件,将新的aof文件更名为旧的aof文件 面试官:恩恩,想了下啊,感觉是不是有点问题?你看啦,重写时,如果有新的数据变更了怎么办?这个子进程应该是感知不到的吧? 小萌(嘿嘿,我就知道你在装,我故意说漏了一点,如果你不懂,不可能这么快就意识到这个问题。面试官好狡猾啊,得小心点...) 小萌:恩恩,是的,这里补充一下哈;在fork后,子进程负责将内存中的数据写入新的aof文件;同时,父进程中,如果有新的数据变更,会将其变更记录写到rewrite_buf中;待子进程写完后,通过信号通知父进程,父进程收到通知后,继续将rewrite_buf中的变更信息写入到新的aof文件... 这样新的aof文件就不会缺失数据了 面试官(微微一笑):恩,不错,学习了...好的,我们再聊聊别的东西吧