自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你知道為啥給JVM分配的內(nèi)存越大,結(jié)果性能越差嗎?

開發(fā) 架構(gòu)
本文主要討論的是Kafka和Elasticsearch兩種分布式系統(tǒng)的線上部署情況,不是普通的Java應(yīng)用系統(tǒng)。

前言

這篇文章,給大家聊一個生產(chǎn)環(huán)境的實踐經(jīng)驗:線上系統(tǒng)部署的時候,JVM堆內(nèi)存大小是越大越好嗎?

先說明白一個前提,本文主要討論的是Kafka和Elasticsearch兩種分布式系統(tǒng)的線上部署情況,不是普通的Java應(yīng)用系統(tǒng)。

1、是否依賴Java系統(tǒng)自身內(nèi)存處理數(shù)據(jù)?

先說明一點,不管是我們自己開發(fā)的Java應(yīng)用系統(tǒng),還是一些中間件系統(tǒng),在實現(xiàn)的時候都需要選擇是否基于自己Java進(jìn)程的內(nèi)存來處理數(shù)據(jù)。

大家應(yīng)該都知道,Java、Scala等編程語言底層依賴的都是JVM,那么只要是使用JVM,就可以考慮在JVM進(jìn)程的內(nèi)存中來放置大量的數(shù)據(jù)。

還是給大家舉個例子,大家應(yīng)該還記得之前聊過消息中間件系統(tǒng)。

比如說系統(tǒng)A可以給系統(tǒng)B發(fā)送一條消息,那么中間需要依賴一個消息中間件,系統(tǒng)A要先把消息發(fā)送到消息中間件,然后系統(tǒng)B從這個消息中間件消費到這條消息。

大家看下面的示意圖。

大家應(yīng)該都知道,一條消息發(fā)送到消息中間件之后,有一種處理方式,就是把這條數(shù)據(jù)先緩沖在自己的JVM內(nèi)存里。

然后過一段時間之后,再從自己的內(nèi)存刷新到磁盤上去,這樣可以持久化保存這條消息,如下圖。

2、依賴Java系統(tǒng)自身內(nèi)存有什么缺陷

如果用類似上述的方式,依賴Java系統(tǒng)自身內(nèi)存處理數(shù)據(jù),比如說設(shè)計一個內(nèi)存緩沖區(qū),來緩沖住高并發(fā)寫入的大量消息,那么是有其缺陷的。

最大的缺陷,其實就是JVM的GC問題,這個GC就是垃圾回收,這里簡單說一下他是怎么回事。

大家可以想一下,如果一個Java進(jìn)程里老是塞入很多的數(shù)據(jù),這些數(shù)據(jù)都是用來緩沖在內(nèi)存里的,但是過一會兒這些數(shù)據(jù)都會寫入磁盤。

那么寫入磁盤之后,這些數(shù)據(jù)還需要繼續(xù)放在內(nèi)存里嗎?

明顯是不需要的了,此時就會依托JVM垃圾回收機制,把內(nèi)存里那些不需要的數(shù)據(jù)給回收掉,釋放掉那些內(nèi)存空間騰出來。

但是JVM垃圾回收的時候,有一種情況叫做stop the world,就是他會停止你的工作線程,就專門讓他進(jìn)行垃圾回收。

這個時候,他在垃圾回收的時候,有可能你的這個中間件系統(tǒng)就運行不了了。

比如你發(fā)送請求給他,他可能都沒法響應(yīng)給你,因為他的接收請求的工作線程都停了,現(xiàn)在人家后臺的垃圾回收線程正在回收垃圾對象。

大家看下圖。

雖然說現(xiàn)在JVM的垃圾回收器一直在不斷的演進(jìn)和發(fā)展,從CMS到G1,盡可能的在降低垃圾回收的時候的影響,減少工作線程的停頓。

但是你要是完全依賴JVM內(nèi)存來管理大量的數(shù)據(jù),那在垃圾回收的時候,或多或少總是有影響的。

所以特別是對于一些大數(shù)據(jù)系統(tǒng),中間件系統(tǒng),這個JVM的GC(Garbage Collector,垃圾回收)問題,真是最頭疼的一個問題。

3、優(yōu)化為依賴OS Cache而不是JVM

所以類似Kafka、Elasticsearch等分布式中間件系統(tǒng),雖然也是基于JVM運行的,但是他們都選擇了依賴OS Cache來管理大量的數(shù)據(jù)。

也就是說,是操作系統(tǒng)管理的內(nèi)存緩沖,而不是依賴JVM自身內(nèi)存來管理大量的數(shù)據(jù)。

具體來說,比如說Kafka吧,如果你寫一條數(shù)據(jù)到Kafka,他實際上會直接寫入磁盤文件。

但是磁盤文件在寫入之前其實會進(jìn)入os cache,也就是操作系統(tǒng)管理的內(nèi)存空間,然后過一段時間,操作系統(tǒng)自己會選擇把他的os cache的數(shù)據(jù)刷入磁盤。

然后后續(xù)在消費數(shù)據(jù)的時候,其實也會優(yōu)先從os cache(內(nèi)存緩沖)里來讀取數(shù)據(jù)。

相當(dāng)于寫數(shù)據(jù)和讀數(shù)據(jù)都是依托于os cache來進(jìn)行的,完全依托操作系統(tǒng)級別的內(nèi)存區(qū)域來進(jìn)行,讀寫性能都很高。

此外,還有另外一個好處,就是不要依托自身JVM來緩沖大量的數(shù)據(jù),這樣可以避免復(fù)雜而且耗時的JVM垃圾回收操作。

