0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

1.2MB數(shù)據(jù)如何吃掉10GB內(nèi)存

OSC開(kāi)源社區(qū) ? 來(lái)源:阿里云開(kāi)發(fā)者 ? 2024-11-04 15:53 ? 次閱讀

以下文章來(lái)源于阿里云開(kāi)發(fā)者,作者竹一

導(dǎo)讀

一個(gè)特殊請(qǐng)求引發(fā)服務(wù)器內(nèi)存用量暴漲進(jìn)而導(dǎo)致進(jìn)程 OOM 的慘案。

問(wèn)題背景

埋點(diǎn)網(wǎng)關(guān)是螞蟻基于 nginx 開(kāi)發(fā)的接入網(wǎng)關(guān)應(yīng)用,作為應(yīng)用接入層網(wǎng)關(guān)負(fù)責(zé)移動(dòng)端埋點(diǎn)數(shù)據(jù)采集,從去年年底開(kāi)始有偶現(xiàn)的進(jìn)程 crash 問(wèn)題。

好在 nginx 設(shè)計(jì)中 worker 進(jìn)程閃退后 master 進(jìn)程會(huì)重新拉起新的進(jìn)程處理請(qǐng)求,埋點(diǎn)客戶(hù)端也有重試機(jī)制,偶現(xiàn)閃退沒(méi)有造成大的影響。

初步分析

說(shuō)實(shí)話(huà)作為 C 語(yǔ)言應(yīng)用,crash 也沒(méi)什么好奇怪的 :),第一反應(yīng)當(dāng)然是業(yè)務(wù)代碼有問(wèn)題,查看機(jī)器內(nèi)存的占用也沒(méi)有大的起伏。

893795f2-9a62-11ef-a511-92fbcf53809c.png

所以先排除了內(nèi)存泄漏最終 OOM 導(dǎo)致進(jìn)程閃退。大概率是內(nèi)存沒(méi)用好,內(nèi)存越界訪(fǎng)問(wèn)導(dǎo)致的。這種問(wèn)題排查起來(lái)也挺簡(jiǎn)單,找部分機(jī)器開(kāi)啟 core-dump,拿到 core 文件一看就知道是哪里跪了。說(shuō)干就干,線(xiàn)上找了部分機(jī)器開(kāi)啟開(kāi)關(guān),等問(wèn)題復(fù)現(xiàn)后登錄,就遇到了第一個(gè)難題:沒(méi)有生成核心轉(zhuǎn)儲(chǔ)文件。

反復(fù)檢查 core-dump 開(kāi)關(guān)確認(rèn)已經(jīng)正確打開(kāi),再回頭檢查了一遍最近的代碼變更,也沒(méi)看出什么疑點(diǎn),這時(shí)候就有點(diǎn)一籌莫展了。

如果不是

在走迷宮時(shí),如果發(fā)現(xiàn)前面無(wú)路可走,就得回頭思考前面哪一步是不是走錯(cuò)了。

一開(kāi)始排除了內(nèi)存泄漏導(dǎo)致的 OOM 問(wèn)題,是因?yàn)閺谋O(jiān)控上看內(nèi)存占用水位只有 40% 不到,并沒(méi)有上漲到內(nèi)存用完。然而這里的監(jiān)控是分鐘級(jí)的,如果內(nèi)存在短時(shí)間內(nèi)暴漲,秒級(jí)尖刺體現(xiàn)到分鐘級(jí)監(jiān)控上很可能被平均值抹平。

再結(jié)合沒(méi)有產(chǎn)生 core-dump 文件的現(xiàn)象,如果是內(nèi)存耗盡導(dǎo)致進(jìn)程被 oom-killer 進(jìn)程殺死是說(shuō)得通的。因?yàn)閛om-killer 進(jìn)程使用SIGKILL信號(hào)強(qiáng)制殺死進(jìn)程,查看 Linux 信號(hào)手冊(cè),根據(jù) POSIX.1-1990 標(biāo)準(zhǔn),SIGKILL信號(hào)意味著進(jìn)程被強(qiáng)制結(jié)束并且不進(jìn)行核心轉(zhuǎn)儲(chǔ)。


Signal   Standard  Action  Comment
 ────────────────────────────────────────────────────────────────────────
 ...
 SIGIOT     -    Core  IOT trap. A synonym for SIGABRT
 SIGKILL   P1990   Term  Kill signal
 SIGLOST    -    Term  File lock lost (unused)
 ...
