2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

为什么 Redis 快照使用子进程 (三)

  • 2019-12-26
  • 本文字数:1404 字

    阅读完需:约 5 分钟

为什么 Redis 快照使用子进程 (三)

写时拷贝(Copy-on-Write)的出现就是为了解决这一问题,就像我们在这一节开头介绍的,写时拷贝的主要作用就是将拷贝推迟到写操作真正发生时,这也就避免了大量无意义的拷贝操作。在一些早期的 *nix 系统上,系统调用 fork 确实会立刻对父进程的内存空间进行复制,但是在今天的多数系统中,fork 并不会立刻触发这一过程:



fork 函数调用时,父进程和子进程会被 Kernel 分配到不同的虚拟内存空间中,所以在两个进程看来它们访问的是不同的内存:


  • 在真正访问虚拟内存空间时,Kernel 会将虚拟内存映射到物理内存上,所以父子进程共享了物理上的内存空间;

  • 当父进程或者子进程对共享的内存进行修改时,共享的内存才会以页为单位进行拷贝,父进程会保留原有的物理空间,而子进程会使用拷贝后的新物理空间;


在 Redis 服务中,子进程只会读取共享内存中的数据,它并不会执行任何写操作,只有父进程会在写入时才会触发这一机制,而对于大多数的 Redis 服务或者数据库,写请求往往都是远小于读请求的,所以使用 fork 加上写时拷贝这一机制能够带来非常好的性能,也让 BGSAVE 这一操作的实现变得非常简单。

总结

Redis 实现后台快照的方式非常巧妙,通过操作系统提供的 fork 和写时拷贝的特性轻而易举的就实现了这个功能,从这里我们就能看出作者对于操作系统知识的掌握还是非常扎实的,大多人在面对类似的场景时,想到的方法可能就是手动实现类似『写时拷贝』的特性,然而这不仅增加了工作量,还增加了程序出现问题的可能性。


到这里,我们简单总结一下 Redis 为什么在使用 RDB 进行快照时会通过子进程的方式进行实现:


  1. 通过 fork 创建的子进程能够获得和父进程完全相同的内存空间,父进程对内存的修改对于子进程是不可见的,两者不会相互影响;

  2. 通过 fork 创建子进程时不会立刻触发大量内存的拷贝,内存在被修改时会以页为单位进行拷贝,这也就避免了大量拷贝内存而带来的性能问题;


上述两个原因中,一个为子进程访问父进程提供了支撑,另一个为减少额外开销做了支持,这两者缺一不可,共同成为了 Redis 使用子进程实现快照持久化的原因。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • Nginx 的主进程会在运行时 fork 一组子进程,这些子进程可以分别处理请求,还有哪些服务会使用这一特性?

  • 写时拷贝其实是一个比较常见的机制,在 Redis 之外还有哪里会用到它?


如果对文章中的内容有疑问或者想要了解更多软件工程上一些设计决策背后的原因,可以在博客下面留言,作者会及时回复本文相关的疑问并选择其中合适的主题作为后续的内容。

Reference

相关文章


本文转载自 Draveness 技术博客。


原文链接:https://draveness.me/whys-the-design-redis-bgsave-fork


2019-12-26 17:271105

评论

发布
暂无评论
发现更多内容

架构优化与业务迭代,你会怎么选?

架构精进之路

软件开发

队列高级应用之设计一个高性能线程池

架构师修行之路

分布式 线程池 架构设计 架构师

领域驱动设计(DDD)实践之路(二):事件驱动与CQRS

vivo互联网技术

DDD 架构设计 CQRS

推荐一个替代印象笔记,onenote的神奇笔记!

申屠鹏会

笔记

告诉你如何同时拿到腾讯两个部门的offer?

我是程序员小贱

简谈Python3关键字nonlocal使用场景

wangkx

Python Python基础

我们未曾见过的世界,大到无法想象

wangkx

ios 极客 apple 苹果 软件推荐

大厂需要你的简历有这些内容!

我是程序员小贱

SpringBoot系列(四):SpringBoot特性_外部化配置(properties文件配置)

xcbeyond

Java 微服务 springboot

Rust竟然没有异常处理?

袁承兴

rust 异常 java异常处理

面试官:说下对cookie,session,Token的理解

Java小咖秀

Java 面试

憋再@官方了,头像加国旗,10行代码给你安排!

wangkx

Python python升级

浅谈技术管理者的角色认知与自我管理

Geek_37rwst

团队管理 管理 自我管理 技术管理

二叉查找树-增删查和针对重复数据的 Java 实现

多选参数

数据结构 算法 二叉树 数据结构与算法

troubleshoot之:分析OutOfMemoryError异常

程序那些事

Java JVM 异常 JIT

如何理解Python中的可迭代对象、迭代器和生成器

wangkx

Python python升级

简谈Python3中的闭包

wangkx

Python Python基础

架构师训练营 - 第 7 周学习总结

红了哟

一口气搞懂「文件系统」,就靠这 20 张图了

小林coding

操作系统 计算机基础 文件管理 文件存储 文件系统

HashMap、LinkedHashMap 学习笔记

Geek_vidmje

翻译: Effective Go (5)

申屠鹏会

翻译 Go 语言

你可能不知道的iPython使用技巧

wangkx

Python

神经网络激活函数为什么要使用非线性函数?

wangkx

神经网络 激活函数

非科班面试阿里,拼多多,银行都问了些啥?

我是程序员小贱

重点发布!河北行动计划发布!聚焦7大重点任务发展大数据产业

CECBC

区块链技术 落地应用 政策

如何做好技术选型

xcbeyond

Java 架构 最佳实践 技术选型

IT人的身体健康

隆隆

IT人健康

第10周总结+作业

林毋梦

简述Python中变量作用域的规则

wangkx

Python python升级 Python基础

图解JavaScript——代码实现(new、Object.create()、Object.assign()、flat()等十四种代码原理实现不香吗?)

执鸢者

Java 大前端 代码原理

敏捷软件工程实践书籍

Bob Jiang

敏捷 敏捷书籍 工程实践

为什么 Redis 快照使用子进程 (三)_语言 & 开发_Draveness_InfoQ精选文章