av一区二区在线观看_亚洲男人的天堂网站_日韩亚洲视频_在线成人免费_欧美日韩精品免费观看视频_久草视

您的位置:首頁技術(shù)文章
文章詳情頁

NodeJs超長字符串問題處理的詳細(xì)分析

瀏覽:140日期:2022-06-01 11:40:24
目錄
  • 問題背景
  • 代碼細(xì)節(jié)
  • 更進(jìn)一步
  • 總結(jié)

問題:對于超大的 string V8不能支持

問題背景

在 Nodejs 計(jì)算服務(wù)中,對端上上報(bào)的內(nèi)存信息二進(jìn)制數(shù)據(jù)進(jìn)行預(yù)處理+緩存時(shí),遇到了一個(gè)奇怪的報(bào)錯(cuò):RangeError: Invalid string length 。根據(jù)該報(bào)錯(cuò)信息,查找得知是字符串長度超過了 node.js 的限制,即 2^29-1 (約 5 億+)個(gè)字符。整體流程如圖所示。

關(guān)于 node.js string 的長度上限,主要和 V8 引擎「壓縮指針」技術(shù)有關(guān)。按個(gè)人理解,其通過壓縮指向變量的地址(64 位)中固定的 32 位的方式,從而減少引擎的內(nèi)存占用。

代碼細(xì)節(jié)

由于需要快速訪問某地址,因此緩存的數(shù)據(jù)結(jié)構(gòu)必須是個(gè)對象,即 INodeGraph。具體結(jié)構(gòu)如下:

  type IAddr = string;// 內(nèi)存圖譜  declare interface INodeGraph {    [addr: IAddr]: IParsedNode;  }// 內(nèi)存節(jié)點(diǎn)信息  declare interface IParsedNode {    addr: IAddr;    // size, nodeType 等輔助信息    parentNodeAddr: IAddr[]; // addr    childNodeAddr: string[]; // addr    edgeMap: {      [addr: IAddr]: {// 當(dāng)前節(jié)點(diǎn)與父子節(jié)點(diǎn)之間的邊(關(guān)系)的信息      };    };  }

我們目的很明確,就是實(shí)現(xiàn)這樣一個(gè) js 大對象的持久化存儲,并且能夠方便快速的轉(zhuǎn)回 js object。為解決此問題,首先想到的能否利用 protobuf 替代 JSON 實(shí)現(xiàn)持久化。可惜的是 protobuf 并不適用于動態(tài) key 的場景,它適用于處理數(shù)組中存儲多個(gè)相似結(jié)構(gòu)對象的數(shù)據(jù)結(jié)構(gòu)。

隨后嘗試了減少對象中不必要的信息,即縮短對象的固定 key,例如用「pNode」取代冗長的「parentNodeAddr」。對于一個(gè)百萬個(gè)鍵值對的 object 而言,雖然犧牲了代碼的可讀性,但在實(shí)際的 case 中,能承載的鍵值對數(shù)量大約多了 20%。
事實(shí)上回過頭來看,更好的處理方式或許是用另外的 Map 存儲對象的 key。例如 : 將nodeGraph.parentNodeAddr這個(gè) key 最大程度縮短為nodeGraph.p

聲明 const GraphKey = { parentNodeAddr: 'p' } 保存一個(gè) key 的映射,需要訪問某屬性時(shí),使用nodeGraph[GraphKey.parentNodeAddr]

更進(jìn)一步

上述手段只是治標(biāo)不治本,對于 key 更多的大對象并不能徹底解決問題。因此在不改變項(xiàng)目整體架構(gòu)的前提下(如使用圖數(shù)據(jù)庫/改用 go 開發(fā)等),提出以下兩個(gè)最終方案:

方案 1:借助 Node.js C++ Addons 的能力,繞開 js string 的限制,將相關(guān)序列化邏輯交給 C++ 處理,并直接將處理好的引用樹 js object 進(jìn)行后續(xù)處理。

  • 優(yōu)勢:如果能實(shí)現(xiàn),性能會獲得優(yōu)先提升;擴(kuò)展了 Node.js 的能力
  • 劣勢:實(shí)現(xiàn)難度大;維護(hù)可能是個(gè)問題

方案 2:生成引用樹緩存時(shí),拆分為多個(gè)較小的對象,分別進(jìn)行序列化和存儲,使用時(shí)再合并為一個(gè)大對象。

  • 優(yōu)勢:無需 C++ 側(cè)開發(fā),難度更小;維護(hù)方便
  • 劣勢:合并對象需要額外的時(shí)間,這一步驟可能會讓未命中緩存時(shí)的首次請求更慢

總結(jié)

到此這篇關(guān)于NodeJs超長字符串問題處理的文章就介紹到這了,更多相關(guān)NodeJs字符串問題處理內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標(biāo)簽: JavaScript
主站蜘蛛池模板: 国产a久久麻豆入口 | 国产精品一二三四 | 在线一区 | 极品尤物一区二区三区 | 午夜激情网站 | 毛片毛片毛片毛片毛片 | 成人精品国产 | 偷拍一区二区三区 | 黑人黄色一级片 | 夜夜欢天天干 | 亚洲成人av一区二区 | 肉丝美脚视频一区二区 | www.欧美精品 | 国产日韩一区二区三区 | 开心激情婷婷 | 在线观看中文字幕 | 不卡的av在线 | a在线免费观看 | 午夜国产视频 | 日韩在线视频观看 | 日韩中文字幕在线播放 | 欧美精品99 | 成人国产在线观看 | 欧美日韩免费看 | 亚洲第十页 | 国产亚洲精品成人av久久ww | 久久国产亚洲 | 夜间福利视频 | 国产h在线| 成人免费精品 | 一区二区美女 | 激情小说亚洲 | 中文字幕av一区二区三区谷原希美 | 伊人9999 | 免费a在线| 欧美一区二区在线观看 | 国产中文字幕在线 | 久久精品1| 成人午夜av| 国产精品成人免费视频 | 国产成人免费 |