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

分布式系統(tǒng)Kafka和ES中,JVM內(nèi)存越大越好嗎?

云計(jì)算 虛擬化 分布式 Kafka
這篇文章,給大家聊一個(gè)生產(chǎn)環(huán)境的實(shí)踐經(jīng)驗(yàn):線上系統(tǒng)部署的時(shí)候,JVM 堆內(nèi)存大小是越大越好嗎?

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

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

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

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

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

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

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

大家看下面的示意圖:

 

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

然后過一段時(shí)間之后,再?gòu)淖约旱膬?nèi)存刷新到磁盤上去,這樣可以持久化保存這條消息,如下圖:

 

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

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

***的缺陷,其實(shí)就是 JVM 的 GC 問題,這個(gè) GC 就是垃圾回收,這里簡(jiǎn)單說一下它是怎么回事。

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

那么寫入磁盤之后,這些數(shù)據(jù)還需要繼續(xù)放在內(nèi)存里嗎?明顯是不需要的了,此時(shí)就會(huì)依托 JVM 垃圾回收機(jī)制,把內(nèi)存里那些不需要的數(shù)據(jù)給回收掉,釋放掉那些內(nèi)存空間騰出來(lái)。

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

這個(gè)時(shí)候,它在垃圾回收的時(shí)候,有可能你的這個(gè)中間件系統(tǒng)就運(yùn)行不了了。

比如你發(fā)送請(qǐng)求給它,它可能都沒法響應(yīng)給你,因?yàn)樗慕邮照?qǐng)求的工作線程都停了,現(xiàn)在人家后臺(tái)的垃圾回收線程正在回收垃圾對(duì)象。

大家看下圖:

 

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

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

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

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

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

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

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

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

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

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

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

大家看下面的圖,其實(shí)就是一個(gè)典型的 Kafka 的運(yùn)行流程:

 

然后比如 Elasticsearch,它作為一個(gè)現(xiàn)在***的分布式搜索系統(tǒng),也是采用類似的機(jī)制。

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

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

現(xiàn)在就可以進(jìn)入我們的主題了,那么比如就以上述說的 Kafka、Elasticsearch 等系統(tǒng)而言,在線上生產(chǎn)環(huán)境部署的時(shí)候,你知道它們是大量依賴于 OS Cache 來(lái)緩沖大量數(shù)據(jù)的。那么,給它們分配 JVM 堆內(nèi)存大小的時(shí)候是越大越好嗎?

明顯不是的,假如說你有一臺(tái)機(jī)器,有 32GB 的內(nèi)存,現(xiàn)在你如果在搞不清楚狀況的情況下,要是傻傻的認(rèn)為還是給 JVM 分配越大內(nèi)存越好,此時(shí)比如給了 16G 的堆內(nèi)存空間給 JVM,那么 OS Cache 剩下的內(nèi)存,可能就不到 10GB 了,因?yàn)楸旧砥渌某绦蜻€要占用幾個(gè) GB 的內(nèi)存。

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

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

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

 

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

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

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

正確的做法:針對(duì)場(chǎng)景合理給 OS Cache 更大內(nèi)存

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

因?yàn)樗鼈兛赡懿恍枰馁M(fèi)過大的內(nèi)存空間,不依賴 JVM 內(nèi)存管理數(shù)據(jù),當(dāng)然具體是設(shè)置多少,需要你精準(zhǔn)的壓測(cè)和優(yōu)化。

但是對(duì)于這類系統(tǒng),應(yīng)該給 OS Cache 留出來(lái)足夠的內(nèi)存空間,比如 32GB 內(nèi)存的機(jī)器,完全可以給 OS Cache 留出來(lái) 20 多 G 的內(nèi)存空間。

那么此時(shí)假設(shè)你這臺(tái)機(jī)器總共就寫入了 20GB 的數(shù)據(jù),就可以全部駐留在 OS Cache 里了。

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

整個(gè)過程,如下圖所示:

 

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

中華石杉:十余年 BAT 架構(gòu)經(jīng)驗(yàn),一線互聯(lián)網(wǎng)公司技術(shù)總監(jiān)。帶領(lǐng)上百人團(tuán)隊(duì)開發(fā)過多個(gè)億級(jí)流量高并發(fā)系統(tǒng)?,F(xiàn)將多年工作中積累下的研究手稿、經(jīng)驗(yàn)總結(jié)整理成文,傾囊相授。微信公眾號(hào):石杉的架構(gòu)筆記(ID:shishan100)。

 

責(zé)任編輯:武曉燕 來(lái)源: 石杉的架構(gòu)筆記
相關(guān)推薦

2023-03-11 13:15:01

AI模型系統(tǒng)

2017-08-30 16:47:49

Kafka設(shè)計(jì)原理

2023-05-29 14:07:00

Zuul網(wǎng)關(guān)系統(tǒng)

2017-07-27 14:32:05

大數(shù)據(jù)分布式消息Kafka

2023-05-12 08:23:03

分布式系統(tǒng)網(wǎng)絡(luò)

2017-10-27 08:40:44

分布式存儲(chǔ)剪枝系統(tǒng)

2018-12-14 10:06:22

緩存分布式系統(tǒng)

2023-10-26 18:10:43

分布式并行技術(shù)系統(tǒng)

2023-02-11 00:04:17

分布式系統(tǒng)安全

2024-10-18 08:00:00

分布式系統(tǒng)背壓數(shù)據(jù)庫(kù)

2021-07-06 10:35:46

分布式KafkaLinux

2023-07-19 08:22:01

分布式系統(tǒng)數(shù)據(jù)

2023-10-24 17:14:52

Kafka分布式系統(tǒng)

2017-10-17 08:33:31

存儲(chǔ)系統(tǒng)分布式

2020-10-30 07:47:42

分布式

2016-08-12 15:17:40

分布式

2024-07-05 08:26:54

2022-07-18 10:29:33

數(shù)據(jù)分布式系統(tǒng)

2015-12-14 17:35:21

GemFire12306分布式

2011-04-18 14:43:23

分布式測(cè)試分布式測(cè)試
點(diǎn)贊
收藏

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