瞌睡遇上枕頭,剛好發(fā)現(xiàn)監(jiān)控平臺(tái)上線(xiàn)了單機(jī)秒級(jí)監(jiān)控(感謝平臺(tái)工具給力),再找到發(fā)生 crash 的機(jī)器和時(shí)間點(diǎn),發(fā)現(xiàn)推測(cè)是對(duì)的,在幾秒內(nèi)其中一個(gè) worker 進(jìn)程內(nèi)存占用飆升,從幾百 MB 一路暴漲到十幾 GB,在 8C16G 規(guī)格的機(jī)器上很快就因?yàn)閮?nèi)存耗盡被內(nèi)核殺掉。

89533b7c-9a62-11ef-a511-92fbcf53809c.jpg

問(wèn)題查到這里,好消息是排查方向總算對(duì)了,壞消息是 OOM 進(jìn)程閃退只是問(wèn)題的表現(xiàn),而導(dǎo)致內(nèi)存飆升的根本原因還是沒(méi)什么頭緒。

懷疑有異常的攻擊流量,然而查看閃退前后該機(jī)器的網(wǎng)絡(luò)流量,inbytes 和 outbytes 并沒(méi)有波動(dòng),所以也基本排除了被突發(fā)流量攻擊;懷疑是網(wǎng)關(guān)上 ip geo 信息查詢(xún)的二分查找邏輯有死循環(huán),經(jīng)過(guò)代碼檢查和測(cè)試也沒(méi)發(fā)現(xiàn)這里有問(wèn)題;甚至懷疑系統(tǒng)跑久了有內(nèi)存碎片,但經(jīng)過(guò)排查也排除了這種可能,今年之前也沒(méi)出現(xiàn)這種問(wèn)題。

所以目前的情況就是在沒(méi)有任何外部攻擊的情況下,系統(tǒng)內(nèi)存突然就爆了。這還真是見(jiàn)了鬼,排查了這么多問(wèn)題,如此詭異的情況也是少見(jiàn)。

core-dump!

core-dump 文件是進(jìn)程閃退前最后的“遺照”,類(lèi)似尸檢之于法醫(yī),對(duì)于查問(wèn)題能提供非常多線(xiàn)索。拿不到轉(zhuǎn)儲(chǔ)文件真是兩眼一抹黑 —— 全靠猜。所以痛定思痛,決定想辦法把 core-dump 文件拿到。

既然閃退是因?yàn)閮?nèi)存占用過(guò)高,而被 oom-killer 殺死又不會(huì)進(jìn)行核心轉(zhuǎn)儲(chǔ),總不能到 Linux 內(nèi)核里修改 oom-killer 發(fā)送的信號(hào)。在跟師兄討論時(shí),師兄提出一個(gè)思路:在用戶(hù)態(tài)實(shí)現(xiàn)一個(gè) oom-killer(青春版),當(dāng)然沒(méi)有復(fù)雜的打分邏輯,只需要檢測(cè)目標(biāo)進(jìn)程的內(nèi)存用量,到閾值之后發(fā)送一個(gè)可以產(chǎn)生內(nèi)核轉(zhuǎn)儲(chǔ)行為的信號(hào)來(lái)殺死進(jìn)程,通過(guò)主動(dòng)殺死進(jìn)程的方式產(chǎn)生 core-dump 文件。

后面師兄抽空幫忙寫(xiě)了一個(gè) nginx 輔助進(jìn)程,邏輯是每秒檢測(cè)一次所有 worker 進(jìn)程的內(nèi)存用量,如果超過(guò)一定閾值就發(fā)送SIGABORT信號(hào)主動(dòng)殺死對(duì)應(yīng)進(jìn)程。當(dāng)然為了防止工具誤殺導(dǎo)致更嚴(yán)重的問(wèn)題,限制在應(yīng)用重啟后的生命周期內(nèi)最多只會(huì)觸發(fā)一次。

找了部分機(jī)器部署之后,還真給拿到了 core-dump 文件,不過(guò)還有個(gè)小插曲,第一次拿到的文件過(guò)大發(fā)生了截?cái)?,后續(xù)又將單進(jìn)程的內(nèi)存閾值從 8GB 調(diào)整為 4GB,終于拿到了完整可用的 core-dump!

895a01a0-9a62-11ef-a511-92fbcf53809c.jpg

