当前位置: 首页 > news >正文

珠海市企业网站制作平台视频网站建设方案书

珠海市企业网站制作平台,视频网站建设方案书,免费软件下载中心,企业微信小程序入口一、AOF#xff08;Append Only File#xff09; Redis 每执行一条写操作命令#xff0c;就把该命令以追加的方式写入到一个文件里#xff0c;然后重启 Redis 的时候#xff0c;先去读取这个文件里的命令#xff0c;并且执行它。 注意#xff1a;只会记录写操作命令Append Only File Redis 每执行一条写操作命令就把该命令以追加的方式写入到一个文件里然后重启 Redis 的时候先去读取这个文件里的命令并且执行它。 注意只会记录写操作命令读操作命令是不会被记录的因为没意义。 AOF 日志文件其实就是普通的文本我们可以通过 cat 命令查看里面的内容不过里面的内容如果不知道一定的规则的话可能会看不懂。 我这里以「set name mogu」命令作为例子Redis 执行了这条命令后记录在 AOF 日志里的内容如下: *3 $3 set $4 name $4 mogu我这里给大家解释下。 「*3」表示当前命令有三个部分每部分都是以「$数字」开头后面紧跟着具体的命令、键或值。然后这里的「数字」表示这部分中的命令、键或值一共有多少字节。例如「$3 set」表示这部分有 3 个字节也就是「set」命令这个字符串的长度。 不知道大家注意到没有Redis 是先执行写操作命令后才将该命令记录到 AOF 日志里的这么做其实有两个好处。 避免额外的检查开销。不会阻塞当前写操作命令的执行因为当写操作命令执行成功后才会将命令记录到 AOF 日志。 当然AOF 持久化功能也不是没有潜在风险。 执行写操作命令和记录日志是两个过程那当 Redis 在还没来得及将命令写入到硬盘时服务器发生宕机了这个数据就会有丢失的风险。前面说道由于写操作命令执行成功后才记录到 AOF 日志所以不会阻塞当前写操作命令的执行但是可能会给「下一个」命令带来阻塞风险。因为将命令写入到日志的这个操作也是在主进程完成的执行命令也是在主进程也就是说这两个操作是同步的。 认真分析一下其实这两个风险都有一个共性都跟「 AOF 日志写回硬盘的时机」有关。 1.1 过程分析 Redis 写入 AOF 日志的过程 Redis 执行完写操作命令后会将命令追加到 server.aof_buf 缓冲区然后通过 write() 系统调用将 aof_buf 缓冲区的数据写入到 AOF 文件此时数据并没有写入到硬盘而是拷贝到了内核缓冲区 page cache等待内核将数据写入硬盘具体内核缓冲区的数据什么时候写入到硬盘由内核决定。 如下图所示。 1.2 三种写回硬盘的策略 在 redis.conf 配置文件中的 appendfsync 配置项可以有以下 3 种参数可填 Always这个单词的意思是「总是」所以它的意思是每次写操作命令执行完后同步将 AOF 日志数据写回硬盘可以最大程度保证数据不丢失但不可避免会影响主进程的性能。Everysec这个单词的意思是「每秒」所以它的意思是每次写操作命令执行完后先将命令写入到 AOF 文件的内核缓冲区然后每隔一秒将缓冲区里的内容写回到硬盘如果上一秒的写操作命令日志没有写回到硬盘发生了宕机这一秒内的数据会丢失。No意味着不由 Redis 控制写回硬盘的时机转交给操作系统控制写回的时机也就是每次写操作命令执行完后先将命令写入到 AOF 文件的内核缓冲区再由操作系统决定何时将缓冲区内容写回硬盘。相比于 Always 策略性能较好但是操作系统写回硬盘的时机是不可预知的如果 AOF 日志内容没有写回硬盘一旦服务器宕机就会丢失不定数量的数据。 这 三种写回策略都无法能完美解决「主进程阻塞」和「减少数据丢失」的问题只能根据自己的业务场景进行选择。 1.3 三种策略实现原理 看了源码后你就会发现这三种策略只是在控制 fsync() 函数的调用时机。 当应用程序向文件写入数据时内核通常先将数据复制到内核缓冲区中然后排入队列然后由内核决定何时写入硬盘。 如果想要应用程序向文件写入数据后能立马将数据同步到硬盘就可以调用 fsync() 函数这样内核就会将内核缓冲区的数据直接写入到硬盘等到硬盘写操作完成后该函数才会返回。 Always 策略就是每次写入 AOF 文件数据后就执行 fsync() 函数Everysec 策略就会创建一个异步任务来执行 fsync() 函数No 策略就是永不执行 fsync() 函数; 1.4 重写机制 例子如果我们执行了1W遍的set name #随机值#。按照日志记录是不是有记录1W条命令记录到AOF文件中。如果写1百万次呢就记录1百万条记录AOF会越来越大效率会越来越低。当 AOF 日志文件过大就会带来性能问题比如重启 Redis 后需要读 AOF 文件的内容以恢复数据如果文件过大整个恢复的过程就会很慢。 所以Redis 为了避免 AOF 文件越写越大提供了 AOF 重写机制当 AOF 文件的大小超过所设定的阈值后Redis 就会启用 AOF 重写机制来压缩 AOF 文件。 在使用重写机制后就会读取 name 最新的 value键值对 然后用一条 set name xxx 命令记录到新的 AOF 文件之前的第一个命令就没有必要记录了因为它属于「历史」命令没有作用了。这样一来一个键值对在重写日志中只用一条命令就行了。 重写工作完成后就会将新的 AOF 文件覆盖现有的 AOF 文件这就相当于压缩了 AOF 文件使得 AOF 文件体积变小了。 然后在通过 AOF 日志恢复数据时只用执行这条命令就可以直接完成这个键值对的写入了。 所以重写机制的妙处在于尽管某个键值对被多条写命令反复修改最终也只需要根据这个「键值对」当前的最新状态然后用一条命令去记录键值对代替之前记录这个键值对的多条命令这样就减少了 AOF 文件中的命令数量。 总结AOF 重写机制是在重写时读取当前数据库中的所有键值对然后将每一个键值对用一条命令记录到「新的 AOF 文件」等到全部记录完后就将新的 AOF 文件替换掉现有的 AOF 文件。 为什么重写 AOF 的时候不直接复用现有的 AOF 文件而是先写到新的 AOF 文件再覆盖过去。 因为如果 AOF 重写过程中失败了现有的 AOF 文件就会造成污染可能无法用于恢复使用。 1.5 后台重写 写入 AOF 日志的操作虽然是在主进程完成的因为它写入的内容不多所以一般不太影响命令的操作。但是在触发 AOF 重写时比如当 AOF 文件大于 64M 时就会对 AOF 文件进行重写这时是需要读取所有缓存的键值对数据并为每个键值对生成一条命令然后将其写入到新的 AOF 文件重写完后就把现在的 AOF 文件替换掉。这个过程其实是很耗时的所以重写的操作不能放在主进程里。因此Redis 的重写 AOF 过程是由后台子进程 bgrewriteaof 来完成的 好处 子进程进行 AOF 重写期间主进程可以继续处理命令请求从而避免阻塞主进程子进程带有主进程的数据副本数据副本怎么产生的后面会说这里使用子进程而不是线程因为如果是使用线程多线程之间会共享内存那么在修改共享内存数据的时候需要通过加锁来保证数据的安全而这样就会降低性能。而使用子进程创建子进程时父子进程是共享内存数据的不过这个共享的内存只能以只读的方式而当父子进程任意一方修改了该共享内存就会发生「写时复制」于是父子进程就有了独立的数据副本就不用加锁来保证数据安全。 子进程是怎么拥有主进程一样的数据副本的呢 主进程在通过 fork 系统调用生成 bgrewriteaof 子进程时操作系统会把主进程的「页表」复制一份给子进程这个页表记录着虚拟地址和物理地址映射关系而不会复制物理内存也就是说两者的虚拟空间不同但其对应的物理空间是同一个。 这样一来子进程就共享了父进程的物理内存数据了这样能够节约物理内存资源页表对应的页表项的属性会标记该物理内存的权限为只读。 不过当父进程或者子进程在向这个内存发起写操作时CPU 就会触发写保护中断这个写保护中断是由于违反权限导致的然后操作系统会在「写保护中断处理函数」里进行物理内存的复制并重新设置其内存映射关系将父子进程的内存读写权限设置为可读写最后才会对内存进行写操作这个过程被称为「写时复制(Copy On Write)」在发生写操作的时候操作系统才会去复制物理内存。 这样是为了防止 fork 创建子进程时**由于物理内存数据的复制时间过长而导致父进程长时间阻塞的问题。如果父进程的内存数据非常大那自然页表也会很大这时父进程在通过 fork 创建子进程的时候阻塞的时间也越久。 所以有两个阶段会导致阻塞父进程 创建子进程的过程中阻塞的时间跟页表的大小有关页表越大阻塞的时间也越长创建完子进程后如果子进程或者父进程修改了共享数据就会发生写时复制这期间会拷贝物理内存如果内存越大自然阻塞的时间也越长 还有个问题重写 AOF 日志过程中如果主进程修改了已经存在 key-value此时这个 key-value 数据在子进程的内存数据就跟主进程的内存数据不一致了这时要怎么办呢 为了解决这种数据不一致问题Redis 设置了一个 AOF 重写缓冲区这个缓冲区在创建 bgrewriteaof 子进程之后开始使用。 在重写 AOF 期间当 Redis 执行完一个写命令之后它会同时将这个写命令写入到 「AOF 缓冲区」和 「AOF 重写缓冲区」。 也就是说在 bgrewriteaof 子进程执行 AOF 重写期间主进程需要执行以下三个工作: 执行客户端发来的命令将执行后的写命令追加到 「AOF 缓冲区」将执行后的写命令追加到 「AOF 重写缓冲区」 当子进程完成 AOF 重写工作扫描数据库中所有数据逐一把内存数据的键值对转换成一条命令再将命令记录到重写日志后会向主进程发送一条信号信号是进程间通讯的一种方式且是异步的。主进程收到该信号后会调用一个信号处理函数该函数主要做以下工作 将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中使得新旧两个 AOF 文件所保存的数据库状态一致新的 AOF 的文件进行改名覆盖现有的 AOF 文件。 信号函数执行完后主进程就可以继续像往常一样处理命令了。 在整个 AOF 后台重写过程中除了发生写时复制会对主进程造成阻塞还有信号处理函数执行时也会对主进程造成阻塞在其他时候AOF 后台重写都不会阻塞主进程。 二、RDB快照 所谓的快照就是记录某一个瞬间东西比如当我们给风景拍照时那一个瞬间的画面和信息就记录到了一张照片。 所以RDB 快照就是记录某一个瞬间的内存数据记录的是实际数据而 AOF 文件记录的是命令操作的日志而不是实际的数据。 因此在 Redis 恢复数据时 RDB 恢复数据的效率会比 AOF 高些因为直接将 RDB 文件读入内存就可以不需要像 AOF 那样还需要额外执行操作命令的步骤才能恢复数据。 Redis 提供了两个命令来生成 RDB 文件分别是 save 和 bgsave他们的区别就在于是否在「主线程」里执行 ● 执行了 save 命令就会在主线程生成 RDB 文件由于和执行操作命令在同一个线程所以如果写入 RDB 文件的时间太长会阻塞主线程 ● 执行了 bgsave 命令会创建一个子进程来生成 RDB 文件这样可以避免主线程的阻塞 RDB 文件的加载工作是在服务器启动时自动执行的Redis 并没有提供专门用于加载 RDB 文件的命令。 只要满足上面条件的任意一个就会执行 bgsave它们的意思分别是 ● 900 秒之内对数据库进行了至少 1 次修改 ● 300 秒之内对数据库进行了至少 10 次修改 ● 60 秒之内对数据库进行了至少 10000 次修改。 这里提一点Redis 的快照是全量快照也就是说每次执行快照都是把内存中的「所有数据」都记录到磁盘中。 所以可以认为执行快照是一个比较重的操作如果频率太频繁可能会对 Redis 性能产生影响。如果频率太低服务器故障时丢失的数据会更多。 通常可能设置至少 5 分钟才保存一次快照这时如果 Redis 出现宕机等情况则意味着最多可能丢失 5 分钟数据。 这就是 RDB 快照的缺点在服务器发生故障时丢失的数据会比 AOF 持久化的方式更多因为 RDB 快照是全量快照的方式因此执行的频率不能太频繁否则会影响 Redis 性能而 AOF 日志可以以秒级的方式记录操作命令所以丢失的数据就相对更少。 执行快照时数据能被修改了怎么办 执行 bgsave 过程中由于是交给子进程来构建 RDB 文件主线程还是可以继续工作的此时主线程可以修改数据吗 如果不可以修改数据的话那这样性能一下就降低了很多。如果可以修改数据又是如何做到到呢 那具体如何做到到呢关键的技术就在于写时复制技术Copy-On-Write, COW。 执行 bgsave 命令的时候会通过 fork() 创建子进程此时子进程和父进程是共享同一片内存数据的因为创建子进程的时候会复制父进程的页表但是页表指向的物理内存还是一个。只有在发生修改内存数据的情况时物理内存才会被复制一份。 这样的目的是为了减少创建子进程时的性能损耗从而加快创建子进程的速度毕竟创建子进程的过程中是会阻塞主线程的。 所以创建 bgsave 子进程后由于共享父进程的所有内存数据于是就可以直接读取主线程父进程里的内存数据并将数据写入到 RDB 文件。 当主线程父进程对这些共享的内存数据也都是只读操作那么主线程父进程和 bgsave 子进程相互不影响。 但是如果主线程父进程要修改共享数据里的某一块数据比如键值对 A时就会发生写时复制于是这块数据的物理内存就会被复制一份键值对 A’然后主线程在这个数据副本键值对 A’进行修改操作。与此同时bgsave 子进程可以继续把原来的数据键值对 A写入到 RDB 文件。 就是这样Redis 使用 bgsave 对当前内存中的所有数据做快照这个操作是由 bgsave 子进程在后台完成的执行时不会阻塞主线程这就使得主线程同时可以修改数据。 所以bgsave 快照过程中如果主线程修改了共享数据发生了写时复制后RDB 快照保存的是原本的内存数据而主线程刚修改的数据是没办法在这一时间写入 RDB 文件的只能交由下一次的 bgsave 快照。因此如果主线程修改了内存数据不管是否是共享的内存数据RDB 快照都无法写入主线程刚修改的数据因为此时主线程父进程的内存数据和子进程的内存数据已经分离了子进程写入到 RDB 文件的内存数据只能是原本的内存数据。如果系统恰好在 RDB 快照文件创建完毕后崩溃了那么 Redis 将会丢失主线程在快照期间修改的数据。 另外写时复制的时候会出现这么个极端的情况。 在 Redis 执行 RDB 持久化期间刚 fork 时主进程和子进程共享同一物理内存但是途中主进程处理了写操作修改了共享内存于是当前被修改的数据的物理内存就会被复制一份。 那么极端情况下如果所有的共享内存都被修改则此时的内存占用是原先的 2 倍。 所以针对写操作多的场景我们要留意下快照过程中内存的变化防止内存被占满了。 三、RDB 和 AOF 合体 尽管 RDB 比 AOF 的数据恢复速度快但是快照的频率不好把握 ● 如果频率太低两次快照间一旦服务器发生宕机就可能会比较多的数据丢失 ● 如果频率太高频繁写入磁盘和创建子进程会带来额外的性能开销。 那有没有什么方法不仅有 RDB 恢复速度快的优点和又有 AOF 丢失数据少的优点呢 当然有那就是将 RDB 和 AOF 合体使用这个方法是在 Redis 4.0 提出的该方法叫混合使用 AOF 日志和内存快照也叫混合持久化。 如果想要开启混合持久化功能可以在 Redis 配置文件将下面这个配置项设置成 yes aof-use-rdb-preamble yes 混合持久化工作在 AOF 日志重写过程。 当开启了混合持久化时在 AOF 重写日志时fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件然后主线程处理的操作命令会被记录在重写缓冲区里重写缓冲区里的增量命令会以 AOF 方式写入到 AOF 文件写入完成后通知主进程将新的含有 RDB 格式和 AOF 格式的 AOF 文件替换旧的的 AOF 文件。 也就是说使用了混合持久化AOF 文件的前半部分是 RDB 格式的全量数据后半部分是 AOF 格式的增量数据。 这样的好处在于重启 Redis 加载数据的时候由于前半部分是 RDB 内容这样加载的时候速度会很快。 加载完 RDB 的内容后才会加载后半部分的 AOF 内容这里的内容是 Redis 后台子进程重写 AOF 期间主线程处理的操作命令可以使得数据更少的丢失。
http://www.dnsts.com.cn/news/154978.html

