偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

優(yōu)化Kubernetes上的JVM Warm-up

開發(fā) 前端
在這篇文章中,我將討論我們?cè)贙ubernetes集群中使用Java服務(wù)關(guān)于JVM預(yù)熱問題的經(jīng)驗(yàn)和方法。

 

JVM 預(yù)熱(warm-up)是一個(gè)臭名昭著的問題。盡管基于JVM的應(yīng)用程序有著出色的性能,但是需要一個(gè)預(yù)熱的過程,在預(yù)熱期間,性能不是最佳的。它可以歸因于即時(shí)(JIT)編譯之類的事情,它通過收集使用情況配置文件信息來優(yōu)化常用代碼。最終的負(fù)面影響是,與平均時(shí)間相比,在預(yù)熱期間收到的請(qǐng)求將具有非常高的響應(yīng)時(shí)間。在容器化,高吞吐量,頻繁部署和自動(dòng)伸縮的環(huán)境中,此問題可能會(huì)加劇。

在這篇文章中,我將討論我們?cè)贙ubernetes集群中使用Java服務(wù)關(guān)于JVM預(yù)熱問題的經(jīng)驗(yàn)和方法。

創(chuàng)世記

幾年前,我們從單體架構(gòu)逐步轉(zhuǎn)為微服務(wù)架構(gòu),并且部署到Kubernetes中。大多數(shù)新服務(wù)都是用Java開發(fā)的。當(dāng)我們啟用Java服務(wù)時(shí),我們首先遇到了這個(gè)問題。通過負(fù)載測(cè)試執(zhí)行了正常的容量規(guī)劃過程,并確定N個(gè)容器足以處理超出預(yù)期的峰值流量。

盡管該服務(wù)可以毫不費(fèi)力地處理高峰流量,但我們開始在部署過程中發(fā)現(xiàn)問題。我們的每個(gè)Pod在高峰時(shí)間處理的RPM都超過10k,而我們使用的是Kubernetes滾動(dòng)更新機(jī)制。在部署期間,服務(wù)的響應(yīng)時(shí)間會(huì)激增幾分鐘,然后再穩(wěn)定到通常的穩(wěn)定狀態(tài)。在我們的NewRelic儀表板中,我們將看到類似于以下的圖形:

同時(shí),依賴于我們?cè)摬渴鸬钠渌?wù)在相關(guān)時(shí)間段內(nèi)也發(fā)生了高響應(yīng)時(shí)間和超時(shí)錯(cuò)誤。

Take 1: 增加應(yīng)用數(shù)目

我們很快意識(shí)到該問題與JVM預(yù)熱階段有關(guān),但是由于正在進(jìn)行其他重要事情,因此沒有太多時(shí)間進(jìn)行排查。因此,我們嘗試了最簡(jiǎn)單的解決方案--增加容器的數(shù)量,以減少每個(gè)容器的吞吐量。我們將Pod的數(shù)量增加了幾乎三倍,因此每個(gè)Pod在高峰時(shí)處理的吞吐量約為4k RPM。我們還調(diào)整了部署策略,以確保一次最多25%的部署(使用maxSurge和maxUnavailable參數(shù))。這樣就解決了問題,盡管我們的運(yùn)行速度是穩(wěn)態(tài)所需容量的3倍,但我們能夠在我們的服務(wù)或任何相關(guān)服務(wù)中毫無(wú)問題地進(jìn)行部署。

在接下來的幾個(gè)月中,隨著我們遷移更多服務(wù),我們也開始在其他服務(wù)中頻繁注意到該問題。然后,我們決定花一些時(shí)間來排查問題并找到更好的解決方案。

Take 2: Warm-Up 腳本

閱讀各種文章之后,我們決定嘗試一下熱身腳本。我們的想法是運(yùn)行一個(gè)預(yù)熱腳本,該腳本將綜合請(qǐng)求發(fā)送給該服務(wù)幾分鐘,以期預(yù)熱JVM,然后才允許實(shí)際流量通過。

為了創(chuàng)建預(yù)熱腳本,我們從生產(chǎn)流量中抓取了實(shí)際的URL。然后,我們創(chuàng)建了一個(gè)Python腳本,該腳本使用這些URL發(fā)送并行請(qǐng)求。我們相應(yīng)地配置了就緒探針的initialDelaySeconds,以確保預(yù)熱腳本在Pod準(zhǔn)備就緒并開始接受流量之前完成。

