写点什么

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

  • 2019 年 12 月 26 日
  • 本文字数:1198 字

    阅读完需:约 4 分钟

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

子进程

在计算机编程领域,尤其是 Unix 和类 Unix 系统中,fork 都是一个进程用于创建自己拷贝的操作,它往往都是被操作系统内核实现的系统调用,也是操作系统在 *nix 系统中创建新进程的主要方法。



当程序调用了 fork 方法之后,我们就可以通过 fork 的返回值确定父子进程,以此来执行不同的操作:


  • fork 函数返回 0 时,意味着当前进程是子进程;

  • fork 函数返回非 0 时,意味着当前进程是父进程,返回值是子进程的 pid


C


int main() {    if (fork() == 0) {        // child process    } else {        // parent process    }}
复制代码


fork手册 中,我们会发现调用 fork 后的父子进程会运行在不同的内存空间中,当 fork 发生时两者的内存空间有着完全相同的内容,对内存的写入和修改、文件的映射都是独立的,两个进程不会相互影响。


The child process and the parent process run in separate memory spaces. At the time of fork() both memory spaces have the same content. Memory writes, file mappings (mmap(2)), and unmappings (munmap(2)) performed by one of the processes do not affect other.


除此之外,子进程几乎是父进程的完整副本(Exact duplicate),然而这两个进程在以下的一些方面会有较小的区别:


  • 子进程用于独立且唯一的进程 ID;

  • 子进程的父进程 ID 与父进程 ID 完全相同;

  • 子进程不会继承父进程的内存锁;

  • 子进程会重新设置进程资源利用率和 CPU 计时器;


最关键的点在于父子进程的内存在 fork 时是完全相同的,在 fork 之后进行写入和修改也不会相互影响,这其实就完美的解决了快照这个场景的问题 —— 只需要某个时间点下内存中的数据,而父进程可以继续对自己的内存进行修改,这既不会被阻塞,也不会影响生成的快照。


写时拷贝

既然父进程和子进程拥有完全相同的内存空间并且两者对内存的写入都不会相互影响,那么是否意味着子进程在 fork 时需要对父进程的内存进行全量的拷贝呢?假设子进程需要对父进程的内存进行拷贝,这对于 Redis 服务来说基本都是灾难性的,尤其是在以下的两个场景中:


  1. 内存中存储大量的数据,fork 时拷贝内存空间会消耗大量的时间和资源,会导致程序一段时间的不可用;

  2. Redis 占用了 10G 的内存,而物理机或者虚拟机的资源上限只有 16G,在这时我们就无法对 Redis 中的数据进行持久化,也就是说 Redis 对机器上内存资源的最大利用率不能超过 50%;


如果无法解决上面的两个问题,使用 fork 来生成内存镜像的方式也无法真正落地,不是一个工程中真正可以使用的方法。


就算脱离了 Redis 的场景,fork 时全量拷贝内存也是难以接受的,假设我们需要在命令行中执行一个命令,我们需要先通过 fork 创建一个新的进程再通过 exec 来执行程序,fork 拷贝的大量内存空间对于子进程来说可能完全没有任何作用的,但是却引入了巨大的额外开销。


本文转载自 Draveness 技术博客。


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


2019 年 12 月 26 日 17:27408

评论

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

QCon演讲| 从团伙到团队,PingCode研发团队敏捷实践血泪史

PingCode

敏捷 研发管理 研发效能 开发

汽车之家:基于 Flink + Iceberg 的湖仓一体架构实践

Apache Flink

flink

基于 Flink 打造的伴鱼实时计算平台 Palink 的设计与实现

Apache Flink

flink

对话吴军:人工智能如何推动金融行业的数字化转型

索信达控股

人工智能 大数据 金融科技 数字化转型 金融

JAVA中的浮点数与二进制

加百利

Java 后端 二进制 6月日更

并发王者课-青铜9:防患未然-如何处理线程中的异常

MetaThoughts

Java 多线程 并发

奇亚矿机系统,Bzz分币系统,云算力APP开发

2021年马士兵老师1000道Java大厂面试真题视频解析+笔记+源码

Java架构追梦

Java 架构 面试 马士兵

都啥年代了,求你别再说Redis是单线程了!

Java redis 编程 程序员

36氪企服点评|中国企服软件金榜-项目管理系列榜单揭晓,Worktile夺魁!

PingCode

项目管理 研发管理 研发工具 项目管理工具

一文你带快速认识Vue-Router路由

华为云开发者联盟

html Vue vue-router 路由 路由管理器

6月18日华为云携手中科院上海药物所,深度解读AI药物研发技术

华为云开发者联盟

AI 华为云 药物 TechWave EIHealth

「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之EXCEL数据导入(九)

crudapi

Vue crud crudapi qusar 数据导入

液体测量技术:从水到血液

不脱发的程序猿

物联网 液体测量技术 测量技术 ADI

【布道API】API端点/资源命名最佳实践

devpoint

RESTful Rest API 6月日更

百度大规模Service Mesh落地实践

百度Geek说

Service Mesh 软件架构

PHP ppa 不再支持过时的 Ubuntu 16.04,请立即升级 20.04

大龄程序员老羊

php ubuntu 架构 DevOps

我的编辑器能玩贪吃蛇,一起玩不?

华为云开发者联盟

大前端 编辑器 贪吃蛇 Blot Quill

淘宝“618”双11系统架构是如何设计的呢?这份Java千亿级并发系统架构设计笔记告诉你答案

Java 程序员 架构 计算机

Hi,HarmonyOS!融云全系产品已成功适配鸿蒙 OS 2.0

融云 RongCloud

竞赛|数据竞赛Top解决方案开源整理

不脱发的程序猿

开源 数据竞赛

5分钟带你玩转国内首款研发自动化工具PingCode Flow

PingCode研发中心

研发管理 研发效能 自动化管理 研发工具

网络攻防学习笔记 Day40

穿过生命散发芬芳

网络攻防 6月日更

【世界海洋日】TcaplusDB号召你一同保护海洋生物多样性

TcaplusDB

数据库 nosql tencentdb TcaplusDB

阿里最新发布的 Spring Cloud ALiBaBa 全解第三版,一睹庐山真面目!

Java 程序员 架构 微服务

WebRTC 用例和性能

anyRTC开发者

音视频 WebRTC RTC sdk

并发王者课-青铜10:千锤百炼-如何解决生产者与消费者经典问题

MetaThoughts

Java 多线程 并发

TcaplusDB祝大家端午安康!

TcaplusDB

数据库 nosql tencentdb TcaplusDB

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