influxdb內(nèi)存占用大的原因分析(源碼篇)

背景

influxdb是一款開源的高性能時序數(shù)據(jù)庫。在我們SEE監(jiān)控模塊是必備組件,主要用于幫助我們快速地存儲莲蜘、查詢和分析這些數(shù)據(jù)熟呛。雖然我們享受到influxdb帶來的諸多益處,但是很多客戶會反饋相較于其他應用influxdb的內(nèi)存占用實在是太大了炭懊,今天我們進來系統(tǒng)的分析一下。

分析過程

通過TOP命令,分析內(nèi)存占用的總體情況


我們可以看到influxdb這個進程中目前VIRT是15G便贵,RES是6.2G九府,SHR是6.1G。那么我們需要弄清楚這三個指標分別代表了什么

VIRT:一個進程地址空間的總大小父阻,包括代碼段愈涩、數(shù)據(jù)段(包括堆和棧)、共享庫加矛、映射文件等履婉。它反映了進程可尋址的虛擬內(nèi)存空間大小。也就是是程序向操作系統(tǒng)申請的空間大小斟览,但是不一定會完全被占用毁腿,只是一個理論值。

RES: ?指的是進程當前在RAM中使用的內(nèi)存大小,也就是常駐內(nèi)存的大小已烤。RES包括了所有的程序指令鸠窗、數(shù)據(jù)以及共享庫等在內(nèi),但不包括被交換出去的內(nèi)存胯究。

SHR: 表示共享內(nèi)存或共享庫的大小稍计。在 Linux 系統(tǒng)中,共享內(nèi)存是多個進程可以同時訪問的一段內(nèi)存區(qū)域唐片,多個進程可以通過映射同一個共享內(nèi)存區(qū)域來實現(xiàn)進程間通信丙猬。而共享庫則是多個進程可以共享的動態(tài)鏈接庫,在內(nèi)存中只需要加載一份共享庫费韭,就可以在多個進程中重復使用茧球,從而減少了內(nèi)存的占用。

RES=SHR+程序自身內(nèi)存占用(堆棧相關內(nèi)存占用)星持,通過上圖的TOP來看抢埋,常駐內(nèi)存中大部分都是共享內(nèi)存,那么到底共享了什么督暂?

通過smaps揪垄,確定共享內(nèi)存中的內(nèi)容

通過查看/proc/pid/smaps來確定具體的內(nèi)存占用


我們主要關注里面的Size、Rss字段逻翁,分別代表了申請的內(nèi)存空間的大小以及真實占用內(nèi)存的大小饥努,發(fā)現(xiàn)那些占用大的內(nèi)存快,基本上來自xxx.tsm文件八回,可能通過下面的方式看起來更直觀一點:

cat /proc/228347/smaps | sed -n '/see/,+2p' | grep -v 'Size:' | sed 's/\ kB//' | awk '{print $NF}' | awk 'BEGIN{i=-1}{i++;a[i]=$0}END{for(k=0;k<length(a);k=k+2) {if(a[k+1]/1000>10){m+=a[k+1]/1000;print a[k],a[k+1]/1000,m}}}'


因為這些tsm文件導致的常駐內(nèi)存的大小就有6.1G酷愧,這還只是篩選出大于10M的那些數(shù)據(jù)文件,總的應該會更多缠诅。那么問題來了溶浴,influxdb為什么會將這些文件引入內(nèi)存?

高性能利器-mmap

mmap(memory mapped file)是一種內(nèi)存映射文件的機制,它可以將文件映射到進程的地址空間中管引,使得文件的內(nèi)容在內(nèi)存中像數(shù)組一樣被訪問士败。在Linux和UNIX系統(tǒng)中,mmap函數(shù)允許進程把一個文件或者其他對象映射到它的進程空間褥伴,從而實現(xiàn)文件內(nèi)容與虛擬內(nèi)存之間的映射谅将。使用mmap函數(shù)映射文件可以提高文件讀取速度,減少IO開銷噩翠,特別是對于大文件的讀取操作戏自。當文件被映射到進程的虛擬地址空間中時,進程可以像訪問內(nèi)存一樣訪問文件中的內(nèi)容伤锚,而不需要進行系統(tǒng)調(diào)用讀取磁盤上的數(shù)據(jù)擅笔。

