COW技术性 Node

lxf2023-03-12 12:51:01

本文带大家了解一下COW(Copy-On-Write)技术性,介绍一下COW技术性 Node.js 的进程创建和文件复制的应用,希望能帮助到大家!

COW技术性 Node

COW 并不是乳牛,是 Copy-On-Write 的简称,这是一种是拷贝但是也不完全就是复制技术性。

一般来说拷贝便是建立出完全一样二份,二份是单独的:

COW技术性 Node

可是,有些时候拷贝这件事情没有太大的必需,一定可以重复使用以前的,此刻能够仅仅引入以前那份,写具体内容的时候才会去拷贝相对应的一部分具体内容。那样假如具体内容用以读得话,就免除了拷贝,而必要时写,才能真正的拷贝一些内容做改动。

COW技术性 Node

这就叫做“写时复制”,其实就是 Copy-On-Write。

基本原理非常简单,但在操作系统的代码优化和文件目录上却比较常见,Node.js 里也由于这种技术变“懒”了。

文中我们一起来探讨下 Copy-On-Write 在 Node.js 的进程创建和文件复制的应用。【强烈推荐学习培训:《nodejs 教程》】

文件复制

文件复制这件事情比较常见的构思便是彻底写一份同样的文件信息到另一个部位,但这样有几个问题:

  • 彻底写一份同样的具体内容,假如相同的文件复制了无数次,那样也建立同样的具体内容无数次么?太可惜磁盘空间了
  • 假如提到一半断电了怎么办?覆盖具体内容如何修复?

该怎么办呢?此刻电脑操作系统设计师就会想到 COW 技术性。

用 COW 技术进行文件复制之后轻松解决了上边几个问题:

  • 拷贝仅仅添加一个引入到以前内容,假如不改动并不能真真正正拷贝,仅有到第一次修改内容的时候才会去真真正正拷贝相对应的db块,这个就防止了很多磁盘空间的消耗。
  • 写文件的时候会先在另一个空余磁盘块做改动,等改动完以后才会拷贝到总体目标部位,这样才不会有关闭电源没法回退问题

在 Node.js 的 fs.copyFile 的 api 就可以使用 Copy-On-Write 方式

默认设置前提下,copyFile 会载入目标文件,遮盖原具体内容

const fsPromises = require('fs').promises;

(async function() {
  try {
    await fsPromises.copyFile('source.txt', 'destination.txt');
  } catch(e) {
    console.log(e.message);
  }
})();

可是能通过第三个主要参数特定复制对策:

const fs = require('fs');
const fsPromises = fs.promises;
const { COPYFILE_EXCL, COPYFILE_FICLONE, COPYFILE_FICLONE_FORCE} = fs.constants;

(async function() {
  try {
    await fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_FICLONE);
  } catch(e) {
    console.log(e.message);
  }
})();

鼓励的 flag 有 3 个:

  • COPYFILE_EXCL: 假如目标文件已存有,会出错(默认设置是遮盖)
  • COPYFILE_FICLONE: 以 copy-on-write 方式拷贝,假如电脑操作系统不兼容就变为真正意义上的拷贝(默认设置是可以直接拷贝)
  • COPYFILE_FICLONE_FORCE:以 copy-on-write 方式拷贝,假如电脑操作系统不兼容就出错

这3个变量定义各是 1,2,4,能通过按位或将它们合拼以后传到:

const flags = COPYFILE_FICLONE | COPYFILE_EXCL;
fsPromises.copyFile('source.txt', 'destination.txt', flags);

Node.js 适用操作系统的 copy-on-write 技术性,在一些场景中能够提高性能,最好使用 COPYFILE_FICLONE 的形式,要比默认方法好一些。

进程创建

fork 是最常见的创建进程的形式,而其完成就是一种 copy-on-write 技术性。

我们都知道,过程在内存中分成字符串常量、数据段、局部变量段这 3 一部分:

  • 字符串常量:储放要实行的代码
  • 数据段:储放一些全局性数据信息
  • 局部变量段:储放实施的情况

假如根据该进程创建一个新的过程,那么就要拷贝这 3 一部分运行内存。而那这三部分运行内存是一样的具体内容,那么就白白浪费存储空间。

因此 fork 并不能真正意义上的拷贝运行内存,反而是建立一个新的过程,引入父进程的运行内存,作为数据库的改动时,才能真正的拷贝这部分的运行内存。

COW技术性 Node

这也就是为什么把进程创建称为 fork,其实就是分岔,因为没完全就是单独的,仅仅某一部分进行了分岔,变成二份,但是大多数还是一样的。

那如果要实行的代码不一样该怎么办呢,这个时候就要用 exec 了,他会建立一个新的字符串常量、数据段、局部变量段、实行一个新的编码。

Node.js 里边同样也可以用 fork 和 exec 的 api:

fork:

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`I am worker #${cluster.worker.id}`);
}

exec:

const { exec } = require('child_process');
exec('my.bat', (err, stdout, stderr) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(stdout);
});

fork 是 linux 进程创建的前提,不难看出 copy-on-write 技术性多重要了。

汇总

拷贝相同的具体内容好几份毫无疑问较为浪费空间,因此电脑操作系统正在做文件复制、进程创建时的运行内存拷贝的时候都会使用了 Copy-On-Write 技术性,只有先改动的时候才能去干拷贝。

Node.js 推动了 fs.copyFile 的 flags 设置,能够特定 COPYFILE_FICLONE 来用 Copy-On-Write 的形式做文件复制,也还是建议大家使用这个方法来节约磁盘空间,提升文件复制性能。

进度的 fork 都是 Copy-On-Write 的实现,并不能立即拷贝进度的字符串常量、数据段、局部变量段到新的内容,反而是引入以前的,只会在改动的时候才能做真正意义上的运行内存拷贝。

除此之外,Copy-On-Write 在 Immutable 的实现,在分布式的读写分离等行业都有许多运用。

COW 让 Node.js 变“懒”了,但特性却越来越高了。

全文详细地址:https://juejin.cn/post/6999497362255118366

创作者:zxg_神说要有光

大量程序编写基本知识,请访问:编程学习!!

以上就是关于探讨Node.js COW技术实现进程创建和文件复制的具体内容,大量欢迎关注AdminJS其他类似文章!