培训行业seo整站优化,网站制作公司-山而,长宁品牌网站建设,wordpress变数据库文章目录 前置知识RDB#xff08;定期备份#xff09;触发机制流程说明RDB文件的处理RDB 的优缺点 AOF#xff08;实时备份#xff09;使用AOF命令写入AOF工作流程文件同步重写机制重写触发机制AOF进制重写流程 混合持久化启动时数据恢复 总结 前置知识 回顾MySQL MySQL的事… 文章目录 前置知识RDB定期备份触发机制流程说明RDB文件的处理RDB 的优缺点 AOF实时备份使用AOF命令写入AOF工作流程文件同步重写机制重写触发机制AOF进制重写流程 混合持久化启动时数据恢复 总结 前置知识 回顾MySQL MySQL的事务有4个比较核心的特性
原子性 一致性 持久性 隔离性 何为持久 重启进程/重启主机之后数据是否仍然存在 把数据存储到硬盘上持久如果把数据存储到内存上 不持久 redis是一个内存数据库将数据存储到内存当中但是内存当中的数据是不持久的如果想做到持久那么就需要让redis把数据存储到硬盘上。Redis相比于MySQL这样的关系型数据库最明显的特点/优势效率高快
为了保证速度快数据肯定还得在内存当中但是为了持久数据还得想办法存储在硬盘上这样的两份数据理论上是完全相同的。Redis⽀持RDB和AOF两种持久化机制持久化功能有效地避免因进程退出造成数据丢失问题当下次重启时利⽤之前持久化的⽂件即可实现数据恢复 RDB定期备份
RDB持久化是定期把当前redis内存当中的数据⽣成快照保存到硬盘的过程触发RDB持久化过程分为⼿动触发和⾃动触发
触发机制
⼿动触发程序员通过redis客户端执行特定的命令来触发快照生成对应save和bgsave命令
save命令阻塞当前Redis服务器直到RDB过程完成为⽌对于内存⽐较⼤的实例会造成⻓时间阻塞基本不采⽤bgsave 命令Redis 进程执⾏ fork 操作创建⼦进程RDB 持久化过程由⼦进程负责完成后⾃动结束。阻塞只发⽣在 fork 阶段⼀般时间很短不会影响redis服务器处理其它客户端的请求和命令
Redis 内部的所有涉及 RDB 的操作都采⽤类似 bgsave 的⽅式 何时会自动触发 1.使⽤ save 配置。如 “save m n” 表⽰ m 秒内数据集发⽣了 n 次修改⾃动 RDB 持久化
在redis配置文件当中进行设置让redis每隔多长时间/每产生多少次修改就触发 虽然此处的数值可以自由修改配置但是因为生成一次rdb快照是有成本的所i有不能让这个操作执行的太频繁所以可能就会导致快照里面的数据和当前实时的数据情况可能存在偏差
2.redis进行主从复制的时候从节点进⾏全量复制操作时主节点会进行RDB 持久化生成rdb快照随后将rdb快照文件内容发送给从结点
3.执⾏ shutdown 命令关闭 Redis 时 / 正常关闭redis服务器
也会执⾏ RDB 持久化 如果插入新的key不手动执行bgsave然后重启redis服务器会怎么样 1.如果是正常流程重启redis服务器此时redis服务器会在退出的时候自动触发生成rdb持久化操作
2.如果是异常重启kill -9 或者服务器掉电此时redis服务器来不及进行rdb持久化操作那么此时内存当中尚未保存到快照中的数据就会随着重启而丢失 流程说明 bgsave 命令的运作流程 1.执⾏ bgsave 命令Redis ⽗进程判断当前进是否存在其他正在执⾏的⼦进程如 RDB/AOF ⼦进 程如果存在 bgsave 命令直接返回
2.⽗进程执⾏ fork 创建⼦进程fork 过程中⽗进程会阻塞通过 info stats 命令查看 latest_fork_usec 选项可以获取最近⼀次 fork 操作的耗时单位为微秒
3.⽗进程 fork 完成后bgsave 命令返回 “Background saving started” 信息并不再阻塞⽗进程可 以继续响应其他命令
4.⼦进程创建 RDB ⽂件根据⽗进程内存⽣成临时快照⽂件完成后对原有⽂件进⾏原⼦替换。执 ⾏ lastsave 命令可以获取最后⼀次⽣成 RDB 的时间对应 info 统计的 rdb_last_save_time 选 项
5.进程发送信号给⽗进程表⽰完成⽗进程更新统计信息 RDB文件的处理
保存RDB ⽂件保存在配置文件/etc/redis/redis.conf指定的⽬录 ⽂件名通过 dbfilename 配置默认 dump.rdb指定
这个是rdb机制生成的镜像文件它是二进制文件将内存当中的数据以压缩的形式保存当这个二进制文件当中压缩需要消耗一定的CPU在资源但是能节省存储空间后续redis服务器重新启动就会尝试加载这个rdb文件如果发现格式错误就可能导致加载数据失败注意rdb文件虽然不主动修改它仍然可能会出现意外问题比如网络传输或者其它问题可能会引起这个文件的损坏此时redis服务器就无法启动 可以通过执⾏config set dir {newDir}和 config set dbfilename {newFilename} 运⾏期间动态执⾏当下次运⾏时 RDB ⽂件会保存到新⽬录 **压缩**Redis 默认采⽤ LZF 算法对⽣成的 RDB ⽂件做压缩处理压缩后的⽂件远远⼩于内存⼤ ⼩默认开启可以通过参数 config set rdbcompression {yes|no} 动态修改
虽然压缩 RDB 会消耗 CPU但可以⼤幅降低⽂件的体积⽅便保存到硬盘或通过⽹络发送到 从节点因此建议开启 注意1rdb持久化操作可以进行多次当执行生成rdb镜像文件操作的时候此时就会把要生成的快照数据先保存到一个临时文件当中当这个快照生成完成之后在删除之前的rdb文件然后把新生成的rdb文件的名字改成刚才的dump.rdb 。但是rdb文件始终是只有一个的 验证可以通过Linux的stat命令查看文件的相关信息观察文件inode编号的变化 注意2执行flushall操作会清空rdb文件 如果把rdb文件故意改坏了此时会怎么样 手动的把rdb文件内容改坏然后一定是通过kill掉redis进程的方式然后重新启动redis服务器如果是通过service redis-server restart重启就会在redis服务器退出的时候重新生成rdb快照就会把刚才改坏的rdb文件重新替换为正确的。
rdb文件坏了得到的结果是不可预期的如果 Redis 启动时加载到损坏的 RDB ⽂件会拒绝启动。这时可以使⽤ Redis 提供的 redis-check-dump ⼯具检测 RDB ⽂件并获取对应的错误报告 当redis服务器挂了的时候可以看看redis日志了解发生了什么/var/log/redis/ RDB 的优缺点
1RDB 是⼀个压缩的⼆进制⽂件代表 Redis 在某个时间点上的数据快照。⾮常适⽤于备份全 量复制等场景。⽐如每 6 ⼩时执⾏ bgsave 备份并把 RDB ⽂件复制到远程机器或者⽂件系统中 如 hdfs⽤于灾备
2Redis 加载 RDB 恢复数据远远快于 AOF 的⽅式。
因为RDB使用的是二进制的方式来组织数据直接把数据读取到内存当中然后按照字节的个数读取出来放到结构体/对象当中而AOF是用文本的方式组织数据需要进行一系列的字符串切分操作
3RDB ⽅式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运⾏都要执⾏ fork 创建⼦进 程属于重量级操作频繁执⾏成本过⾼
4RDB ⽂件使⽤特定⼆进制格式保存Redis 版本演进过程中有多个 RDB 版本兼容性可能有⻛ 险
老版本的redis的rbd文件放到新版本的redis当中不一定能识别到如果确实要又一些升级版本的需要就可以通过程序直接遍历旧的redis当中的所有key将数据取出来插入到新的redis服务器当中
RDB最大的问题就是不能实时的持久化保存数据在两次生成快照之间实时的数据可能会随着重启而丢失
例如配置文件当中save 60 10000代表的含义就是两次生成rdb之间的间隔最少是60s并且需要执行10000次操作以上才会触发。
假设12:00:00生成了rdb文件此时硬盘的那个字的快照数据和内存当中的一样从12:00:01开始redis收到了大量的key的变化请求此时会在12:01:00生成下一个快照文件但是如果在12:00:01 ~ 12:01:00之间redis服务器挂了那么就会导致12:00:00之后的数据丢失了此时就需要使用AOF持久化方式来解决上述的问题
如果需要关闭自动生成快照只需要在配置文件当中改为save AOF实时备份
AOFAppend Only File持久化以独⽴⽇志的⽅式记录每次写命令把用户的每个操作都记录到文件当中redis重启时再重新执⾏ AOF ⽂件中的命令达到恢复数据的⽬的。AOF 的主要作⽤是解决了数据持久化的实时性⽬前已经是 Redis 持久化的主流⽅式
使用AOF
开启 AOF 功能需要设置配置appendonly yes默认不开启 如果开启了aof功能那么rdb功能就不生效了启动的时候不再去读取rdb文件的内容
AOF ⽂件名通过 appendfilename 配置默认是 appendonly.aof设置。保存⽬录同 RDB 持久化⽅式⼀致通过 dir 配置指定 AOF 的⼯作流程操作命令写⼊append、⽂件同步sync、⽂件重写 rewrite、重启加载loadAOF是一个文本文件每次进行的操作都会记录到文本文件当中通过一些特殊符号为分隔符来对命令的细节作出区分 命令写入
AOF 命令写⼊的内容直接是⽂本协议格式。例如 set hello world 这条命令在 AOF 缓冲区会追加如下 ⽂本
*3\r\n$3\r\nset\r\n$5\r\nhello\r\n$5\r\nworld\r\n此处遵守 Redis 格式协议Redis 选择⽂本协议可能的原因⽂本协议具备较好的兼容性实现简单 具备可读性 AOF工作流程 1.所有的写⼊命令会追加到 aof_buf缓冲区中
2.AOF 缓冲区根据对应的策略向硬盘做同步操作
3.随着 AOF ⽂件越来越⼤需要定期对 AOF ⽂件进⾏重写达到压缩的⽬的
4.当 Redis 服务器启动时可以加载 AOF ⽂件进⾏数据恢复 问引入了AOF之后redis既要学内存又要写硬盘速度还能和之前一样快吗 实际上AOF机制并没有影响到redis处理请求的速度
1因为AOF机制并非是直接让工作线程把数据写入硬盘而是先写入一个内存当中的缓冲区积累一部分内容之后再统一写入硬盘就能大大降低写硬盘的次数。 写硬盘的时候写入硬盘数据的多少对于性能影响没有多大但是写入硬盘的次数则影响很大
2硬盘上读写数据顺序读写的速度是比较快的但是还是比内存要慢但是在硬盘上随机访问的速度是比较慢的而AOF是每次把新的操作写入到原有文件的末尾属于是顺序写入
注意因为是先把数据写入到缓冲区当中本质上还是在内存当中如果这个时候进程挂了或者主机掉电了此时缓冲区当中没有来得及写入硬盘的数据是会丢失的
redis给出了一些选项根据实际情况来决定取舍也就是缓冲区的刷新策略
刷新频率越高性能影响越大同步数据的可靠性越高刷新频率越低性能影响越小同步数据的可靠性越低 文件同步
Redis 提供了多种 AOF 缓冲区同步⽂件策略由参数 appendfsync 控制 可配置项说明说明always命令写⼊ aof_buf 后调⽤ fsync 同步完成后返回频率最高数据可靠性最高性能最低everysec命令写⼊aof_buf 后只执⾏ write 操作不进行fsync每秒由同步线程进行fsync频率低一些数据可靠性降低性能提高no命令写⼊ aof_buf 后只执⾏ write 操作由OS控制fsync频率频率最低数据可靠性最低性能最高 系统调⽤ write 和 fsync 说明 1.write 操作会触发延迟写delayed write机制。Linux 在内核提供⻚缓冲区⽤来提供硬盘 IO 性 能。write 操作在写⼊系统缓冲区后⽴即返回。同步硬盘操作依赖于系统调度机制例如缓冲区 ⻚空间写满或达到特定时间周期。同步⽂件之前如果此时系统故障宕机缓冲区内数据将丢失
2.Fsync 针对单个⽂件操作做强制硬盘同步fsync 将阻塞直到数据写⼊到硬盘
3.配置为 always 时每次写⼊都要同步 AOF ⽂件性能很差在⼀般的 SATA 硬盘上只能⽀持⼤ 约⼏百 TPS 写⼊。除⾮是⾮常重要的数据否则不建议配置
4.配置为 no 时由于操作系统同步策略不可控虽然提⾼了性能但数据丢失⻛险⼤增除⾮数据 重要程度很低⼀般不建议配置
5.配置为 everysec是默认配置也是推荐配置兼顾了数据安全性和性能。理论上最多丢失 1 秒的 数据 重写机制
随着命令不断写⼊ AOF⽂件会越来越⼤会影响redis下次启动的时间因为redis启动要读取aof文件的内容为了解决这个问题Redis 引⼊ AOF 重写机制压缩文件体积
AOF ⽂件重写是把 Redis 进程内的数据转化为写命令同步到新的 AOF ⽂件因为原来的aof文件还记录了中间的过程然而实际上redis在重新启动的时候只关注最终结果较⼩的 AOF ⽂件⼀⽅⾯降低了硬盘空间占⽤还可以提升启动 Redis 时数据恢复的速度 重写后的 AOF文件为什么可以变⼩ 进程内已超时的数据不再写⼊⽂件旧的 AOF 中的⽆效命令例如 del、hdel、srem 等重写后将会删除只需要保留数据的最终版本多条写操作合并为⼀条例如 lpush list a、lpush list b、lpush list c 从可以合并为 lpush list a b c 剔除冗余操作合并一些操作减小aof文件的占用空间 重写触发机制
AOF 重写过程可以⼿动触发和⾃动触发 ⼿动触发调⽤ bgrewriteaof 命令 ⾃动触发根据 auto-aof-rewrite-min-size 和 auto-aof-rewrite-percentage 参数确定⾃动触发时机 auto-aof-rewrite-min-size表⽰触发重写时 AOF 的最⼩⽂件⼤⼩默认为 64MBauto-aof-rewrite-percentage代表当前 AOF 占⽤⼤⼩相⽐较上次重写时增加的⽐例 AOF进制重写流程 1.执⾏ AOF 重写请求
如果当前进程正在执⾏ AOF 重写请求不执⾏。如果当前进程正在执⾏ bgsave 操作生成rdb快照文件此时aof重写操作就会等待等待 bgsave 完成之后再执⾏aof重写
2.⽗进程执⾏ fork 创建⼦进程父进程仍然负责接收请求子进程负责针对aof文件进行重写
3.重写
主进程 fork 之后继续响应其他命令。所有新来的修改操作写⼊ AOF 缓冲区并根据 appendfsync 策 略同步到硬盘再刷新到原来的AOF文件当中保证旧 AOF ⽂件机制正确⼦进程里的内存数据是父进程fork之前的状态fork之后新来的请求对内存造成的修改子进程是不知道的⽗进程中需要将 fork 之后这段时间的修改操作写⼊ AOF 重写缓冲区aof_rewrite_buf中专门用户存放fork之后收到的数据
4.⼦进程根据内存快照将命令合并到新的 AOF ⽂件中
注意重写的时候不关心原来的aof文件只是关心内存当中最终的数据状态子进程只需要把内存当中的数据获取出来以AOF的格式写入到一个新的AOF文件当中内存当中的数据的状态就相当于是把AOF文件结果整理后的样子
5.⼦进程完成重写
新⽂件写⼊后⼦进程发送信号给⽗进程父进程把 AOF重写缓冲区内临时保存的命令追加到新 AOF ⽂件中⽤新 AOF ⽂件替换⽼ AOF ⽂件 注意父进程fork之后就已经让子进程写新的aof文件了并且随着时间推移子进程很快就写完了新的文件要让新的aof文件代替旧的但是父进程此时还在继续写这个即将消亡的进的aof文件此时是否还有意义
不能不写要考虑极端情况假设在重写的过程当中重写到一半服务器挂了此时子进程内存的数据就会丢失新的aof文件内容还不完整如果父进程不坚持写aof文件此时重启服务器的时候就没办法保证数据的完整性了 混合持久化
AOF本来是按照文本的方式写入文件的但是文本的方式写入文件后续加载的成本比较高所以redis就引入了混合持久化的方式结合了rdb和aof的特点
按照aof的方式每一个请求/操作都记录到文件当中在触发aof重写之后就会把当前内存的状态按照rdb的二进制格式写入到新的aof文件当中后续再进行的操作仍然是按照aof文本的形式追加到文件的后面 在配置文件当中这个选项为yes表示开启混合持久
注意如果当redis上同时存在aof文件和rdb快照的时候以aof文件为主此时rdb快照就直接被忽略了
这是因为AOF中包含的数据比RDB更全
启动时数据恢复
当 Redis 启动时会根据 RDB 和 AOF ⽂件的内容进⾏数据恢复 Redis 根据持久化⽂件进⾏数据恢复 总结
1.RDB 视为内存的快照产⽣的内容更为紧凑占⽤空间较⼩恢复时速度更快。但产⽣ RDB 的开 销较⼤不适合进⾏实时持久化⼀般⽤于冷备和主从复制
2.AOF 视为对修改命令保存在恢复时需要重放命令。并且有重写机制来定期压缩 AOF ⽂件
3.RDB 和 AOF 都使⽤ fork 创建⼦进程利⽤子进程拥有⽗进程内存快照的特点进⾏持久化 尽可能不影响主进程继续处理后续命令