如上圖可以看到程序的堆棧,這種通過(guò)自殺產(chǎn)生的內(nèi)核堆棧不像內(nèi)存越界的堆棧直接指向了程序崩潰點(diǎn),當(dāng)前的堆棧只能反應(yīng)程序在異常時(shí)執(zhí)行的代碼,不一定是準(zhǔn)確的問(wèn)題點(diǎn),但也能提供非常多的線(xiàn)索。從堆棧結(jié)合代碼可以看出程序正在進(jìn)行數(shù)據(jù)攢批寫(xiě)出, 再往前是 schema 埋點(diǎn)數(shù)據(jù)的拆分,攢批寫(xiě)出時(shí)恰好在調(diào)用 ngx_pcalloc 函數(shù)從內(nèi)存池中申請(qǐng)內(nèi)存,所以很可能是在 schema 埋點(diǎn)數(shù)據(jù)拆分之后的攢批發(fā)送時(shí)內(nèi)存分配出了問(wèn)題。

合理猜測(cè)

在繼續(xù)分析之前插入一個(gè)我們的業(yè)務(wù)流程,大致可以分為請(qǐng)求接收、數(shù)據(jù)處理、數(shù)據(jù)攢批、數(shù)據(jù)發(fā)送幾個(gè)階段,為了保護(hù)埋點(diǎn)網(wǎng)關(guān),在這些階段分別設(shè)置了數(shù)據(jù)大小限制:

數(shù)據(jù)解壓前的 body 大小限制 4MB 以?xún)?nèi);

解壓后的數(shù)據(jù)限制 32MB 以?xún)?nèi);

而拆分后單條埋點(diǎn)大小限制根據(jù)業(yè)務(wù)類(lèi)型動(dòng)態(tài)調(diào)整,最大支持 2MB;

89609b50-9a62-11ef-a511-92fbcf53809c.png

既然程序申請(qǐng)了這么多內(nèi)存,也拿到了 core-dump,直接將內(nèi)存 dump 出來(lái)看看里面都裝了些什么數(shù)據(jù),根據(jù)數(shù)據(jù)的內(nèi)容可以大概推測(cè)是哪個(gè)節(jié)點(diǎn)申請(qǐng)的內(nèi)存。再將之前的 core-dump 文件翻出來(lái)尋找蛛絲馬跡,從內(nèi)存中看到大量攢批完成準(zhǔn)備發(fā)送的日志內(nèi)容,說(shuō)明很可能是數(shù)據(jù)攢批發(fā)送階段占用了大量?jī)?nèi)存。

數(shù)據(jù)從攢批到發(fā)送階段的內(nèi)存管理使用了內(nèi)存池,開(kāi)始攢批時(shí)創(chuàng)建內(nèi)存池,在攢批完成后會(huì)將數(shù)據(jù)打包為 HTTP 協(xié)議發(fā)送出去,期間會(huì)經(jīng)過(guò) ProtoBuf 序列化、壓縮、生成簽名等流程,最后數(shù)據(jù)寫(xiě)出成功后將內(nèi)存池整體釋放。

897b45c2-9a62-11ef-a511-92fbcf53809c.png

仔細(xì)分析這里內(nèi)存相關(guān)的動(dòng)作,有一個(gè)問(wèn)題是內(nèi)存的分配比較粗曠,因?yàn)橛胁糠謹(jǐn)?shù)據(jù)有單條超大埋點(diǎn)的需求,比如客戶(hù)端閃退堆棧數(shù)據(jù),在數(shù)據(jù)攢批階段為了保證每次攢批至少能存放一條以上的數(shù)據(jù),所以?xún)?nèi)存池創(chuàng)建時(shí)的最低大小設(shè)置為攢批閾值 + 單條埋點(diǎn)最大限制 + 部分協(xié)議元數(shù)據(jù)大小,最終這個(gè)值大約是 3MB,意味著創(chuàng)建一個(gè)寫(xiě)出請(qǐng)求至少會(huì)申請(qǐng) 3MB 內(nèi)存。但正常情況下數(shù)據(jù)發(fā)送相對(duì)數(shù)據(jù)流入的數(shù)量級(jí)會(huì)少很多,寫(xiě)出請(qǐng)求的創(chuàng)建也會(huì)隨著請(qǐng)求流入和數(shù)據(jù)攢批打散,內(nèi)存池在數(shù)據(jù)寫(xiě)出完成后就會(huì)釋放,內(nèi)存的輪轉(zhuǎn)速度非???,所以網(wǎng)關(guān)的內(nèi)存占用并不高,僅有 30% 左右。

