您现在的位置是:亿华云 > 域名
让 Node.js 变“懒”的 COW 技术
亿华云2025-10-04 03:56:58【域名】1人已围观
简介COW 不是奶牛,是 Copy-On-Write 的缩写,这是一种是复制但也不完全是复制的技术。一般来说复制就是创建出完全相同的两份,两份是独立的:但是,有的时候复制这件事没多大必要,完全可以复用之前
COW 不是懒奶牛,是技术 Copy-On-Write 的缩写,这是懒一种是复制但也不完全是复制的技术。
一般来说复制就是技术创建出完全相同的两份,两份是懒独立的:
但是,有的技术时候复制这件事没多大必要,完全可以复用之前的懒,这时候可以只是技术引用之前的那份,在写内容的懒时候才去复制对应的一部分内容。这样如果内容用于读的技术话,就免去了复制,懒而如果需要写,技术才会真正复制部分内容来做修改。懒
这就叫做“写时复制”,技术也就是源码下载懒 Copy-On-Write。
原理很简单,但是在操作系统的内存管理和文件系统中却很常见,Node.js 里面也因为这种技术变“懒”了。
本文我们来探究下 Copy-On-Write 在 Node.js 的进程创建和文件复制的应用:
文件复制
文件复制这件事最常见的思路就是完全写一份相同的文件内容到另一个位置,但是这样有两个问题:
完全写一份相同的内容,如果同样的文件复制了几百次,那么也创建相同的内容几百次么?太浪费硬盘空间了 如果写到一半断电了怎么办?覆盖的内容如何恢复?怎么办呢?这时候操作系统设计者就想到了 COW 技术。
用 COW 技术实现文件复制以后完美解决了上面两个问题:
复制只是添加一个引用到之前的内容,如果不修改并不会真正复制,只有到第一次修改内容的时候才去真正复制对应的数据块,这样就避免了大量硬盘空间的浪费。 写文件时会先在另一个空闲磁盘块做修改,等修改完之后才会复制到目标位置,这样就不会有断电无法回滚的问题在 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 并不会真正的复制内存,而是创建一个新的进程,引用父进程的内存,当做数据的修改的时候,才会真正复制该部分的内存。
这也是为什么把进程创建叫做 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 变“懒”了,但性能却更高了。
很赞哦!(127)
相关文章
- 以上的就是为大家介绍的关于域名的详解
- 5. 四种状态过后,域名管理机构释放域名给公众注册。
- 便宜域名使用如何?小白可以买到便宜域名吗?
- Status、Creation Date、Expiration Date
- 4、选择一个安全的域名注册商进行域名注册
- 注册域名要了解几大点?新手有什么方式注册域名?
- 打开https://www.aizhan.com/输入自己想要查询的域名然后按回车键,如果做过网站都会有数据显示出来
- 个人域名转为公司需要什么条件?个人域名转为公司该怎么做?
- 用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。
热门文章
站长推荐
以上的就是为大家介绍的关于域名的详解域名注册:域名注册0
4、企业无形资产:通用网站已成为企业网络知识产权的重要组成部分,属于企业的无形资产,也有助于提升企业的品牌形象和技术领先形象。它是企业品牌资产不可或缺的一部分。
为什么喜欢国外注册域名?国外注册域名注意什么?
为什么起域名意义非凡?起域名有什么名堂?
4.域名的整体品牌营销力
付款完成后,您只需耐心等待,如果您注册成功,系统会提示您。这里需要注意的是,域名是一个即时产品,只有在最终付款成功时才能预订,注册成功后不能更改。
付款完成后,您只需耐心等待,如果您注册成功,系统会提示您。这里需要注意的是,域名是一个即时产品,只有在最终付款成功时才能预订,注册成功后不能更改。
.com域名是国际最广泛流行的通用域名,目前全球注册量第一的域名,公司企业注册域名的首选。国际化公司通常会注册该类域名。