我們都知道influxdb為了保證數(shù)據(jù)可靠性會將數(shù)據(jù)落盤志衣,為了保證查詢的效率足夠高,他也利用了mmap技術將數(shù)據(jù)文件tsm進行了內(nèi)存映射猛们,使得influxdb可以像操作內(nèi)存一樣操作數(shù)據(jù)文件念脯,避免了傳統(tǒng)模式那種多次上下文切換帶來的功能損耗,從而讓influxdb性能更優(yōu)弯淘。本文結合influxdb 1.8.4的源碼進行此過程的梳理

a. influxdb啟動時會調(diào)用文件存儲層打開對于文件等的引用



b.創(chuàng)建文件的閱讀器



c.閱讀器的初始化



d.文件的mmap操作進行內(nèi)存映射



mmap函數(shù)會將指定的文件區(qū)域映射到進程的地址空間中绿店,它會在虛擬地址空間中分配一段連續(xù)的地址,并將這段地址映射到指定的文件區(qū)域中庐橙。這個操作是真正占用進程的虛擬內(nèi)存的假勿,但是在內(nèi)存實際分配之前,這部分虛擬內(nèi)存是不會被物理內(nèi)存占用的态鳖,只有在程序訪問這部分虛擬內(nèi)存時转培,操作系統(tǒng)才會將其對應的物理內(nèi)存分配出來,從而使得虛擬內(nèi)存真正占用物理內(nèi)存浆竭。因此浸须,mmap 操作并不是直接占用內(nèi)存,而是分配好虛擬內(nèi)存地址邦泄。所以mmap()調(diào)用會增加進程的虛擬內(nèi)存空間删窒,因此VIRT會增大,但是并不會直接占用物理內(nèi)存顺囊,因此RES不會變肌索。實際的物理內(nèi)存映射會在訪問映射區(qū)域時發(fā)生,此時才會將數(shù)據(jù)載入物理內(nèi)存并增加進程的實際內(nèi)存使用量特碳。那么哪些操作會將數(shù)據(jù)加入到物理內(nèi)存呢驶社?

查詢數(shù)據(jù)階段:當用戶執(zhí)行查詢操作時,InfluxDB需要讀取磁盤上的數(shù)據(jù)文件测萎,并將其映射到虛擬地址空間中以進行數(shù)據(jù)的查詢和處理。這時操作系統(tǒng)會將相關的內(nèi)存頁加載到內(nèi)存中届巩,然后將其映射到進程的虛擬地址空間中硅瞧,供應用程序訪問。

寫入數(shù)據(jù)階段:當用戶寫入數(shù)據(jù)時恕汇,InfluxDB需要將數(shù)據(jù)寫入到磁盤上的數(shù)據(jù)文件中腕唧。如果數(shù)據(jù)文件已經(jīng)被映射到虛擬地址空間中,那么寫入數(shù)據(jù)的過程也會訪問被映射的虛擬地址瘾英。寫入數(shù)據(jù)時枣接,操作系統(tǒng)會將修改后的內(nèi)存頁標記為已修改,然后在適當?shù)臅r候將其寫回到磁盤上的數(shù)據(jù)文件中缺谴。