大家看下面的圖,其實就是一個典型的Kafka的運行流程。

然后比如Elasticsearch,他作為一個現(xiàn)在最流行的分布式搜索系統(tǒng),也是采用類類似的機制。

大量的依賴os cache來緩沖大量的數(shù)據(jù),然后在進(jìn)行搜索和查詢的時候,也可以優(yōu)先從os cache(內(nèi)存區(qū)域)中讀取數(shù)據(jù),這樣就可以保證非常高的讀寫性能。

4、老司機經(jīng)驗之談

依賴os cache的系統(tǒng)JVM內(nèi)存越大越好?

所以現(xiàn)在就可以進(jìn)入我們的主題了,那么比如就以上述說的kafka、elasticsearch等系統(tǒng)而言,在線上生產(chǎn)環(huán)境部署的時候,你知道他們是大量依賴于os cache來緩沖大量數(shù)據(jù)的。

那么,給他們分配JVM堆內(nèi)存大小的時候是越大越好嗎?

明顯不是的,假如說你有一臺機器,有32GB的內(nèi)存,現(xiàn)在你如果在搞不清楚狀況的情況下,要是傻傻的認(rèn)為還是給JVM分配越大內(nèi)存越好,此時比如給了16G的堆內(nèi)存空間給JVM,那么os cache剩下的內(nèi)存,可能就不到10GB了,因為本身其他的程序還要占用幾個GB的內(nèi)存。

那如果是這樣的話,就會導(dǎo)致你在寫入磁盤的時候,os cache能容納的數(shù)據(jù)量很有限。

比如說一共有20G的數(shù)據(jù)要寫入磁盤,現(xiàn)在就只有10GB的數(shù)據(jù)可以放在os cache里,然后另外10GB的數(shù)據(jù)就只能放在磁盤上。

此時在讀取數(shù)據(jù)的時候,那么起碼有一半的讀取請求,必須從磁盤上去讀了,沒法從os cache里讀,誰讓你os cache里就只能放的下10G的一半大小的數(shù)據(jù)啊,另外一半都在磁盤里,這也是沒辦法的,如下圖。

那此時你有一半的請求都是從磁盤上在讀取數(shù)據(jù),必然會導(dǎo)致性能很差。

所以很多人在用Elasticsearch的時候就是這樣的一個問題,老是覺得ES讀取速度慢,幾個億的數(shù)據(jù)寫入ES,讀取的時候要好幾秒。

那能不花費好幾秒嗎?你要是ES集群部署的時候,給JVM內(nèi)存過大,給os cache留了幾個GB的內(nèi)存,導(dǎo)致幾億條數(shù)據(jù)大部分都在磁盤上,不在os cache里,最后讀取的時候大量讀磁盤,耗費個幾秒鐘是很正常的。

5、正確的做法

針對場景合理給os cache更大內(nèi)存。

所以說,針對類似Kafka、Elasticsearch這種生產(chǎn)系統(tǒng)部署的時候,應(yīng)該要給JVM比如6GB或者幾個GB的內(nèi)存就可以了。

因為他們可能不需要耗費過大的內(nèi)存空間,不依賴JVM內(nèi)存管理數(shù)據(jù),當(dāng)然具體是設(shè)置多少,需要你精準(zhǔn)的壓測和優(yōu)化。

但是對于這類系統(tǒng),應(yīng)該給os cache留出來足夠的內(nèi)存空間,比如32GB內(nèi)存的機器,完全可以給os cache留出來20多G的內(nèi)存空間,那么此時假設(shè)你這臺機器總共就寫入了20GB的數(shù)據(jù),就可以全部駐留在os cache里了。

然后后續(xù)在查詢數(shù)據(jù)的時候,不就可以全部從os cache里讀取數(shù)據(jù)了,完全依托內(nèi)存來走,那你的性能必然是毫秒級的,不可能出現(xiàn)幾秒鐘才完成一個查詢的情況。

整個過程,如下圖所示:

所以說,建議大家在線上生產(chǎn)系統(tǒng)引入任何技術(shù)的時候,都應(yīng)該先對這個技術(shù)的原理,甚至源碼進(jìn)行深入的理解,知道他具體的工作流程是什么,然后針對性的合理設(shè)計生產(chǎn)環(huán)境的部署方案,保證最佳的生產(chǎn)性能。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2017-12-11 15:04:58

404錯誤HTTP代碼

2025-04-02 08:47:23

DOM文檔結(jié)構(gòu)API

2012-09-29 09:22:24

.NETGC內(nèi)存分配

2012-09-29 10:29:56

.Net內(nèi)存分配繼承

2024-04-03 09:23:31

ES索引分析器

2021-04-23 07:27:31

內(nèi)存分配CPU

2023-06-26 08:20:02

openapi格式注解

2023-03-09 08:23:07

序列化?接口方法

2023-09-08 08:35:42

層疊樣式表CSS

2010-09-25 15:40:52

配置JVM內(nèi)存

2015-11-11 10:41:49

1600億AWS云計算

2018-10-28 15:40:23

Python編程語言

2012-01-11 10:45:57

JavaJVM

2018-04-08 08:45:53

對象內(nèi)存策略

2022-03-07 10:54:34

內(nèi)存Linux

2014-07-15 11:05:30

黑莓

2020-11-23 08:43:32

機器學(xué)習(xí)技術(shù)人工智能

2009-07-09 10:01:26

設(shè)置JVM內(nèi)存分配

2021-08-10 13:50:32

內(nèi)存電腦軟件

2022-02-15 20:08:41

JDKJavaWindows
點贊
收藏

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