將目光轉(zhuǎn)向內(nèi)存池的釋放階段,該階段是在 HTTP 數(shù)據(jù)發(fā)送完成并收到響應(yīng)后做的,沒(méi)有提前釋放是因?yàn)槿魯?shù)據(jù)寫(xiě)出失敗,網(wǎng)關(guān)需要將數(shù)據(jù)暫存到內(nèi)存或磁盤(pán)中,在后續(xù)進(jìn)行重試,看起來(lái)好像也沒(méi)有什么地方會(huì)有發(fā)生急性?xún)?nèi)存泄漏。

但考慮極端情況,如果前面的數(shù)據(jù)攢批速度遠(yuǎn)超數(shù)據(jù)寫(xiě)出呢?會(huì)一瞬間創(chuàng)建大量寫(xiě)出請(qǐng)求,而數(shù)據(jù)發(fā)送到下游,同機(jī)房的一個(gè) rt 大約 20ms,如果從上??鐧C(jī)房調(diào)用到河源,一個(gè) rt 就需要 40ms 了,若數(shù)據(jù)還沒(méi)來(lái)得及寫(xiě)出完成并釋放內(nèi)存池,理論上有可能導(dǎo)致內(nèi)存占用飆升。但從之前的分析看,問(wèn)題機(jī)器上并沒(méi)有大量數(shù)據(jù)涌入,若是單個(gè)請(qǐng)求過(guò)大,對(duì)于單個(gè)請(qǐng)求還有 4MB 的數(shù)據(jù)大小限制,怎么才能一瞬間將整個(gè)內(nèi)存超過(guò) 10GB 的空間打滿(mǎn)?

四兩撥千斤

以上都是猜測(cè),既然懷疑是這里,干脆就加監(jiān)控指標(biāo)發(fā)上去看看內(nèi)存究竟申請(qǐng)了多少。上線(xiàn)后發(fā)現(xiàn)在問(wèn)題機(jī)器閃退的時(shí)間點(diǎn),創(chuàng)建寫(xiě)出請(qǐng)求的數(shù)量確實(shí)出現(xiàn)了一個(gè)明顯尖刺,由于之前增加了進(jìn)程內(nèi)存限制,這里還沒(méi)有漲更高就因?yàn)橛|發(fā)閾值被殺死。到這里問(wèn)題的直接原因算是定位到了:短時(shí)間內(nèi)創(chuàng)建了大量數(shù)據(jù)寫(xiě)出請(qǐng)求,內(nèi)存池來(lái)不及釋放,導(dǎo)致內(nèi)存瞬間被打爆。

899c3f8e-9a62-11ef-a511-92fbcf53809c.png

打破砂鍋問(wèn)到底,又是什么場(chǎng)景下會(huì)集中創(chuàng)建寫(xiě)出請(qǐng)求呢??jī)煞N可能:

有大量上報(bào)請(qǐng)求流入。之前也提到過(guò),從單機(jī)的網(wǎng)絡(luò)流量監(jiān)控來(lái)看,問(wèn)題時(shí)間點(diǎn)并沒(méi)有波動(dòng),并且這臺(tái)機(jī)器上的其他 worker 進(jìn)程也沒(méi)有問(wèn)題,所以基本可以排除第一種場(chǎng)景。

單次上報(bào)請(qǐng)求中攜帶了非常多數(shù)據(jù)。而對(duì)于單次請(qǐng)求,網(wǎng)關(guān)有設(shè)置 4MB 的原始數(shù)據(jù)限制,攜帶超過(guò) 4MB 的數(shù)據(jù)上報(bào)會(huì)被直接拒絕服務(wù)。難道這不到 4MB 的數(shù)據(jù)經(jīng)過(guò)一系列處理和攢批,真就撬動(dòng)了超 10GB 的內(nèi)存消耗?

從之前的內(nèi)存 dump 中又發(fā)現(xiàn)了可疑的地方,一個(gè)用戶(hù)的 uid 在內(nèi)存里重復(fù)了 6 萬(wàn)次!再細(xì)看重復(fù)的數(shù)據(jù),大部分字段都是相同的,僅有 timestamp、startTime、endTime 等時(shí)間戳字段不同。到這里第一時(shí)間想到的是一種攻擊方式——壓縮炸彈。大量重復(fù)字符,意味著更高的數(shù)據(jù)壓縮率,因?yàn)椴徽撌?LZ77 算法、哈夫曼編碼還是字典編碼,壓縮算法的核心都是利用各種手段減少重復(fù)數(shù)據(jù)占用的存儲(chǔ)空間。

89abd5a2-9a62-11ef-a511-92fbcf53809c.jpg

