在 2025 收官前,看清 Data + AI 的真实走向,点击查看 BUILD 大会精华版 了解详情
写点什么

为什么 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:271141

评论

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

如何监控Nginx的upstream后端server

运维研习社

nginx 负载均衡 zabbi

我的配置中心知识整理

老白鹿

微服务 技术选型 配置中心 配置管理

Selenium 常用方法与属性、鼠标悬停与 Select 操作

梦想橡皮擦

Python 28天写作 2月春节不断更

New转乾坤——云网融合真正的打开方式!

脑极体

Mybatis【20】-- Mybatis延迟加载怎么处理?

秦怀杂货店

数据库 缓存 mybatis 加载

工业互联网助力数字中国建设(新论)

工业互联网

第5周作业_贷款申请流程图

园子

互联网金融

MYSQL 索引篇(上)

new life

MySQL性能优化 执行计划 MySQL使用 索引性能

Kafka.05 - 生产者与消费者介绍

insight

kafak 2月春节不断更

【进阶】面试官问我Chrome浏览器的渲染原理(6000字长文)

我是哪吒

学习 程序员 chorme 28天写作 2月春节不断更

MYSQL 索引篇(下)

new life

MySQL MySQL性能优化 多字段联合验证 索引性能

压力太大的话,就放点气儿吧

道伟

28天写作

什么容易被记住——造梦师指南

Justin

心理学 28天写作 游戏设计

上天的源码要不要——GitHub 热点速览 v.21.08

HelloGitHub

Python GitHub 开源 Go 语言

基于matlab的控制系统与仿真2-传递函数模型

AXYZdong

matlab 2月春节不断更

go get下载包失败问题

happlyfox

28天写作 2月春节不断更 Go 语言

如何解决深度推荐系统中的Embedding冷启动问题?

王喆

机器学习 深度学习 推荐系统 计算广告 Embedding

“云原生”的应用价值及关键属性解读

这些面试题你会吗?连续四年百度Android岗必问面试题!深度好文

欢喜学安卓

android 程序员 面试 移动开发

透彻解析!在字节跳动我是如何当面试官的,讲的明明白白!

欢喜学安卓

android 程序员 面试 移动开发

透彻解析!如何快速的开发一个完整的直播app,薪资翻倍

欢喜学安卓

android 程序员 面试 移动开发

【管理笔记11】优秀人才的十二个特质

L3C老司机

28天写作

聊聊如何做好计划

数列科技杨德华

28天写作

程序员心中的一道坎:主存的编址与计算和串并联系统!

冰河

程序员 操作系统 计算 编址 串并联系统

三、创建、更新和删除文档

Kylin

读书笔记 七日更 分布式数据库mongodb 二月春节不断更

lua 对象编程解读

程序员与厨子

lua 学习 编程

(28DW-S8-Day3) 比特币、 区块链是什么?

mtfelix

比特币 区块链 28天写作

28天瞎写的第二百四十一天:正念是不是迷信、玄学、神棍?

树上

冥想 28天写作 正念 迷信

遇见ZooKeeper:初识

Jackey

zookeeper

python爬虫-学习urllib和requests使用,模拟请求

大佬sam

二月春节不断更

Mybatis【19】-- Mybatis自关联多对多查询

秦怀杂货店

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