相关文章:

  • 成都网页设计公司推荐泉州百度seo公司
  • 资阳网站建设公司怎么注册网站网址
  • 建设银行在网站上开通短信提醒东莞手机建网站
  • 什么做网站站群什么值得买网站模版
  • 网站建设海南怎么在wordpress免费注册博客网站
  • 公司网站谁负责做个人网页制作总结
  • 无锡网站建设 百家号wordpress 在线游戏网站
  • 深圳网站建设服务联系方式聊城专业做网站
  • 小程序开发教程 下载安徽百度关键词优化
  • 做战袍网站江西中慧城乡建设开发公司网站
  • 搭建电商网站源码wordpress文章 404
  • 长春企业网站建设价格我的家乡网页制作素材
  • 盘锦门户网站制作十大免费ppt网站下载
  • 网站建设氺首选金手指14Wordpress企业主题XShuan
  • 天津网站建设技术托管商标与logo的区别
  • 做网站郴州网站设计的公司价格
  • 自备服务器做网站工作室网站源码php
  • 做做网站已更新朝阳网站建设怎么样
  • 免费绑定域名的建站高端网站建设流行风
  • 网站开发技术文档范例给别人做设计的网站
  • 学校网站建设与管理办法wordpress 安装主题
  • flash开发网站上海网站建设服务站霸网络
  • 郑州做网站元辰企业网站变成app的方法
  • 网站推广计划机构河南工程建设信息网查
  • 外贸网站适合用数字域名吗阿里巴巴国际站特点
  • 淘宝网站建设预算表网页ui设计培训
  • wordpress模板 微信网络优化策划书
  • 公司网站建设排名wordpress 下载的还是旧文件
  • 汕头市网站建设蓝天使网站建设
  • 寻找昆明网站建设Wordpress手帐