正常線(xiàn)上的請(qǐng)求壓縮率根據(jù)業(yè)務(wù)上報(bào)策略的差異平均會(huì)在 30% 左右,而如果數(shù)據(jù)大量重復(fù),這個(gè)壓縮率則會(huì)非常高。根據(jù) dump 出來(lái)的數(shù)據(jù),簡(jiǎn)單擼了個(gè)腳本手動(dòng)構(gòu)造出類(lèi)似的測(cè)試數(shù)據(jù),時(shí)間戳隨機(jī)遞增,其他耗時(shí)相關(guān)的字段取隨機(jī)數(shù),剩余字段用固定 mock 值。

執(zhí)行結(jié)果如下,單條埋點(diǎn)經(jīng)過(guò) ProtoBuf 序列化后為 3.47KB,一萬(wàn)條埋點(diǎn)打包后原始數(shù)據(jù)有 34.7MB,壓縮后只剩 1.2MB,壓縮率達(dá)到恐怖的 3.5%,這就能解釋為何前面有 4MB 的 body 大小限制但沒(méi)能防住超大數(shù)據(jù)上報(bào)。


origin data bytes: 34697723
compressed data bytes: 1214252

真相大白

將 mock 出的原始數(shù)據(jù)裁剪到 32MB 以?xún)?nèi)再發(fā)送到埋點(diǎn)網(wǎng)關(guān),果然復(fù)現(xiàn)了內(nèi)存暴漲并閃退的問(wèn)題。埋點(diǎn)網(wǎng)關(guān)對(duì)于文本類(lèi)埋點(diǎn)有單次請(qǐng)求最多攜帶的埋點(diǎn)條數(shù)限制,而對(duì)于 ProtoBuf 類(lèi)型的 schema 埋點(diǎn)還沒(méi)有做限制。于是在生產(chǎn)環(huán)境先增加了對(duì)超量 schema 埋點(diǎn)上報(bào)的告警,發(fā)現(xiàn)確實(shí)存在零星攜帶超量埋點(diǎn)的請(qǐng)求,接著再對(duì) schema 類(lèi)型的埋點(diǎn)增加了條數(shù)限制后果然再?zèng)]有閃退,可以確認(rèn)根本原因是這里了。

但話(huà)說(shuō)回來(lái),這次上報(bào)雖然日志條數(shù)非常多,就算有重復(fù)數(shù)據(jù)的壓縮率高問(wèn)題,解壓后最多也就 32MB 的原始數(shù)據(jù),又是如何放大到超過(guò) 10GB 呢?

答案也在 dump 出的數(shù)據(jù)內(nèi)容中,可以看到大量重復(fù)數(shù)據(jù)的埋點(diǎn)業(yè)務(wù)碼,對(duì)應(yīng)業(yè)務(wù)對(duì)數(shù)據(jù)的時(shí)效性要求非常高,所以數(shù)據(jù)攢批閾值設(shè)置得很小,每攢夠 25.6KB 即會(huì)觸發(fā)一次日志寫(xiě)出。意味著一個(gè) 32MB 原始數(shù)據(jù)的請(qǐng)求上來(lái),在數(shù)據(jù)攢批發(fā)送時(shí)會(huì)瞬間創(chuàng)建出大約 1250 個(gè)寫(xiě)出請(qǐng)求,每個(gè)寫(xiě)出請(qǐng)求的內(nèi)存池至少 3MB,就會(huì)申請(qǐng)出總計(jì) 3.75GB 的內(nèi)存。

話(huà)又說(shuō)回來(lái),3.75GB 離 10GB 還是差很遠(yuǎn),因?yàn)檫€沒(méi)完,端特征埋點(diǎn)因?yàn)橛袑?shí)時(shí)消費(fèi)需求,所以網(wǎng)關(guān)會(huì)同時(shí)寫(xiě)出三份數(shù)據(jù),一份寫(xiě)出到 SLS,還有兩份分別發(fā)送到不同的應(yīng)用系統(tǒng),每個(gè)寫(xiě)出通道都有獨(dú)立的數(shù)據(jù)攢批發(fā)送流程,最終申請(qǐng)的內(nèi)存大小就是 3.75GB * 3 = 11.25GB。

排查到這里,問(wèn)題的原因鏈條就比較完整了:

單次請(qǐng)求攜帶大量埋點(diǎn)數(shù)據(jù),因?yàn)橹貜?fù)字段多壓縮率足夠高,所以繞過(guò)了前面對(duì)請(qǐng)求 body 的尺寸限制;

