成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

讓 Node.js 變“懶”的 COW 技術(shù)

開發(fā) 前端
COW 不是奶牛,是 Copy-On-Write 的縮寫,這是一種是復制但也不完全是復制的技術(shù)。本文我們來探究下 Copy-On-Write 在 Node.js 的進程創(chuàng)建和文件復制的應(yīng)用。

[[419135]]

COW 不是奶牛,是 Copy-On-Write 的縮寫,這是一種是復制但也不完全是復制的技術(shù)。

一般來說復制就是創(chuàng)建出完全相同的兩份,兩份是獨立的:

但是,有的時候復制這件事沒多大必要,完全可以復用之前的,這時候可以只是引用之前的那份,在寫內(nèi)容的時候才去復制對應(yīng)的一部分內(nèi)容。這樣如果內(nèi)容用于讀的話,就免去了復制,而如果需要寫,才會真正復制部分內(nèi)容來做修改。

這就叫做“寫時復制”,也就是 Copy-On-Write。

原理很簡單,但是在操作系統(tǒng)的內(nèi)存管理和文件系統(tǒng)中卻很常見,Node.js 里面也因為這種技術(shù)變“懶”了。

本文我們來探究下 Copy-On-Write 在 Node.js 的進程創(chuàng)建和文件復制的應(yīng)用:

文件復制

文件復制這件事最常見的思路就是完全寫一份相同的文件內(nèi)容到另一個位置,但是這樣有兩個問題:

  • 完全寫一份相同的內(nèi)容,如果同樣的文件復制了幾百次,那么也創(chuàng)建相同的內(nèi)容幾百次么?太浪費硬盤空間了
  • 如果寫到一半斷電了怎么辦?覆蓋的內(nèi)容如何恢復?

怎么辦呢?這時候操作系統(tǒng)設(shè)計者就想到了 COW 技術(shù)。

用 COW 技術(shù)實現(xiàn)文件復制以后完美解決了上面兩個問題:

  • 復制只是添加一個引用到之前的內(nèi)容,如果不修改并不會真正復制,只有到第一次修改內(nèi)容的時候才去真正復制對應(yīng)的數(shù)據(jù)塊,這樣就避免了大量硬盤空間的浪費。
  • 寫文件時會先在另一個空閑磁盤塊做修改,等修改完之后才會復制到目標位置,這樣就不會有斷電無法回滾的問題

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

默認情況下,copyFile 會寫入目標文件,覆蓋原內(nèi)容

  1. const fsPromises = require('fs').promises; 
  2.  
  3. (async function() { 
  4.   try { 
  5.     await fsPromises.copyFile('source.txt''destination.txt'); 
  6.   } catch(e) { 
  7.     console.log(e.message); 
  8.   } 
  9. })(); 

但是可以通過第三個參數(shù)指定復制的策略:

  1. const fs = require('fs'); 
  2. const fsPromises = fs.promises; 
  3. const { COPYFILE_EXCL, COPYFILE_FICLONE, COPYFILE_FICLONE_FORCE} = fs.constants; 
  4.  
  5. (async function() { 
  6.   try { 
  7.     await fsPromises.copyFile('source.txt''destination.txt', COPYFILE_FICLONE); 
  8.   } catch(e) { 
  9.     console.log(e.message); 
  10.   } 
  11. })(); 

支持的 flag 有 3 個:

  • COPYFILE_EXCL: 如果目標文件已存在,會報錯(默認是覆蓋)
  • COPYFILE_FICLONE: 以 copy-on-write 模式復制,如果操作系統(tǒng)不支持就轉(zhuǎn)為真正的復制(默認是直接復制)
  • COPYFILE_FICLONE_FORCE:以 copy-on-write 模式復制,如果操作系統(tǒng)不支持就報錯

這3個常量分別是 1,2,4,可以通過按位或把它們合并之后傳入:

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

Node.js 支持操作系統(tǒng)的 copy-on-write 技術(shù),在一些場景下可以提升性能,建議使用 COPYFILE_FICLONE 的方式,會比默認的方式好一些。

進程創(chuàng)建

fork 是常見的創(chuàng)建進程的方式,而它的實現(xiàn)就是一種 copy-on-write 技術(shù)。

我們知道,進程在內(nèi)存中分為代碼段、數(shù)據(jù)段、堆棧段這 3 部分:

  • 代碼段:存放要執(zhí)行的代碼
  • 數(shù)據(jù)段:存放一些全局數(shù)據(jù)
  • 堆棧段:存放執(zhí)行的狀態(tài)

如果基于該進程創(chuàng)建一個新的進程,那么要復制這 3 部分內(nèi)存。而如果這三部分內(nèi)存是一樣的內(nèi)容,那就浪費了內(nèi)存空間。

