簡書 滌生膳帕。
轉(zhuǎn)載請注明原創(chuàng)出處,謝謝薇缅!
如果讀完覺得有收獲的話危彩,歡迎點(diǎn)贊加關(guān)注。
說明
本篇原文來自 LinkedIn 的 Zhenyun Zhuang泳桦,原文:Application Pauses When Running JVM Inside Linux Control Groups[1]汤徽,在容器化的進(jìn)程中,或多或少會(huì)對現(xiàn)有應(yīng)用程序帶來一些問題灸撰,這篇文章講的是 LinkedIn 在使用 cgroups 構(gòu)建容器化產(chǎn)品過程中谒府,發(fā)現(xiàn)資源限制策略對 Java 應(yīng)用程序性能會(huì)產(chǎn)生一些影響拼坎,文章深入分析問題根本原因,并給出解決方案完疫。筆者看過后泰鸡,覺得非常贊,因此翻譯后獻(xiàn)給大家壳鹤,希望對大家有幫助盛龄。
前言
基于 Linux cgroups[2]的解決方案(例如丑念,Docker[3]窗宦,CoreOS[4])越來越多地用于在同一主機(jī)上托管多個(gè)應(yīng)用程序。我們一直在 LinkedIn 上使用 cgroups 來構(gòu)建我們自己的容器化[5]產(chǎn)品 LPS[6](LinkedIn 平臺(tái)即服務(wù))发绢,并研究資源限制策略對應(yīng)用程序性能的影響锹淌。這篇文章介紹了我們關(guān)于 CPU 調(diào)度如何影響 cgroups 中 Java 應(yīng)用程序性能的一些發(fā)現(xiàn)匿值。我們發(fā)現(xiàn),在將 CFS[7](完全公平調(diào)度程序)與 CFS 帶寬控制的配額結(jié)合使用時(shí)赂摆,Java 應(yīng)用程序可能會(huì)有越來越長的暫停千扔。在這些暫停期間,應(yīng)用程序不能響應(yīng)用戶請求库正,因此,這是我們需要分析和解決這個(gè)嚴(yán)重性能問題厘唾。
這些增多的暫停是由 JVM 的 GC(垃圾收集)機(jī)制和 CFS 調(diào)度之間的交互引起的褥符。在 CFS 中,為 cgroup 分配了一定的 CPU 配額(即 cfs_quota)抚垃,這會(huì)被 JVM GC 的多線程活動(dòng)快速耗盡喷楣,從而導(dǎo)致應(yīng)用程序受到限制。例如鹤树,可能會(huì)發(fā)生以下情況:
如果一個(gè)應(yīng)用程序在一個(gè)調(diào)度期間積極地使用其 CPU 配額铣焊,那么該應(yīng)用程序就會(huì)受到限制(不再使用 CPU),并在調(diào)度期間的剩余持續(xù)時(shí)間內(nèi)停止響應(yīng)罕伯。
多線程的 JVM GC 會(huì)使問題更加嚴(yán)重曲伊,因?yàn)閼?yīng)用程序的所有線程都計(jì)算了cfs_quota(配額)。因此追他,CPU 配額可能會(huì)更快地用完坟募。JVM GC 有許多非 STW(stop the world)的并發(fā)階段。但是邑狸,它們的運(yùn)行也會(huì)導(dǎo)致更快的使用完 CPU 配額懈糯,因此,實(shí)際上將整個(gè)應(yīng)用程序設(shè)置為 STW(stop the world)单雾。
在本文中赚哗,我們將分享我們研究這個(gè)問題之后的發(fā)現(xiàn)她紫,以及我們關(guān)于 CFS/JVM 調(diào)優(yōu)以減輕負(fù)面影響的建議。具體而言:
- 應(yīng)該將足夠的 CPU 配額分配給承載 Java 應(yīng)用程序的 CGROUP屿储;
- 應(yīng)該適當(dāng)?shù)卣{(diào)低 JVM GC 線程贿讹,以緩解暫停。
Linux cgroups 背景
Linux cgroups(控制組)用于限制應(yīng)用程序的各種類型資源的使用扩所。對于 CPU 資源围详,CPU 子系統(tǒng)調(diào)度 CPU 的 cgroup 任務(wù)訪問,CFS 是兩個(gè)受支持的調(diào)度程序之一祖屏。 CFS 是一個(gè)比例共享調(diào)度程序助赞,它根據(jù) cgroup 的權(quán)重為 cgroup 分配 CPU 訪問權(quán)限。
對于我們使用的 RHEL7[8](Red Hat Enterprise Linux)機(jī)器袁勺,有多個(gè)可調(diào)參數(shù)雹食。用于限制 CPU 執(zhí)行的有兩個(gè) CFS 參數(shù),這兩個(gè)參數(shù)可以用于限制 cgroup 使用的 CPU 資源:cpu.cfs_period_us 和 cpu.cfs_quota_us期丰,均以微秒為單位群叶。 cpu.cfs_period_us 指定應(yīng)用配額的 CFS 周期或強(qiáng)制執(zhí)行間隔,cpu.cfs_quota_us指定 cgroup 在每個(gè) CFS 周期中可以使用的配額钝荡。 cpu.cfs_quota_us 實(shí)質(zhì)上設(shè)置了 CPU 資源的硬限制(即上限)街立。 cgroup(及其進(jìn)程)僅允許在 cpu.cfs_quota_us 中指定的持續(xù)時(shí)間內(nèi)占用 CPU 核心資源。因此埠通,為了給出 cgroup N 核赎离,cpu.cfs_quota_us 設(shè)置為 cpu.cfs_period_us 的 N 倍。
工作負(fù)載和配置情況
為了進(jìn)行分析端辱,我們創(chuàng)建了一個(gè)用于測試 CFS 行為的 Java 應(yīng)用程序梁剔。這個(gè) Java 應(yīng)用程序簡單地在 Java 堆上分配對象。當(dāng)分配的對象數(shù)量達(dá)到某個(gè)閾值后舞蔽,將釋放其中的一部分荣病。有兩個(gè)應(yīng)用程序線程,每個(gè)線程獨(dú)立地執(zhí)行對象分配和對象釋放渗柿。每個(gè)對象分配所花費(fèi)的時(shí)間記錄為分配延遲个盆。這個(gè)測試 Java 應(yīng)用程序的源代碼位于 GitHub[9] 上。
我們考慮的性能指標(biāo)包括:
(1)應(yīng)用程序吞吐量(對象分配率);
(2)對象分配延遲;
(3)cgroup 的統(tǒng)計(jì)信息做祝,包括 cgroup 的 CPU 使用率砾省,nr_throttled(受限制的 CFS 周期數(shù))和 throttled_time(總限制時(shí)間)。
我們使用的機(jī)器是 RHEL7混槐,內(nèi)核為 3.10.0-327编兄,它有 24 個(gè) HT(超線程)內(nèi)核。使用 CFS 上限強(qiáng)制限制 CPU 資源狠鸳。默認(rèn)情況下,托管 Java 應(yīng)用程序的 cgroup 被分配了三個(gè) CPU 共享核心件舵,考慮到有兩個(gè)應(yīng)用程序線程和 GC 活動(dòng)。在以后的測試中铅祸,我們還改變了分配的核心數(shù)量坑质,以獲得更多的信息临梗。默認(rèn)情況下,cfs_period 為 100 毫秒盟庞。每次運(yùn)行工作需要 20 分鐘(1200 秒)吃沪。因此,當(dāng) cfs_period 為 100ms 時(shí)票彪,每次運(yùn)行中有 12,000 個(gè) CFS 周期不狮。
排查應(yīng)用長時(shí)間暫停
我們將從對特定應(yīng)用程序暫停的詳細(xì)分析開始,以便了解暫停背后的原因垮耳。
應(yīng)用暫停
在 22:57:34 時(shí)遂黍,兩個(gè)應(yīng)用程序線程都停止大約三秒鐘(即 2,917 毫秒和 2,916 毫秒)俊嗽。
// Thread id, time stamp, application freezing time (ms)
Thread 1: 2016-10-07 22:57:34.00974,2917
Thread 2: 2016-10-07 22:57:34.00975,2916
JVM GC STW
為了理解導(dǎo)致三秒鐘應(yīng)用程序凍結(jié)的原因绍豁,我們首先檢查了 JVM GC 日志。我們發(fā)現(xiàn)在 22:57:37.771 時(shí)敬飒,STW(停止世界)GC 暫停發(fā)生芬位。請注意昧碉,暫停持續(xù)約 0.12 秒揽惹。
2016-10-07T22:57:33.985+0000: 30.856: [GC concurrent-root-region-scan-start]
2016-10-07T22:57:33.991+0000: 30.863: [GC concurrent-root-region-scan-end, 0.0064502 secs]
2016-10-07T22:57:33.991+0000: 30.863: [GC concurrent-mark-start]
2016-10-07T22:57:37.771+0000: 34.642: [GC pause (G1 Evacuation Pause) (young), 0.1194989 secs]
[Parallel Time: 118.0 ms, GC Workers: 18]
[GC Worker Start (ms): Min: 34642.7, Avg: 34642.9, Max: 34643.1, Diff: 0.4]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, Sum: 1.3]
[SATB Filtering (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Update RS (ms): Min: 8.5, Avg: 10.8, Max: 13.7, Diff: 5.2, Sum: 194.8]
[Processed Buffers: Min: 3, Avg: 3.6, Max: 4, Diff: 1, Sum: 65]
[Scan RS (ms): Min: 0.0, Avg: 1.3, Max: 4.0, Diff: 4.0, Sum: 23.2]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Object Copy (ms): Min: 103.8, Avg: 105.4, Max: 105.9, Diff: 2.2, Sum: 1896.6]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.5]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.6]
[GC Worker Total (ms): Min: 117.4, Avg: 117.6, Max: 117.9, Diff: 0.4, Sum: 2117.1]
[GC Worker End (ms): Min: 34760.5, Avg: 34760.6, Max: 34760.6, Diff: 0.1]
[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.5 ms]
[Other: 1.0 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.2 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.2 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.1 ms]
[Eden: 1120.0M(1120.0M)->0.0B(1120.0M) Survivors: 160.0M->160.0M Heap: 16.6G(25.0G)->15.9G(25.0G)]
[Times: user=1.27 sys=0.09, real=0.12 secs]
2016-10-07T22:57:37.891+0000: 34.762: Total time for which application threads were stopped: 0.1197007 seconds, Stopping threads took: 0.0000314 seconds
與 3 秒鐘的應(yīng)用停止相比搪搏,0.12 秒的 GC 暫停不足以解釋 2.88 秒(即 3 - 0.12)的時(shí)間差距疯溺;因此哎垦,暫停必然有其他原因。
CFS 限制
我們懷疑應(yīng)用程序除了 GC 外的暫停是由 cgroups 的 CFS 調(diào)度程序引起的挠说。我們通過收集應(yīng)用程序運(yùn)行的每一秒的各種類型的報(bào)告 cgroups 統(tǒng)計(jì)信息來檢查 cgroups 的統(tǒng)計(jì)信息愿题。我們發(fā)現(xiàn)“throttled_time”的指標(biāo)很有意義潘酗。 “throttled_time”報(bào)告該組實(shí)體已被限制的累計(jì)總持續(xù)時(shí)間(以納秒為單位)。
我們注意到琐脏,當(dāng)應(yīng)用程序被凍結(jié)時(shí)缸兔,“throttled_time”發(fā)生在 22:57:33惰蜜。當(dāng)應(yīng)用程序處于凍結(jié)期時(shí),“throttled_time”的增加(即差異)約為 5.28 秒格侯。因此财著,我們認(rèn)為“throttled_time”導(dǎo)致應(yīng)用凍結(jié)。
// time stamp, throttled_time in ns, delta in seconds (difference from last report)
2016-10-07 22:57:32.01789 throttled_time 72284616704759 //
2016-10-07 22:57:33.02097 throttled_time 72288113805728 // delta = 3.497 seconds
2016-10-07 22:57:34.02403 throttled_time 72288643653704 // delta = 0.529 seconds
2016-10-07 22:57:35.02707 throttled_time 72289899729523 // delta = 1.256 seconds
2016-10-07 22:57:36.03015 throttled_time 72289899729523 // delta = 0 seconds
2016-10-07 22:57:37.03311 throttled_time 72289899729523 // delta = 0 seconds
JVM GC 線程
我們發(fā)現(xiàn)一些 CFS 調(diào)度周期暴露了大量的“throttled_time”,我們認(rèn)為這是由(多個(gè))JVM GC 線程引起的伟姐。簡而言之,當(dāng) GC 啟動(dòng)時(shí)倒戏,JVM 會(huì)調(diào)用多個(gè) GC 線程來完成工作杜跷。 JVM 使用內(nèi)部公式來決定 GC 線程的數(shù)量。具體來說憋槐,對于具有 24 個(gè)內(nèi)核的計(jì)算機(jī)淑趾,并行 GC 線程的數(shù)量為 18扣泊,并發(fā) GC 線程的數(shù)量為 5。由于這些大量線程评矩,cgroup 的 CPU 配額很快用完阱飘,導(dǎo)致所有應(yīng)用程序線程(包括 GC 線程)暫停。
// Flag: -XX:+PrintFlagsFinal
// The machine has 24 cpu cores
// GC output
uintx ParallelGCThreads = 18 {product}
uintx ConcGCThreads := 5
CFS 調(diào)度程序如何導(dǎo)致應(yīng)用程序暫停蔗喂?
CFS 調(diào)度程序可能導(dǎo)致應(yīng)用程序長時(shí)間的暫停弱恒。有些情況下棋恼,cgroup(以及在cgroup 中運(yùn)行的應(yīng)用程序)受到限制锈玉,導(dǎo)致應(yīng)用程序暫停很長時(shí)間拉背。雖然“GC 線程更快速地使用 CFS 配額(cpu.cfs_quota_us)”的簡要回答很容易給出,但我們想更全面地了解這個(gè)問題犁罩,以便提出解決方案。
關(guān)于使用 CFS 調(diào)度程序時(shí)應(yīng)用程序暫停有三種問題場景含滴,我們將逐一解釋谈况。為了更好地說明問題递胧,我們使用具體配置的示例(例如,cfs_period 和 cfs_quota)祝闻。
理想場景(預(yù)期場景)
假設(shè) cfs_period 為 300ms联喘,cgroup(僅含有單個(gè)應(yīng)用程序)的 cfs_quota 為 90ms舷蒲。我們還假設(shè)應(yīng)用程序只有一個(gè)活動(dòng)線程來簡化表示。
理想情況下堤框,CPU 調(diào)度程序會(huì)調(diào)度應(yīng)用程序在每個(gè) CFS 周期內(nèi)稀疏運(yùn)行蜈抓,以便應(yīng)用程序不會(huì)長時(shí)間暫停昂儒。如下圖所示,應(yīng)用程序計(jì)劃在 300ms CFS 期間運(yùn)行 3 次腊嗡。計(jì)劃運(yùn)行之間存在應(yīng)用程序暫停燕少,預(yù)期的應(yīng)用程序暫停時(shí)間為 70 毫秒(假設(shè)應(yīng)用程序完全使用 90 毫秒 CPU 配額)蒿囤。
Java 和非 Java 應(yīng)用程序的問題場景
第一個(gè)問題發(fā)生在應(yīng)用程序耗盡 90ms 的所有 CPU 配額時(shí),例如在某些 CFS 時(shí)段的前 90ms 內(nèi)恒傻。然后建邓,由于配額被占用涝缝,在剩余的 210ms 期間,應(yīng)用程序暫停罐氨,用戶經(jīng)歷 210ms 延遲滩援。請注意,多線程應(yīng)用程序的問題更嚴(yán)重租悄,因?yàn)?CPU 配額可以更快地用完泣棋。
Java 應(yīng)用程序的問題場景(GC 期間的 STW 階段)
在 STW(stop the world)GC 暫停期間潭辈,Java 應(yīng)用程序更嚴(yán)重澈吨,因?yàn)?JVM 可以使用多個(gè) GC 線程并行收集垃圾。
假設(shè)在某些 CFS 期間修赞,在應(yīng)用程序運(yùn)行 30ms 后柏副,需要完成 STW GC蚣录。我們假設(shè) GC 工作需要 60ms 的 CPU,而 JVM 有 4 個(gè) GC 線程。然后在 45ms 內(nèi)公壤,可以完全消耗 90ms 的整個(gè) CPU 配額(即,在“運(yùn)行”期間的 CPU 時(shí)間是(60ms “GC”/ 4個(gè)線程 = 15ms)GC 實(shí)際時(shí)間 + 30ms 應(yīng)用運(yùn)行)沾鳄。剩余的 255ms 將是應(yīng)用程序暫停時(shí)間译荞。
顯然休弃,使用更多 GC 線程塔猾,可以更快地耗盡 CPU 配額。請注意糯俗,在現(xiàn)代計(jì)算機(jī)上睦擂,GC 線程的數(shù)量可能會(huì)大得多顿仇,因?yàn)樵?cgroup 中運(yùn)行的每個(gè) JVM 仍會(huì)根據(jù)整個(gè)物理主機(jī)的 CPU 核心數(shù)設(shè)置其 GC 并行化級別。例如跪帝,在 12 核機(jī)器上些阅,默認(rèn)情況下 JVM 使用 9 個(gè) GC 線程市埋。 24 核機(jī)器將使JVM使用 18 個(gè) GC 線程。
Java 應(yīng)用程序的問題場景(GC 期間的并發(fā)階段)
對于流行的 JVM 垃圾收集器,如 CMS 和 G1坷澡,GC 有多個(gè)階段;某些階段是 STW馅扣,其他階段是并發(fā)(非 STW)着降。雖然并發(fā) GC 階段(使用并發(fā) GC 線程)旨在避免 JVM STW任洞,但 cgroup 的使用完全違背了目的。在并發(fā) GC 階段妆偏,使用的 CPU 時(shí)間也會(huì)影響 cgroup 的 CPU 使用率耀销,這實(shí)際上會(huì)導(dǎo)致應(yīng)用程序遇到更大的“STW”暫停熊尉。
建議
我們已經(jīng)看到狰住,由于 JVM GC 和 CFS 調(diào)度之間的交互,在 Linux cgroup 中運(yùn)行的 Java 應(yīng)用程序可能會(huì)遇到更長的應(yīng)用程序暫停肮蛹。為緩解此問題伦忠,我們建議您使用以下調(diào)整:
- 充分配置 CPU 資源(即 CFS 配額)稿辙。顯然,分配給 cgroup 的 CPU 配額越大赋咽,cgroup 被限制的可能性就越小脓匿。
- 適當(dāng)調(diào)整 GC 線程宦赠。
充分配置 CPU 資源
對于我們使用的只有 2 個(gè)活動(dòng)應(yīng)用程序線程的工作負(fù)載,似乎 2 個(gè) CPU 核心可以滿足 CPU 需求爱咬。但是绊起,我們發(fā)現(xiàn)由于 GC 活動(dòng)燎斩,應(yīng)用程序受益于更大的 CPU 配額(即栅表,更多的 CPU 核心)怪瓶。
應(yīng)用程序性能(吞吐量和延遲)
為了了解特定 JVM 工作負(fù)載需要多少 CPU 核心,我們改變了分配給每個(gè)主機(jī) cgroup 的 CPU 份額(以 CPU 核心為單位找岖,其中配額的 CPU 核心等于 CFS 周期的單位)敛滋。我們發(fā)現(xiàn)绎晃,分配了更多內(nèi)核后,應(yīng)用程序吞吐量不斷增加袁余,直到大約 12 個(gè)內(nèi)核颖榜。與 2 個(gè)應(yīng)用程序線程相比述召,這種差異(即 12 對 2)顯示了將CPU 份額充分提供給 Java 應(yīng)用程序的重要性积暖。
我們還計(jì)算了大的分配延遲(即超過 50 毫秒)的數(shù)量,并發(fā)現(xiàn)隨著更多內(nèi)核缅疟,大延遲的數(shù)量持續(xù)下降存淫,直到大約 8 個(gè)內(nèi)核。
Cgroup 的 CPU 使用率
cgroup 的 CPU 使用率(用戶時(shí)間和系統(tǒng)時(shí)間)也隨著分配的內(nèi)核數(shù)量的增加而增加,如下圖所示荚虚。請注意籍茧,值是來自所有核心的聚合值。運(yùn)行時(shí)間為 1,200 秒渴析,CPU 使用率為 6,000 秒表示整體 5 核 CPU 使用率俭茧。
這些結(jié)果表明漓帚,對于具有 2 個(gè)活動(dòng)應(yīng)用程序線程的此特定 Java 應(yīng)用程序胰默,需要將更多內(nèi)核分配給主機(jī) cgroup牵署。
調(diào)整 GC 線程(ParallelGCThreads)
我們還將 ParallelGCThreads 從 1 改為 24奴迅,以了解性能影響。請注意脖隶,是通過 JVM 參數(shù)來調(diào)整 ParallelGCThreads暇检,ConcGCThreads 的值块仆。
更多 GC 線程傾向于更快地耗盡 CFS 配額,如 Cgroup 性能(受限制的 CFS 周期數(shù)和受限制時(shí)間)所示庄敛。結(jié)果藻烤,觀察到更大的延遲怖亭。應(yīng)用程序吞吐量沒有太大變化,但對于此特定工作負(fù)載,它實(shí)際上會(huì)下降峭跳。
這些結(jié)果表明調(diào)低 GC 線程可能有利于應(yīng)用程序性能蛀醉。但是衅码,應(yīng)用程序在許多方面有所不同(例如逝段,GC 頻率,堆大小帚桩,應(yīng)用程序線程的特征)账嚎,因此需要針對每個(gè)應(yīng)用程序評估這些調(diào)整的影響儡蔓。由于空間問題和進(jìn)一步調(diào)查的復(fù)雜性喂江,我們不會(huì)深入研究這方面获询。
Cgroup 性能(受限制的 CFS 周期數(shù)和受限制時(shí)間)
應(yīng)用程序性能(延遲和吞吐量)
討論
CFS 上限限制或相對共享
CFS 調(diào)度支持上限限制(即硬限制)和相對共享。 CFS 相對共享使用cpu.shares 可調(diào)參數(shù)來控制 cgroups 可以使用的 CPU 資源的權(quán)重阻肿。雖然它允許 cgroup 使用其他空閑的 CPU 資源丛塌,但由于依賴于其他 cgroup畜疾,相對共享具有性能可預(yù)測性差的限制啡捶。應(yīng)用程序?qū)⒏鶕?jù) CPU 內(nèi)核的可用性看到不同的性能瞎暑,這使得容量規(guī)劃和性能監(jiān)視難以實(shí)現(xiàn)。
在只有一個(gè) cgroup 主動(dòng)使用 CPU 的機(jī)器上墨榄,相對共享允許“忙” cgroup “竊取” CPU 資源超出其邏輯份額(由其 cpu.shares 部分表示)袄秩,因此 JVM GC 的影響不太明顯逢并。然而砍聊,當(dāng)機(jī)器滿負(fù)載(即,所有 CPU 核心都忙)雇庙,相對共享的有效性與上限強(qiáng)制執(zhí)行相當(dāng)疆前,因?yàn)槊總€(gè) cgroup 僅被允許消耗相應(yīng)的 CPU 資源部分竹椒。因此,由多線程 JVM GC 引起的性能問題 - 以及嚴(yán)重的應(yīng)用程序暫停 - 將顯示出來米辐。
調(diào)整 GC 線程依賴工作負(fù)載
減少 GC 線程的數(shù)量有助于降低 CFS 共享過早耗盡的可能性胸完,從而有助于減少由 CFS 限制導(dǎo)致的長應(yīng)用程序暫停书释。但是,較少的 GC 線程也可能導(dǎo)致更長的 GC STW 暫停赊窥,因?yàn)?GC 工作需要更多時(shí)間才能完成爆惧。因此,需要在這兩個(gè)問題之間進(jìn)行權(quán)衡锨能,并且適當(dāng)數(shù)量的 GC 線程取決于工作負(fù)載特征和延遲 SLA(服務(wù)級別協(xié)議)扯再,因此應(yīng)謹(jǐn)慎選擇。
結(jié)論
在 Linux cgroup 中運(yùn)行 Java 應(yīng)用程序需要徹底了解 JVM GC 如何與 cgroup 的 CPU 調(diào)度交互熄阻。我們發(fā)現(xiàn)由于密集的 GC 活動(dòng),應(yīng)用程序可能會(huì)遇到更長的暫停倔约。為確保滿意的應(yīng)用程序性能秃殉,必須配置足夠的 CPU 配額,并且根據(jù)情況浸剩,應(yīng)調(diào)整 GC 線程钾军。
參考文獻(xiàn)
[1] Application Pauses When Running JVM Inside Linux Control Groups:https://engineering.linkedin.com/blog/2016/11/application-pauses-when-running-jvm-inside-linux-control-groups
[2] Cgroup:https://en.wikipedia.org/wiki/Cgroups
[3] Docker:https://en.wikipedia.org/wiki/Docker_%28software%29
[4] CoreOS:https://en.wikipedia.org/wiki/CoreOS
[5] 容器化:https://engineering.linkedin.com/blog/2016/05/rain--better-resource-allocation-through-containerization
[6] LPS:https://engineering.linkedin.com/blog/2016/04/faster-and-easier-service-deployment-with-lps--our-new-private-c
[7] CFS:https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt
[8] RHEL7:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/resource_management_guide/sec-cpu
[9] 測試程序 GitHub 地址:https://github.com/zhenyun/cgroupsGC