埋點(diǎn)網(wǎng)關(guān)在數(shù)據(jù)攢批發(fā)送階段的內(nèi)存池分配粗曠,默認(rèn)按鏈路的最大閾值來(lái)分配內(nèi)存,并且內(nèi)存池釋放依賴(lài)請(qǐng)求寫(xiě)出完成,內(nèi)存釋放速度遠(yuǎn)小于數(shù)據(jù)流入速度;

高時(shí)效、多份寫(xiě)出的業(yè)務(wù)特性,更是讓原本粗曠的內(nèi)存管理雪上加霜,這些因素疊加在一起,最終撬動(dòng)了超過(guò) 10GB 的內(nèi)存消耗;

話(huà)又又又說(shuō)回來(lái),以前為什么沒(méi)有出現(xiàn)這個(gè)情況?

因?yàn)槁顸c(diǎn)網(wǎng)關(guān)的數(shù)據(jù)大小限制經(jīng)歷了幾次調(diào)整,為了支持客戶(hù)端閃退這類(lèi)超大埋點(diǎn)的上報(bào),網(wǎng)關(guān)分別將數(shù)據(jù)大小限制從壓縮后 2MB、解壓后 16MB、單條埋點(diǎn) 256KB 調(diào)整到了當(dāng)前的壓縮后 4MB、解壓后 32MB、單條埋點(diǎn)限制支持根據(jù)業(yè)務(wù)動(dòng)態(tài)調(diào)整,也就間接達(dá)成了原因鏈條里的第二個(gè)因素。

解決方案

之前為 schema 埋點(diǎn)增加了單次請(qǐng)求最多攜帶的埋點(diǎn)條數(shù)限制,閃退問(wèn)題雖然已經(jīng)解決,但排查下來(lái)可以發(fā)現(xiàn)閃退是各種因素疊加在一起導(dǎo)致的結(jié)果,這些地方都還有優(yōu)化空間,對(duì)于埋點(diǎn)網(wǎng)關(guān)這種百萬(wàn) QPS 的在線(xiàn)服務(wù),性能和穩(wěn)定性的優(yōu)化非常有必要。

對(duì)于數(shù)據(jù)攢批發(fā)送,內(nèi)存池很大一部分空間被原始數(shù)據(jù)占用,其實(shí)原始數(shù)據(jù)在經(jīng)過(guò) Protobuf 序列化及壓縮后就不再需要了,因?yàn)?HTTP 請(qǐng)求發(fā)送和后續(xù)的失敗緩存使用的都是壓縮后數(shù)據(jù)。原始數(shù)據(jù)使用的這塊內(nèi)存可以提前到請(qǐng)求發(fā)送之前就釋放,不用等待請(qǐng)求結(jié)束才能釋放內(nèi)存。而壓縮之后的數(shù)據(jù)量大約只有原始數(shù)據(jù)的十分之一,大幅提升內(nèi)存的輪轉(zhuǎn)效率。

89b28316-9a62-11ef-a511-92fbcf53809c.png

內(nèi)存的分配其實(shí)也可以更精細(xì),之前為每個(gè)寫(xiě)出請(qǐng)求分配了 3MB 內(nèi)存,是為了支持單條超大埋點(diǎn),例如客戶(hù)端閃退埋點(diǎn)一條最大可能達(dá)到 2MB,為了保證攢批時(shí)至少能存一條埋點(diǎn),并且網(wǎng)關(guān)的內(nèi)存資源比較寬裕,這塊內(nèi)存池創(chuàng)建得很大,實(shí)際使用中大部分業(yè)務(wù)攢批都用不到這么大的內(nèi)存,可以改為根據(jù)攢批數(shù)據(jù)量動(dòng)態(tài)擴(kuò)容。

除了這些縫縫補(bǔ)補(bǔ),我們也在探索使用內(nèi)存安全的語(yǔ)言比如 Rust 來(lái)實(shí)現(xiàn)更多能力,這里不過(guò)多展開(kāi)。

小結(jié)

歷時(shí)半年之久,經(jīng)過(guò)反復(fù)猜測(cè)、修改、驗(yàn)證,終于將網(wǎng)關(guān)上這個(gè)“定時(shí)炸彈”成功拆除,在成功復(fù)現(xiàn)并定位到根因后真是長(zhǎng)舒一口氣,總結(jié)下來(lái)一點(diǎn)小小的心得(主要還是心理層面的,技術(shù)方面還需要一題一議,不具有普適參考價(jià)值):