令我們驚訝的是,盡管我們看到了一些改進(jìn),但這并不重要。我們?nèi)匀挥^察到響應(yīng)時(shí)間和錯(cuò)誤。另外,預(yù)熱腳本引入了新問題。之前,我們的Pod可以在40-50秒內(nèi)準(zhǔn)備就緒,但是使用腳本,它們大約需要3分鐘,這在部署過程中成為一個(gè)問題,但更重要的是在自動(dòng)伸縮過程中。我們對(duì)熱身機(jī)制進(jìn)行了一些調(diào)整,例如在熱身腳本和實(shí)際流量之間進(jìn)行短暫的重疊,并在腳本本身中進(jìn)行更改,但并沒有看到明顯的改進(jìn)。最后,我們認(rèn)為熱身策略所帶來的小收益是不值得的,因此完全放棄了。

Take 3: 探索啟發(fā)式技術(shù)

既然我們的熱身腳本想法破滅了,決定嘗試一些啟發(fā)式技術(shù):

  • GC (G1, CMS, and Parallel) and various GC parameters
  • Heap memory
  • CPU allocated

經(jīng)過幾輪實(shí)驗(yàn),我們終于取得了突破。我們正在測(cè)試的服務(wù)配置了Kubernetes資源限制:

  1. resources: 
  2.   requests: 
  3.     cpu: 1000m 
  4.     memory: 2000Mi 
  5.   limits: 
  6.     cpu: 1000m 
  7.     memory: 2000Mi 

我們?cè)黾恿薈PU請(qǐng)求并將其限制為2000m,并部署了該服務(wù)以查看影響。與預(yù)熱腳本相比,我們?cè)陧憫?yīng)時(shí)間和錯(cuò)誤方面看到了巨大的進(jìn)步。

為了進(jìn)一步測(cè)試,我們將配置升級(jí)到3000m CPU,令人驚訝的是,問題完全消失了。如下所示,響應(yīng)時(shí)間沒有峰值。

很快就發(fā)現(xiàn)問題出在CPU節(jié)流。顯然,在預(yù)熱階段,JVM需要比平均穩(wěn)態(tài)更多的CPU時(shí)間,但是Kubernetes資源處理機(jī)制(CGroup)正在按照配置的限制來限制CPU。

有一種直接的方法可以驗(yàn)證這一點(diǎn)。 Kubernetes公開了每個(gè)容器的度量標(biāo)準(zhǔn) container_cpu_cfs_throttled_seconds_total ,它表示自此容器啟動(dòng)以來已為它節(jié)流了多少秒的CPU。如果我們?cè)?000m配置下遵守此指標(biāo),則應(yīng)該在開始時(shí)看到很多節(jié)流,然后在幾分鐘后穩(wěn)定下來。我們使用此配置進(jìn)行了部署,這是Prometheus中所有Pod的 container_cpu_cfs_throttled_seconds_total 圖表:

正如預(yù)期的那樣,在容器啟動(dòng)的前5到7分鐘內(nèi)會(huì)有很多節(jié)流--通常在500秒到1000秒之間,但是隨后它穩(wěn)定下來,證實(shí)了我們的假設(shè)。

當(dāng)我們使用3000m CPU配置進(jìn)行部署時(shí),我們觀察到下圖:

CPU節(jié)流幾乎可以忽略不計(jì)(幾乎所有Pod不到4秒),這就是部署順利進(jìn)行的原因。

Take 4: 配置 Burstable Qos

盡管我們發(fā)現(xiàn)了造成此問題的瓶頸,但從成本方面來看,該解決方案(增加CPU請(qǐng)求/限制三倍)并不可行。此解決方案實(shí)際上可能比運(yùn)行更多的Pod更糟糕,因?yàn)镵ubernetes根據(jù)請(qǐng)求調(diào)度Pod,這可能會(huì)導(dǎo)致集群自動(dòng)伸縮器頻繁觸發(fā),從而向集群添加更多節(jié)點(diǎn)。

再次思考這個(gè)問題:

在最初的預(yù)熱階段(持續(xù)幾分鐘),JVM需要比配置的限制(1000m)更多的CPU(〜3000m)。預(yù)熱后,即使CPU限制為1000m,JVM也可以充分發(fā)揮其潛力。 Kubernetes使用“請(qǐng)求”而不是“限制”來調(diào)度Pod。

一旦我們以清晰,平靜的心態(tài)閱讀問題陳述,答案就會(huì)出現(xiàn):Kubernetes Burstable QoS。

Kubernetes根據(jù)配置的資源請(qǐng)求和限制將QoS類分配給Pod。

到目前為止,我們一直在通過使用相等值(最初都是1000m,然后都是3000m)指定請(qǐng)求和限制來使用保證的QoS類。盡管QoS保證有其好處,但在整個(gè)Pod生命周期的整個(gè)周期中,我們不需要3個(gè)CPU的全部功能,我們只需要在最初的幾分鐘內(nèi)使用它即可。 Burstable QoS類就是這樣做的。它允許我們指定小于限制的請(qǐng)求,例如

  1. resources: 
  2.   requests: 
  3.     cpu: 1000m 
  4.     memory: 2000Mi 
  5.   limits: 
  6.     cpu: 3000m 
  7.     memory: 2000Mi 

由于Kubernetes使用請(qǐng)求中指定的值來調(diào)度Pod,因此它將找到具有1000m備用CPU容量的節(jié)點(diǎn)來調(diào)度此Pod。但是,由于此限制在3000m處要高得多,因此,如果應(yīng)用程序在任何時(shí)候都需要超過1000m的CPU,并且該節(jié)點(diǎn)上有可用的CPU備用容量,則不會(huì)在CPU上限制應(yīng)用程序。如果可用,它可以使用長(zhǎng)達(dá)3000m。

最后,是時(shí)候檢驗(yàn)假設(shè)了。我們更改了資源配置并部署了應(yīng)用程序。而且有效!我們?cè)龠M(jìn)行了幾次部署,以測(cè)試我們是否可以重復(fù)結(jié)果,并且該結(jié)果始終如一。此外,我們監(jiān)控了 container_cpu_cfs_throttled_seconds_total 指標(biāo),這是其中一種部署的圖表:

如我們所見,此圖與3000m CPU的“保證的QoS”設(shè)置非常相似。節(jié)流幾乎可以忽略不計(jì),它證實(shí)了具有Burstable QoS的解決方案有效。

結(jié)論

Kubernetes資源限制是一個(gè)重要的概念,我們?cè)谒谢贘ava的服務(wù)中實(shí)施了該解決方案,并且部署和自動(dòng)擴(kuò)展都可以正常工作,沒有任何問題。

以下三個(gè)關(guān)鍵點(diǎn)需要大家注意:

  1. container_cpu_cfs_throttled_seconds_total 

 

 

責(zé)任編輯:張燕妮 來源: 知乎
相關(guān)推薦

2023-07-24 16:09:58

Kubernetes云計(jì)算

2023-09-01 08:59:57

2011-11-28 10:50:56

JavaJVM優(yōu)化

2021-02-19 09:20:04

KubernetesSpark云帳戶

2023-08-01 08:20:42

JVM優(yōu)化虛擬機(jī)

2023-08-04 08:53:42

2023-08-08 10:29:55

JVM優(yōu)化垃圾回收

2010-09-26 10:02:09

JVM優(yōu)化配置

2021-04-25 11:00:37

Kubernetes優(yōu)化Linux

2023-07-14 12:28:07

JVM優(yōu)化操作

2023-01-26 11:56:31

Kubernete虛擬機(jī)k3s

2024-03-14 08:17:33

JVMJava對(duì)象

2013-03-04 10:20:23

JVM優(yōu)化eclipseJVM

2013-10-16 10:45:29

JVMJava

2013-03-04 10:59:47

eclipseJVM

2022-08-25 17:12:53

Kubernetes工具鏈CI

2023-08-02 08:38:27

JVM加載機(jī)制

2021-03-29 09:00:00

Kubernetes容器工具

2023-04-25 08:01:23

JavaQuarkusKubernetes

2020-03-25 08:00:32

Kubernetes節(jié)點(diǎn)工作
點(diǎn)贊
收藏

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