phpcms 网站栏目,seo外链发布工具,旅游网站官网,哈尔滨市工程建设网文章目录 Redis持久化Redis的两种持久化的策略定期备份#xff1a;RDB触发机制rdb的触发时机#xff1a;手动执行savebgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置#xff0c;自动生成rdb快照RDB的优缺点 实时备份#xff1a;AOFAOF是否会影响到red… 文章目录 Redis持久化Redis的两种持久化的策略定期备份RDB触发机制rdb的触发时机手动执行savebgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置自动生成rdb快照RDB的优缺点 实时备份AOFAOF是否会影响到redis的性能AOF的重写机制重写触发方式AOF重写的流程 总结 Redis持久化
在这之前要提及到Mysql的事务的四个比较核心的特性 原子性 一致性 持久性 隔离性 这里mysql的持久性就是把数据存储在硬盘上而redis数据是存在内存里的要想做到持久就需要让redis把数据存储到硬盘上
Redis相比于Mysql这样的关系型数据库最明显的特点/优势就是 快所以为了保证速度快数据肯定还是得在内存中但是为了持久数据还得办法存储在硬盘上 Redis决定 内存中也存数据硬盘上也存数据这样的两份数据理论上是完全相同的 当要插入一个新的数据的时候就需要把这个数据同时写入到内存和硬盘说是两边都写但是实际上具体怎么写硬盘还有不同的策略可以保证整体的效率还是足够的高当查询某个数据的时候直接从内存读取硬盘的数据只是在redsi重启的时候用来恢复内存中的数据代价就是消耗了更多的空间同一份数据存储了两遍但是毕竟硬盘比较便宜这样的开销并不会带来太多的成本 Redis的两种持久化的策略 RDB Redis DataBase 定期备份每隔一段时间进行一次备份AOF Append Only File 实时备份只要有数据变动立即备份 定期备份RDB
RDB 持久化是把当前进程数据生成快照保存到硬盘的过程触发 RDB 持久化过程分为手动触发和自动触发。
触发机制
手动触发通过redis客户端执行特定的命令来执行快照生成 (手动触发分别对应 save 和 bgsave 命令) • save 命令阻塞当前 Redis 服务器直到 RDB 过程完成为止对于内存比较大的实例造成长时间阻塞基本不采用。 • bgsave 命令Redis 进程执行 fork 操作创建子进程RDB 持久化过程由子进程负责完成后自动结束。阻塞只发生在 fork 阶段⼀般时间很短。 Redis 内部的所有涉及 RDB 的操作都采用类似 bgsave 的方式。 执行 bgsave 命令Redis 父进程判断当前进是否存在其他正在执行的子进程如 RDB/AOF 子进 程如果存在 bgsave 命令直接返回。父进程执行 fork 创建子进程fork 过程中父进程会阻塞通过 info stats 命令查看latest_fork_usec 选项可以获取最近⼀次 fork 操作的耗时单位为微秒。父进程 fork 完成后bgsave 命令返回 “Background saving started” 信息并不再阻塞父进程可以继续响应其他命令。子进程创建 RDB 文件根据父进程内存生成临时快照文件完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后⼀次生成 RDB 的时间对应 info 统计的 rdb_last_save_time 选项。进程发送信号给父进程表⽰完成父进程更新统计信息。 自动触发在Redis配置文件中设置一下让Redis每隔多长时间/每产生多少次修改 就触发
Redis生成的RDB文件是存放在redis的工作目录中的也是在redis的配置文件中进行设置的 这里的dump.rdb文件,就是rdb机制生成的镜像文件redis服务器默认就是开启了rdb的这个镜像文件是一个二进制的文件把内存中的数据以压缩的形式保存到这个二进制文件中 后续redis服务器重新启动就会尝试加载这个rdb文件如果发现格式有错误就可能会加载数据失败 rdb文件虽然我们没有主动去动他但是也有可能会出现一些意外问题一旦通过一些操作比如网络传输引起这个文件被破坏此时redis服务器就无法启动 redis提供了rdb文件的检查工具 redis-check-rdb 查看一下RDB文件里面是什么内容 里面都是二进制内容当我们对redis文件中的数据进行增删查改时这里的RDB文件并不会立即更新
rdb的触发时机
手动savebgsave自动配置文件中进行设置 save //seconds之内至少存在changes次key的修改 虽然此处的这些数值都可以自由修改配置但是此处修改上述数据的时候要有一个基本规则 生成一次rdb快照这个成本是一个比较高的成本不能让这个操作执行的太频繁 正因为rdb不能生成的太频繁这就导致快照里的数据和当前实时的数据情况可能会存在偏差 save 60 10000 两次生成rdb之间的间隔至少得是60s 假设当前 12:00:00生成了rdb硬盘上的快照数据和内存中一致 12:00:01开始redis收到了大量的key的变化请求 12:01:00生成下一个快照文件 在上述过程之间redis服务器挂了此时就会导致12:00:00之后的这些数据就丢了数新的据只是在内存里还没存到rdb 手动执行savebgsave保存测试 由于这里执行的数据比较少所以瞬间就完成了立即查看应该是有结果的如果数据比较多执行bgsave就需要消耗一定的时间立即查看不一定就是生成完毕了 保存后查看rdb文件可以看到已经发生了修改 持久化验证可以看到通过上述操作redis服务器在重新启动的时候加载了rdb文件的内容恢复了内存中之前的状态 redis生成快照操作不仅仅是手动执行命令才触发也可以自动触发~ 通过配置文件中save执行M时间内修改N次…通过shotdown命令redis里的一个命令关闭redis服务器也会触发redis进行主从复制的时候主节点也会自动生成rdb快照然后把rdb快照文件内容传输给从节点 不手动执行bgsave测试 插入新的key不手动执行bgsave重新启动redis服务器 如果是通过正常流程重新启动redis服务器此时redis服务器会在退出的时候自动触发生成rdb操作但是如果是异常重启比如kill -9或者服务器 掉电此时redis服务器来不及生成rdb内存中尚未保存在快照中的数据就会随着重启而丢失了 bgsave操作流程测试 bgsave操作流程是创建子进程子进程完成持久化操作持久化会把数据写入到新的文件中然后使用新的文件替换旧的文件 而子进程完成持久化的速度太快了数据少难以观察到子进程但是我们可以通过文件的inode来验证bgsave操作流程 在redis客户端执行bgsave后 可以看到Inode从18685044变为了18685080
通过配置自动生成rdb快照
这里执行flashall也会自动生成rdb快照 将时间设置为60秒 设置两次保存rdb 如果rdb文件故意改坏了会怎样
如果改的是结尾的位置基本没什么影响如果改的hi中间的位置那么redis服务器就会挂掉
redis提供了rdb文件的检查工具可以先通过检查工具检查一下rdb文件格式是否符合要求 运行的时候加入rdb文件作为命令行参数此时就是以检查工具的方式来运行不会真的启动redis服务器 redis-check-rdb dump.rdb RDB的优缺点 RDB 是⼀个紧凑压缩的二进制文件代表 Redis 在某个时间点上的数据快照。非常适用于备份全量复制等场景。比如每 6 小时执行 bgsave 备份并把 RDB 文件复制到远程机器或者文件系统中 如 hdfs用于灾备。 Redis 加载 RDB 恢复数据远远快于 AOF 的方式。 RDB 方式数据没办法做到实时持久化 / 秒级持久化。因为 bgsave 每次运行都要执行 fork 创建子进程属于重量级操作频繁执行成本过高。 RDB 文件使用特定二进制格式保存Redis 版本演进过程中有多个 RDB 版本兼容性可能有风险。
实时备份AOF Append Only File 类似于mysql的binlog会把用户的每个操作都记录到文件中当redis重新启动的时候就会读取这个aof文件中的内容用来恢复数据 将这个appendonly的属性设置为 yes后重启redis服务器这里我执行两次set命令后查看 /var/lib/redis目录下的文件发现多了一个文件appendonly.aof 由文件内容可以看到AOF是一个文本文件每次进行的操作都会被录到文本文件中通过一些特殊的符号作为分隔符来对命令的细节进行区分
AOF是否会影响到redis的性能 redis虽然是一个单线程的服务器但是速度很快引入AOF后又要写内存又要写硬盘还能和之前一样快了吗 实际上是没有影响的 AOF机制并非是直接让工作线程把数据直接写入硬盘而是先写入一个内存的缓冲区积累一波后再统一写入硬盘假设由100个请求100个请求一次写入硬盘比分100次写入一个请求要快得多写硬盘的时候写入硬盘的数据的多少对于性能影响没有很大但是写入硬盘的次数则影响很大 硬盘上读写数据顺序读写的速度是比较快的还是比内存要慢得多随机访问则速度是比较慢的而AOF是每次把新的操作写到原有文件的末尾属于 顺序写入 如果把数据写入缓冲区里本质还是在内存中万一这个时候进程突然挂了或者主机掉电了咋办是不是缓冲区中的数据就丢了 答案是的缓冲区没有来得及写入硬盘的数据会丢的 redis给出了一些选项让程序猿根据实际情况决定怎么取舍缓冲区的刷新策略 刷新频越越高性能影响就越大同时数据的可靠性就越高 刷新频率越低性能影响就越小数据的可靠性就越低~~ 可配置值说明取舍情况always命令写入aof_buf 后调用 fsync 同步完成后返回频率最高数据可靠性最高性能最低everysec命令写入aof_buf 后只执行 write 操作不进行 fsync。每秒由同步线程进行 fsync。频率低一些数据可靠性也会降低性能会提高no命令写入 aof_buf 后只执行 write 操作由 OS 控制 fsync 频率。频率最低数据可靠性也是最低的性能是最高的 通过配置文件可以看到redis默认是everysec策略
AOF的重写机制 AOF文件持续增长体积越来越大会影响到redis下次启动的启动时间redis启动的时候要读取aof文件的内容 redis存在一个机制能够对aof文件进行整理操作这个整理就是能够提出其中的冗余操作并且合并一些操作达到给aof文件瘦身这样的效果例如lpush 111 lpush 222 合并为 lpush 111 222
重写触发方式
手动触发调用bgrewriteaof命令自动触发根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。 auto-aof-rewrite-min-size表示触发重写时AOF的最小文件大小默认为64MBauto-aof-rewrite-percentage代表当前AOF占用大小相比较上次重写时增加的比例
AOF重写的流程 创建子进程fork父进程仍然负责接收请求子进程负责针对aof文件进行重写 注意 重写的时候不关心aof文件中原来都有啥只是关心内存中的最终的数据状态 子进程只需要把内存中当前的数据获取出来以AOF的格式写入到一个新的AOF文件中 此处子进程写数据的额过程非常类似于RDB生成一个镜像快照只不过RDB这里是按照二进制的方式来生成的AOF重写则是按照AOF这里的要求的文本格式来生成的 在创建子进程的一瞬间子进程就继承了当前父进程的内存状态因此子进程里的内存数据是父进程fork之前的状态fork之后新来的请求对内存造成的修改是子进程不知道的 此时父进程这里又准备额一个aof_rewrite_buf缓冲区专门放fork之后收到的数据子进程这边把aof数据写完之后会通过信号通知一下父进程父进程再把aof_rewrite_buf缓冲区中的内容也谢入到新AOF文件里 就可以用新的AOF文件代替旧的AOF文件了 如果在执行bgrewriteaof的时候当前redis已经正在进行aof重写了会咋样呢 ————此时不会再次执行aof重写直接就返回了
如果在执行bgrewriteaof的时候当前redis已经正在进行生成rdb文件快照会咋样呢 ——此时aof重写操作就会等待等待rdb快照生成完毕之后再进行执行aof重写
rdb对于fork之后的新数据就置之不理了aof则对于fork之后的新数据采取了aof_rewrite_buf缓冲区的方式来处理 父进程fork完毕之后就已经让子进程写心得aof文件了并且随着时间的推移子进程很快就写完了新的文件 要让新的aof文件代替旧的父进程此时还在继续写这个即将消亡的旧的aof文件是否还有意义 这里就要考虑到一种极端的情况 假设重写过程中,重写了一半服务器挂了子进程内存的数据就会丢失新的aof文件内容还不完整所以如果父进程不坚持写旧的aof文件重启就没法保证数据的完整性 打开aof文件可以看到所有的操作都被记录了下来 查看一下执行bgrewriteaof之前的aof文件信息 执行一下bgrewriteaof再查看aof文件信息 查看aof文件内容会发现已经变了 并且会变成二进制 为什么会变成二进制呢
AOF本来是按照文本的方式来写入文件的但是文本的写入方式后续的加载成本是很高的redis就引入了“混合持久化的方式”,结合了rdb和aof的特点。按照aof的方式每一个请求/操作都录入文件在触发aof重写之后就会把当前内存的状态按照rdb的二进制格式写入到新的aof文件中后续再进行操作仍然是按照aof文本的方式追加到文件后面的 在配置文件中可以选择是否开启混合持久化
当redis上同时存在aof文件和rdb快照的时候此时以谁为主以aof为主rdb直接被忽略了因为AOF中包含的数据比RDB更全 总结 Redis 提供了两种持久化方案RDB 和 AOF。 RDB 视为内存的快照产生的内容更为紧凑占用空间较小恢复时速度更快。但产生 RDB 的开 销较⼤不适合进行实时持久化⼀般用于冷备和主从复制。 AOF 视为对修改命令保存在恢复时需要重放命令。并且有重写机制来定期压缩 AOF 文件。 RDB 和 AOF 都使用 fork 创建⼦进程利用 Linux ⼦进程拥有⽗进程内存快照的特点进行持久化 尽可能不影响主进程继续处理后续命令。