堅(jiān)信任何現(xiàn)象都有其背后的原因,在排查時(shí)苦于找不到方向,屢次道心破碎想過(guò)放棄,但線(xiàn)上的閃退告警時(shí)刻提醒著“革命尚未成功,同志仍需努力”。

沒(méi)有思路時(shí)可以拿出來(lái)和別人討論案情,思維碰撞中往往會(huì)有靈光乍現(xiàn)。

大膽假設(shè),小心求證。通過(guò)現(xiàn)象推測(cè)可能的原因并一一驗(yàn)證,同時(shí)要有將之前的假設(shè)都推翻重來(lái)的勇氣。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 網(wǎng)關(guān)
    +關(guān)注

    關(guān)注

    9

    文章

    4506

    瀏覽量

    51171
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    9204

    瀏覽量

    85547
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3029

    瀏覽量

    74103
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7605

    瀏覽量

    137000

原文標(biāo)題:“四兩撥千斤”——1.2MB數(shù)據(jù)如何吃掉10GB內(nèi)存

文章出處:【微信號(hào):OSC開(kāi)源社區(qū),微信公眾號(hào):OSC開(kāi)源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    做TYPE-C轉(zhuǎn)接需要達(dá)到傳輸數(shù)據(jù)10GB/s,該用什么設(shè)備儀器檢測(cè)?

    做TYPE-C轉(zhuǎn)接 需要達(dá)到傳輸數(shù)據(jù)10GB/s該用什么設(shè)備儀器檢測(cè)?深圳有沒(méi)有這樣的測(cè)試廠(chǎng)商可以提供完成數(shù)據(jù)的測(cè)試檢測(cè)分析。
    發(fā)表于 01-22 10:27

    10Gb以太網(wǎng)物理層接口的發(fā)展趨勢(shì)

    隨著多家供應(yīng)商可以提供具有卸載(offload)能力和高密度、低延遲交換能力的網(wǎng)絡(luò)接口適配器,10Gb以太網(wǎng)產(chǎn)業(yè)鏈正在迅速成熟。對(duì)于許多要求高速數(shù)據(jù)傳輸?shù)膽?yīng)用領(lǐng)域,10Gb以太網(wǎng)正在逐漸引入許多
    發(fā)表于 04-24 07:00

    10Gb子系統(tǒng)示例如何設(shè)計(jì)

    我已經(jīng)開(kāi)始使用10Gb以太網(wǎng)子系統(tǒng)核心(v3.1)進(jìn)行設(shè)計(jì)。首先,在硬件測(cè)試之前,您通常會(huì)做多少仿真?在我了解了我需要初始化的寄存器后,我很想進(jìn)入實(shí)驗(yàn)室。我的主要問(wèn)題涉及10Gb子系統(tǒng)示例
    發(fā)表于 05-20 16:04

    10Gb/s時(shí)鐘數(shù)據(jù)恢復(fù)電路行為級(jí)模型研究

    10Gb/s時(shí)鐘數(shù)據(jù)恢復(fù)電路行為級(jí)模型研究:研究了超高速(10Gb/s) NRZ 碼時(shí)鐘數(shù)據(jù)恢復(fù)電路的行為級(jí)建模,并采用TSMC 0.18μm CMOS 工藝進(jìn)行了電路級(jí)仿真。關(guān)鍵詞:
    發(fā)表于 12-14 09:25 ?18次下載

    BLADE和Voltaire推出高密度10Gb以太網(wǎng)網(wǎng)絡(luò)方案

    高密度10Gb以太網(wǎng)網(wǎng)絡(luò)方案(BLADE和Voltaire) BLADE和Voltaire攜手推出了行業(yè)最高密度的10Gb 以太網(wǎng)數(shù)據(jù)中心交換網(wǎng)絡(luò)。 基于Voltaire的Vant
    發(fā)表于 04-23 09:54 ?1371次閱讀

    OPPO Find X,是世界上第一款擁有10GB運(yùn)存的手機(jī)

    果不其然,今天小編就在工信部網(wǎng)站上發(fā)現(xiàn)了一款擁有10GB逆天運(yùn)存的手機(jī)正式入網(wǎng)了,它就是OPPO Find X。我們可以看到,工信部網(wǎng)站上標(biāo)明,這是一個(gè)型號(hào)為PAFM00的新版本,內(nèi)存增加到了10GB+256GB存儲(chǔ),可以說(shuō)是如
    發(fā)表于 09-27 16:18 ?1927次閱讀

    OPPO Find X成為了世界上第一款用上了10GB內(nèi)存的手機(jī)

    9月26日也就是昨天,OPPO旗下的Find X它的工信部官網(wǎng)信息得到了更新,此次的更新信息很是嚇人,OPPO Find X新增了10GB內(nèi)存的版本,也就意味著OPPO打磨了四年的Find X將帶領(lǐng)手機(jī)界內(nèi)存邁入到兩位數(shù)的時(shí)代,
    的頭像 發(fā)表于 09-29 17:28 ?4237次閱讀

    一加6T邁凱倫定制版搭載10GB運(yùn)行內(nèi)存支持全新Warp閃充30

    一加最新的旗艦手機(jī)一加6T邁凱倫定制版近日剛剛推出,它在硬件配置上和一加6T標(biāo)準(zhǔn)版并沒(méi)有太大不同,均搭載了驍龍845頂級(jí)處理器,不同的是它的運(yùn)行內(nèi)存高達(dá)10GB,是一加首款10GB運(yùn)存手機(jī),并且支持全新Warp閃充30,帶來(lái)酣暢
    發(fā)表于 12-25 15:56 ?1220次閱讀

    10GB的vivoNEX雙屏版玩游戲怎么樣

    雙屏版于2018年12月11日正式發(fā)布,該旗艦機(jī)全系類(lèi)均為10GB運(yùn)行內(nèi)存,這也意味著智能手機(jī)的“10GB”時(shí)代已經(jīng)悄然來(lái)臨。
    的頭像 發(fā)表于 01-07 11:27 ?3828次閱讀

    2019年旗艦手機(jī)配備10GB內(nèi)存將成為主流

    1月22日消息,據(jù)Digitimes報(bào)道,2019年旗艦手機(jī)配備10GB內(nèi)存將成為主流。
    的頭像 發(fā)表于 01-22 09:10 ?3863次閱讀

    Linux吃掉我的內(nèi)存

    ,Linux系統(tǒng)吃掉我們的內(nèi)存(Linux ate my ram),但其實(shí)這也正是其內(nèi)存管理的特點(diǎn)。free命令介紹 下面為使用free命令查看我們實(shí)驗(yàn)室文件服務(wù)器內(nèi)存得到的結(jié)果,-m
    發(fā)表于 04-02 14:32 ?181次閱讀

    華為 Mate 40/Pro系列搭載全新內(nèi)存擴(kuò)展技術(shù):8GB等效10GB ,12GB等效14GB

    IT之家 10 月 30 日消息 今天下午,華為 Mate40 系列國(guó)行發(fā)布會(huì)舉行,余承東表示,華為Mate40系列搭載了全新內(nèi)存擴(kuò)展技術(shù),實(shí)體內(nèi)存8GB等于擴(kuò)展后等效
    的頭像 發(fā)表于 10-30 15:43 ?7079次閱讀

    10GB顯存容易在4K等游戲中爆顯存,是真的嗎

    NVIDIA的RTX 30系列顯卡中,RTX 3080顯卡無(wú)疑是最受歡迎的之一,就是10GB顯存有點(diǎn)遺憾,大家覺(jué)得NV摳門(mén),10GB顯存容易在4K等游戲中爆顯存,事實(shí)真的如此嗎? YT上有網(wǎng)友對(duì)比
    的頭像 發(fā)表于 11-23 16:06 ?6050次閱讀

    ADN2815:連續(xù)速率10 Mb/s至1.25 Gb/s時(shí)鐘和數(shù)據(jù)恢復(fù)IC數(shù)據(jù)

    ADN2815:連續(xù)速率10 Mb/s至1.25 Gb/s時(shí)鐘和數(shù)據(jù)恢復(fù)IC數(shù)據(jù)
    發(fā)表于 05-09 14:39 ?6次下載
    ADN2815:連續(xù)速率<b class='flag-5'>10</b> <b class='flag-5'>Mb</b>/s至1.25 <b class='flag-5'>Gb</b>/s時(shí)鐘和<b class='flag-5'>數(shù)據(jù)</b>恢復(fù)IC<b class='flag-5'>數(shù)據(jù)</b>表

    Brocade 10Gb/s SR SFP+產(chǎn)品簡(jiǎn)介

    電子發(fā)燒友網(wǎng)站提供《Brocade 10Gb/s SR SFP+產(chǎn)品簡(jiǎn)介.pdf》資料免費(fèi)下載
    發(fā)表于 09-01 15:48 ?0次下載
    Brocade <b class='flag-5'>10Gb</b>/s SR SFP+產(chǎn)品簡(jiǎn)介