所以 fork 并不會真正的復制內(nèi)存,而是創(chuàng)建一個新的進程,引用父進程的內(nèi)存,當做數(shù)據(jù)的修改的時候,才會真正復制該部分的內(nèi)存。

這也是為什么把進程創(chuàng)建叫做 fork,也就是分叉,因為不完全是獨立的,只是某部分做了分叉,成了兩份,但是大部分還是一樣的。

但如果要執(zhí)行的代碼不一樣怎么辦呢,這時候就要用 exec 了,它會創(chuàng)建新的代碼段、數(shù)據(jù)段、堆棧段、執(zhí)行新的代碼。

Node.js 里面同樣可以用 fork 和 exec 的 api:

fork:

  1. const cluster = require('cluster'); 
  2.  
  3. if (cluster.isMaster) { 
  4.   console.log('I am master'); 
  5.   cluster.fork(); 
  6.   cluster.fork(); 
  7. else if (cluster.isWorker) { 
  8.   console.log(`I am worker #${cluster.worker.id}`); 

exec:

  1. const { exec } = require('child_process'); 
  2. exec('my.bat', (err, stdout, stderr) => { 
  3.   if (err) { 
  4.     console.error(err); 
  5.     return
  6.   } 
  7.   console.log(stdout); 
  8. }); 

fork 是 linux 進程創(chuàng)建的基礎(chǔ),由此可見 copy-on-write 技術(shù)多么重要了。

總結(jié)

復制同樣的內(nèi)容多份無疑比較浪費空間,所以操作系統(tǒng)在做文件復制、進程創(chuàng)建時的內(nèi)存復制的時候都采用了 Copy-On-Write 技術(shù),只有真正修改的時候才會去做復制。

Node.js 支持了 fs.copyFile 的 flags 的設(shè)置,可以指定 COPYFILE_FICLONE 來使用 Copy-On-Write 的方式做文件復制,也建議大家使用這種方式來節(jié)省硬盤空間,提高文件復制的性能。

進程的 fork 也是 Copy-On-Write 的實現(xiàn),并不會直接復制進程的代碼段、數(shù)據(jù)段、堆棧段到新的內(nèi)容,而是引用之前的,只有在修改的時候才會做真正的內(nèi)存復制。

除此以外,Copy-On-Write 在 Immutable 的實現(xiàn),在分布式的讀寫分離等領(lǐng)域都有很多應(yīng)用。

COW 讓 Node.js 變“懶”了,但性能卻更高了。

 

責任編輯:姜華 來源: 神光的編程秘籍
相關(guān)推薦

2019-07-09 14:50:15

Node.js前端工具

2013-11-01 09:34:56

Node.js技術(shù)

2015-03-10 10:59:18

Node.js開發(fā)指南基礎(chǔ)介紹

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2011-09-08 13:46:14

node.js

2011-11-01 10:30:36

Node.js

2011-09-02 14:47:48

Node

2011-09-09 14:23:13

Node.js

2011-11-10 08:55:00

Node.js

2012-10-24 14:56:30

IBMdw

2023-12-07 08:07:47

Node流程代碼

2014-08-28 09:35:32

Node.js前端開發(fā)

2021-09-26 05:06:04

Node.js模塊機制

2021-11-06 18:40:27

js底層模塊

2011-11-02 09:04:15

Node.js

2015-06-23 15:27:53

HproseNode.js

2015-04-28 10:13:36

Jenkins蒲公英

2021-02-01 15:42:45

Node.jsSQL應(yīng)用程序
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲成人一区二区三区 | 美女露尿口视频 | 伊人久久麻豆 | 麻豆av片| 91网站在线播放 | 天天狠狠| 成年男女免费视频网站 | 国内自拍第一页 | 精品一区二区三区日本 | 成人免费视频网站在线看 | 呦呦在线视频 | 日韩精品久久久久 | 亚洲a视| 日韩成人国产 | 在线看av网址| 亚洲永久入口 | 性高朝久久久久久久3小时 av一区二区三区四区 | 精精国产xxxx视频在线播放 | 91久久久久久久久久久久久 | 国产精品一区二区视频 | 欧美综合在线观看 | 亚洲区一区二 | 亚洲一区中文字幕在线观看 | av在线天堂| 在线观看中文字幕视频 | 亚洲精品一区二区三区四区高清 | 麻豆视频在线免费观看 | 国产成人免费视频 | 日韩成人在线观看 | 午夜视频一区 | 久久成人激情 | a在线免费观看视频 | 亚洲国产成人av好男人在线观看 | 一级在线观看 | 国产精品国产精品国产专区不卡 | 日韩三级免费观看 | 国产激情在线播放 | 亚洲视频中文字幕 | 国产精品亚洲精品久久 | 日本黄色一级片视频 | 青青草av网站 |