壓縮&合并數(shù)據(jù)階段:當 InfluxDB 執(zhí)行數(shù)據(jù)壓縮操作時但惶,它需要讀取磁盤上的數(shù)據(jù)文件,并將壓縮合并后的數(shù)據(jù)寫入到新的數(shù)據(jù)文件中。這個過程也會訪問被映射的虛擬地址膀曾,類似于查詢數(shù)據(jù)階段县爬。壓縮數(shù)據(jù)時,InfluxDB 會根據(jù)配置的策略來判斷哪些數(shù)據(jù)需要被壓縮添谊,壓縮后的數(shù)據(jù)會被寫入新的數(shù)據(jù)文件中财喳,并替換舊的數(shù)據(jù)文件。

回溯TOP中內(nèi)存指標

基于上面的分析斩狱,我們可以對TOP中的VIRT耳高、RES、SHR 這三個的值進行分析驗證:

VIRT:虛擬內(nèi)存大小所踊,在TOP中顯示的值是15G泌枪。我們通過上面的mmap分析,在influxdb啟動時會進行內(nèi)存映射污筷,將數(shù)據(jù)文件映射進內(nèi)存工闺,雖然不會增加常駐內(nèi)存的大小,但是會直接影響虛擬內(nèi)存瓣蛀,而我們磁盤文件的大小是14G



這個值再加上influxdb自身的堆棧以及其他的共享庫文件的占用陆蟆,基本上為15G。

SHR:共享內(nèi)存大小惋增,在TOP中顯示的值是6.1 G叠殷。上文我們就通過smaps拿到了映射進入內(nèi)存的文件的大小是6.1G,基本上是一致的诈皿。

RES:常駐內(nèi)存大小林束,在TOP中顯示的值是6.2G。自身堆棧的占用可以通過influx工具進入查詢稽亏。


自身堆棧占用大小計算:HeapInUse + (HeapIdle - HeapReleased) = 146890752+(175284224-164610048)=146890752+10674176=157564928=0.15G

RES=SHR+自身堆棧占用=6.1G+0.15G=6.15G壶冒,這個值四舍五入和6.2G是持平的。

結論

influxdb內(nèi)存占用大截歉,主要是因為利用了mmap對數(shù)據(jù)文件進行內(nèi)存映射胖腾。另外為了提升查詢性能,在內(nèi)存中構建了大量的索引幫助快速定位數(shù)據(jù)等瘪松。

參考文檔

influxdb內(nèi)存消耗分析及性能優(yōu)化【追蹤篇】

influxdb內(nèi)存消耗分析及性能優(yōu)化【探索篇】

influxdb官方文檔

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咸作,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宵睦,更是在濱河造成了極大的恐慌记罚,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件壳嚎,死亡現(xiàn)場離奇詭異桐智,居然都是意外死亡末早,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門酵使,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荐吉,“玉大人,你說我怎么就攤上這事口渔⊙溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵缺脉,是天一觀的道長痪欲。 經(jīng)常有香客問我,道長攻礼,這世上最難降的妖魔是什么业踢? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮礁扮,結果婚禮上知举,老公的妹妹穿的比我還像新娘。我一直安慰自己太伊,他們只是感情好雇锡,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著僚焦,像睡著了一般锰提。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芳悲,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天立肘,我揣著相機與錄音,去河邊找鬼名扛。 笑死谅年,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的肮韧。 我是一名探鬼主播踢故,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼惹苗!你這毒婦竟也來了?” 一聲冷哼從身側響起耸峭,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桩蓉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后劳闹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體院究,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡洽瞬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了业汰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伙窃。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖样漆,靈堂內(nèi)的尸體忽然破棺而出为障,到底是詐尸還是另有隱情,我是刑警寧澤放祟,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布鳍怨,位于F島的核電站,受9級特大地震影響跪妥,放射性物質發(fā)生泄漏鞋喇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一眉撵、第九天 我趴在偏房一處隱蔽的房頂上張望侦香。 院中可真熱鬧,春花似錦纽疟、人聲如沸罐韩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伴逸。三九已至,卻和暖如春膘壶,著一層夾襖步出監(jiān)牢的瞬間错蝴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工颓芭, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顷锰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓亡问,卻偏偏與公主長得像官紫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子州藕,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容