<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          ELK 性能優(yōu)化實(shí)踐

          共 10870字,需瀏覽 22分鐘

           ·

          2021-01-13 16:11

          一、背景介紹

          近一年內(nèi)對(duì)公司的 ELK 日志系統(tǒng)做過(guò)性能優(yōu)化,也對(duì) SkyWalking 使用的 ES 存儲(chǔ)進(jìn)行過(guò)性能優(yōu)化,在此做一些總結(jié)。本篇主要是講 ES 在 ELK 架構(gòu)中作為日志存儲(chǔ)時(shí)的性能優(yōu)化方案。

          ELK 架構(gòu)作為日志存儲(chǔ)方案

          ELK日志架構(gòu).png

          二、現(xiàn)狀分析

          1. 版本及硬件配置

          • JDK:JDK1.8_171-b11 (64 位)
          • ES集群:由3臺(tái)16核32G的虛擬機(jī)部署 ES 集群,每個(gè)節(jié)點(diǎn)分配 20 G 堆內(nèi)存
          • ELK版本:6.3.0
          • 垃圾回收器:ES 默認(rèn)指定的老年代(CMS)+ 新生代(ParNew)
          • 操作系統(tǒng):CentOS Linux release 7.4.1708(Core)

          2. 性能問(wèn)題

          隨著接入 ELK 的應(yīng)用越來(lái)越多,每日新增索引約 230 個(gè),新增 document 約 3000 萬(wàn)到 5000 萬(wàn)

          每日上午和下午是日志上傳高峰期,在 Kibana 上查看日志,發(fā)現(xiàn)問(wèn)題:

          (1) 日志會(huì)有 5-40 分鐘的延遲

          (2) 有很多日志丟失,無(wú)法查到

          3. 問(wèn)題分析

          3.1 日志延遲

          首先了解清楚:數(shù)據(jù)什么時(shí)候可以被查到?

          數(shù)據(jù)先是存放在 ES 的內(nèi)存 buffer,然后執(zhí)行 refresh 操作寫(xiě)入到操作系統(tǒng)的內(nèi)存緩存 os cache,此后數(shù)據(jù)就可以被搜索到。

          所以,日志延遲可能是我們的數(shù)據(jù)積壓在 buffer 中沒(méi)有進(jìn)入 os cache 。

          3.2 日志丟失

          查看日志發(fā)現(xiàn)很多 write 拒絕執(zhí)行的情況

          write 線程池拒絕任務(wù)的日志.png

          從日志中可以看出 ES 的 write 線程池已經(jīng)滿負(fù)荷,執(zhí)行任務(wù)的線程已經(jīng)達(dá)到最大 16 個(gè)線程,而 200 容量的隊(duì)列也已經(jīng)放不下新的 task。

          查看線程池的情況也可以看出 write 線程池有很多寫(xiě)入的任務(wù)

          GET?/_cat/thread_pool?v&h=host,name,type,size,active,largest,rejected,completed,queue,queue_size
          write 線程池拒絕任務(wù)的情況.png

          所以我們需要優(yōu)化 ES 的 write 的性能。

          4.解決思路

          4.1 分析場(chǎng)景

          ES 的優(yōu)化分為很多方面,我們要根據(jù)使用場(chǎng)景考慮對(duì) ES 的要求。

          根據(jù)個(gè)人實(shí)踐經(jīng)驗(yàn),列舉三種不同場(chǎng)景下的特點(diǎn)

          • SkyWalking:一般配套使用 ES 作為數(shù)據(jù)存儲(chǔ),存儲(chǔ)鏈路追蹤數(shù)據(jù)、指標(biāo)數(shù)據(jù)等信息。
          • ELK:一般用來(lái)存儲(chǔ)系統(tǒng)日志,并進(jìn)行分析,搜索,定位應(yīng)用的問(wèn)題。
          • 全文搜索的業(yè)務(wù):業(yè)務(wù)中常用 ES 作為全文搜索引擎,例如在外賣(mài)應(yīng)用中,ES 用來(lái)存儲(chǔ)商家、美食的業(yè)務(wù)數(shù)據(jù),用戶在客戶端可以根據(jù)關(guān)鍵字、地理位置等查詢(xún)條件搜索商家、美食信息。

          這三類(lèi)場(chǎng)景的特點(diǎn)如下:


          SkyWalkingELK全文搜索的業(yè)務(wù)
          并發(fā)寫(xiě)高并發(fā)寫(xiě)高并發(fā)寫(xiě)并發(fā)一般不高
          并發(fā)讀并發(fā)低并發(fā)低并發(fā)高
          實(shí)時(shí)性要求5分鐘以?xún)?nèi)30秒以?xún)?nèi)1分鐘內(nèi)
          數(shù)據(jù)完整性可容忍丟失少量數(shù)據(jù)可容忍丟失少量數(shù)據(jù)數(shù)據(jù)盡量100%不丟失

          關(guān)于實(shí)時(shí)性

          • SkyWalking 在實(shí)際使用中,一般使用頻率不太高,往往是發(fā)現(xiàn)應(yīng)用的問(wèn)題后,再去 SkyWalking 查歷史鏈路追蹤數(shù)據(jù)或指標(biāo)數(shù)據(jù),所以可以接受幾分鐘的延遲。
          • ELK 不管是開(kāi)發(fā)、測(cè)試等階段,時(shí)常用來(lái)定位應(yīng)用的問(wèn)題,如果不能快速查詢(xún)出數(shù)據(jù),延遲太久,會(huì)耽誤很多時(shí)間,大大降低工作效率;如果是查日志定位生產(chǎn)問(wèn)題,那更是刻不容緩。
          • 全文搜索的業(yè)務(wù)中一般可以接受在1分鐘內(nèi)查看到最新數(shù)據(jù),比如新商品上架一分鐘后才看到,但盡量實(shí)時(shí),在幾秒內(nèi)可以可看到。

          4.2 優(yōu)化的方向

          可以從三方面進(jìn)行優(yōu)化:JVM 性能調(diào)優(yōu)、ES 性能調(diào)優(yōu)、控制數(shù)據(jù)來(lái)源

          三、ES性能優(yōu)化

          可以從三方面進(jìn)行優(yōu)化:JVM 性能調(diào)優(yōu)、ES 性能調(diào)優(yōu)、控制數(shù)據(jù)來(lái)源

          1. JVM調(diào)優(yōu)

          第一步是 JVM 調(diào)優(yōu)。

          因?yàn)?ES 是依賴(lài)于 JVM 運(yùn)行,沒(méi)有合理的設(shè)置 JVM 參數(shù),將浪費(fèi)資源,甚至導(dǎo)致 ES 很容易 OOM 而崩潰。

          1.1 監(jiān)控 JVM 運(yùn)行情況

          (1)查看 GC 日志

          問(wèn)題:Young GC 和 Full GC 都很頻繁,特別是 Young GC 頻率高,累積耗時(shí)非常多。

          (2) 使用 jstat 看下每秒的 GC 情況參數(shù)說(shuō)明

          • S0:幸存1區(qū)當(dāng)前使用比例
          • S1:幸存2區(qū)當(dāng)前使用比例
          • E:伊甸園區(qū)使用比例
          • O:老年代使用比例
          • M:元數(shù)據(jù)區(qū)使用比例
          • CCS:壓縮使用比例
          • YGC:年輕代垃圾回收次數(shù)
          • FGC:老年代垃圾回收次數(shù)
          • FGCT:老年代垃圾回收消耗時(shí)間
          • GCT:垃圾回收消耗總時(shí)間問(wèn)題:從 jstat gc 中也可以看出,每秒的 eden 增長(zhǎng)速度非常快,很快就滿了。

          1.2 定位 Young GC 頻繁的原因

          1.2.1 檢查是否新生代的空間是否太小

          用下面幾種方式都可查看新、老年代內(nèi)存大小 (1) 使用 jstat -gc pid ?查看 Eden 區(qū)、老年代空間大小 (2) 使用 jmap -heap pid ?查看 Eden 區(qū)、老年代空間大小 (3) 查看 GC 日志中的 GC 明細(xì)其中 996800K 為新生代可用空間大小,即 Eden 區(qū) +1 個(gè) Survivor 區(qū)的空間大小,所以新生代總內(nèi)存是996800K/0.9, 約1081M

          上面的幾種方式都查詢(xún)出,新生代總內(nèi)存約1081M,即1G左右;老年代總內(nèi)存為19864000K,約19G。新、老比例約1:19,出乎意料。

          1.2.1 新老年代空間比例為什么不是 JDK 默認(rèn)的1:2【重點(diǎn)!】

          這真是一個(gè)容易踩坑的地方。如果沒(méi)有顯示設(shè)置新生代大小,JVM 在使用 CMS 收集器時(shí)會(huì)自動(dòng)調(diào)參,新生代的大小在沒(méi)有設(shè)置的情況下是通過(guò)計(jì)算得出的,其大小可能與 NewRatio 的默認(rèn)配置沒(méi)什么關(guān)系而與 ParallelGCThreads 的配置有一定的關(guān)系。

          參考文末鏈接:CMS GC 默認(rèn)新生代是多大?

          所以:新生代大小有不確定性,最好配置 JVM 參數(shù) -XX:NewSize、-XX:MaxNewSize 或者 -xmn ,免得遇到一些奇怪的 GC,讓人措手不及。

          1.3 上面現(xiàn)象造成的影響

          新生代過(guò)小,老年代過(guò)大的影響

          • 新生代過(guò)小: (1) 會(huì)導(dǎo)致新生代 Eden 區(qū)很快用完,而觸發(fā) Young GC,Young GC 的過(guò)程中會(huì) STW(Stop The World),也就是所有工作線程停止,只有 GC 的線程在進(jìn)行垃圾回收,這會(huì)導(dǎo)致 ES 短時(shí)間停頓。頻繁的 Young GC,積少成多,對(duì)系統(tǒng)性能影響較大。(2) 大部分對(duì)象很快進(jìn)入老年代,老年代很容易用完而觸發(fā) Full GC。
          • 老年代過(guò)大:會(huì)導(dǎo)致 Full GC 的執(zhí)行時(shí)間過(guò)長(zhǎng),F(xiàn)ull GC 雖然有并行處理的步驟,但是還是比 Young GC 的 STW 時(shí)間更久,而 GC 導(dǎo)致的停頓時(shí)間在幾十毫秒到幾秒內(nèi),很影響 ES 的性能,同時(shí)也會(huì)導(dǎo)致請(qǐng)求 ES 服務(wù)端的客戶端在一定時(shí)間內(nèi)沒(méi)有響應(yīng)而發(fā)生 timeout 異常,導(dǎo)致請(qǐng)求失敗。

          1.4 JVM優(yōu)化

          1.4.1 配置堆內(nèi)存空間大小

          32G 的內(nèi)存,分配 20G 給堆內(nèi)存是不妥當(dāng)?shù)模哉{(diào)整為總內(nèi)存的50%,即16G。修改 elasticsearch 的 jvm.options 文件

          -Xms16g
          -Xmx16g

          設(shè)置要求:

          • Xms 與 Xmx 大小相同。

            在 jvm 的參數(shù)中 -Xms 和 -Xmx 設(shè)置的不一致,在初始化時(shí)只會(huì)初始 -Xms 大小的空間存儲(chǔ)信息,每當(dāng)空間不夠用時(shí)再向操作系統(tǒng)申請(qǐng),這樣的話必然要進(jìn)行一次 GC,GC會(huì)帶來(lái) STW。而剩余空間很多時(shí),會(huì)觸發(fā)縮容。再次不夠用時(shí)再擴(kuò)容,如此反復(fù),這些過(guò)程會(huì)影響系統(tǒng)性能。同理在 MetaSpace 區(qū)也有類(lèi)似的問(wèn)題。

          • jvm 建議不要超過(guò) 32G,否則 jvm 會(huì)禁用內(nèi)存對(duì)象指針壓縮技術(shù),造成內(nèi)存浪費(fèi)

          • Xmx 和 Xms 不要超過(guò)物理 RAM 的50%。參考文末:官方堆內(nèi)存設(shè)置的建議

            Xmx 和 Xms 不要超過(guò)物理內(nèi)存的50%。Elasticsearch 需要內(nèi)存用于JVM堆以外的其他用途,為此留出空間非常重要。例如,Elasticsearch 使用堆外緩沖區(qū)進(jìn)行有效的網(wǎng)絡(luò)通信,依靠操作系統(tǒng)的文件系統(tǒng)緩存來(lái)高效地訪問(wèn)文件,而 JVM 本身也需要一些內(nèi)存。

          1.4.2 配置堆內(nèi)存新生代空間大小

          因?yàn)橹付ㄐ律臻g大小,導(dǎo)致 JVM 自動(dòng)調(diào)參只分配了 1G 內(nèi)存給新生代。

          修改 elasticsearch 的 jvm.options 文件,加上

          -XX:NewSize=8G
          -XX:MaxNewSize=8G

          老年代則自動(dòng)分配 16G-8G=8G 內(nèi)存,新生代老年代的比例為 1:1。修改后每次 Young GC 頻率更低,且每次 GC 后只有少數(shù)數(shù)據(jù)會(huì)進(jìn)入老年代。

          2.3 使用G1垃圾回收器(未實(shí)踐)

          G1垃圾回收器讓系統(tǒng)使用者來(lái)設(shè)定垃圾回收堆系統(tǒng)的影響,然后把內(nèi)存拆分為大量的小 Region,追蹤每個(gè) Region 中可以回收的對(duì)象大小和回收完成的預(yù)計(jì)花費(fèi)的時(shí)間, 最后在垃圾回收的時(shí)候,盡量把垃圾回收對(duì)系統(tǒng)造成的影響控制在我們指定的時(shí)間范圍內(nèi),同時(shí)在有限的時(shí)間內(nèi)盡量回收更多的垃圾對(duì)象。G1垃圾回收器一般在大數(shù)量、大內(nèi)存的情況下有更好的性能。

          ES默認(rèn)使用的垃圾回收器是:老年代(CMS)+ 新生代(ParNew)。如果是JDK1.9,ES 默認(rèn)使用 G1 垃圾回收器。

          因?yàn)槭褂玫氖?JDK1.8,所以并未切換垃圾回收器。后續(xù)如果再有性能問(wèn)題再切換G1垃圾回收器,測(cè)試是否有更好的性能。

          1.5 優(yōu)化的效果

          1.5.1 新生代使用內(nèi)存的增長(zhǎng)率更低

          優(yōu)化前

          優(yōu)化前.png

          每秒打印一次 GC 數(shù)據(jù)。可以看出,年輕代增長(zhǎng)速度很快,幾秒鐘年輕代就滿了,導(dǎo)致 Young GC 觸發(fā)很頻繁,幾秒鐘就會(huì)觸發(fā)一次。而每次 Young GC 很大可能有存活對(duì)象進(jìn)入老年代,而且,存活對(duì)象多的時(shí)候(看上圖中第一個(gè)紅框中的old gc數(shù)據(jù)),有(51.44-51.08)/100 * 19000M = 約68M。每次進(jìn)入老年代的對(duì)象較多,加上頻繁的 Young GC,會(huì)導(dǎo)致新老年代的分代模式失去了作用,相當(dāng)于老年代取代了新生代來(lái)存放近期內(nèi)生成的對(duì)象。當(dāng)老年代滿了,觸發(fā) Full GC,存活的對(duì)象也會(huì)很多,因?yàn)檫@些對(duì)象很可能還是近期加入的,還存活著,所以一次 Full GC 回收對(duì)象不多。而這會(huì)惡性循環(huán),老年代很快又滿了,又 Full GC,又殘留一大部分存活的,又很容易滿了,所以導(dǎo)致一直頻繁 Full GC。

          優(yōu)化后

          優(yōu)化后.png

          每秒打印一次 GC 數(shù)據(jù)。可以看出,新生代增長(zhǎng)速度慢了許多,至少要 60 秒才會(huì)滿,如上圖紅框中數(shù)據(jù),進(jìn)入老年代的對(duì)象約(15.68-15.60)/100 * 10000 = 8M,非常的少。所以要很久才會(huì)觸發(fā)一次 Full GC 。而且等到 Full GC 時(shí),老年代里很多對(duì)象都是存活了很久的,一般都是不會(huì)被引用,所以很大一部分會(huì)被回收掉,留一個(gè)比較干凈的老年代空間,可以繼續(xù)放很多對(duì)象。

          1.5.2 新生代和老年代 GC 頻率更低

          ES 啟動(dòng)后,運(yùn)行14個(gè)小時(shí)

          優(yōu)化前

          優(yōu)化前.png

          Young GC 每次的時(shí)間是不長(zhǎng)的,從上面監(jiān)控?cái)?shù)據(jù)中可以看出每次GC時(shí)長(zhǎng) 1467.995/27276 約等于 0.05 秒。那一秒鐘有多少時(shí)間是在處理 Young GC ?

          計(jì)算公式:1467 秒/( 60 秒× 60 分 14 小時(shí))= 約 0.028 秒,也就是 100 秒中就有 2.8 秒在Young GC,也就是有 2.8S 的停頓,這對(duì)性能還是有很大消耗的。同時(shí)也可以算出多久一次 Young GC, 方程是:60秒×60分*14小時(shí)/ 27276次 = 1次/X秒,計(jì)算得出X = 0.54,也就是 0.54 秒就會(huì)有一次 Young GC,可見(jiàn) Young GC 頻率非常頻繁。

          優(yōu)化后

          優(yōu)化后效果.png

          Young GC 次數(shù)只有修改前的十分之一,Young GC 時(shí)間也是約八分之一。Full GC 的次數(shù)也是只有原來(lái)的八分之一,GC 時(shí)間大約是四分之一。

          GC 對(duì)系統(tǒng)的影響大大降低,性能已經(jīng)得到很大的提升。

          2.ES 調(diào)優(yōu)

          上面已經(jīng)分析過(guò) ES 作為日志存儲(chǔ)時(shí)的特性是:高并發(fā)寫(xiě)、讀少、接受 30 秒內(nèi)的延時(shí)、可容忍部分日志數(shù)據(jù)丟失。下面我們針對(duì)這些特性對(duì)ES進(jìn)行調(diào)優(yōu)。

          2.1 優(yōu)化 ES 索引設(shè)置

          2.2.1 ES 寫(xiě)數(shù)據(jù)底層原理
          ES寫(xiě)入數(shù)據(jù)的原理.png

          refresh ES 接收數(shù)據(jù)請(qǐng)求時(shí)先存入 ES 的內(nèi)存中,默認(rèn)每隔一秒會(huì)從內(nèi)存 buffer 中將數(shù)據(jù)寫(xiě)入操作系統(tǒng)緩存 os cache,這個(gè)過(guò)程叫做 refresh;

          到了 os cache 數(shù)據(jù)就能被搜索到(所以我們才說(shuō) ES 是近實(shí)時(shí)的,因?yàn)?1 s 的延遲后執(zhí)行 refresh 便可讓數(shù)據(jù)被搜索到)

          fsync translog 會(huì)每隔 5 秒或者在一個(gè)變更請(qǐng)求完成之后執(zhí)行一次 fsync 操作,將 translog 從緩存刷入磁盤(pán),這個(gè)操作比較耗時(shí),如果對(duì)數(shù)據(jù)一致性要求不是很高時(shí)建議將索引改為異步,如果節(jié)點(diǎn)宕機(jī)時(shí)會(huì)有5秒數(shù)據(jù)丟失;

          flush ES 默認(rèn)每隔30分鐘會(huì)將 os cache 中的數(shù)據(jù)刷入磁盤(pán)同時(shí)清空 translog 日志文件,這個(gè)過(guò)程叫做 flush。

          merge

          ES 的一個(gè) index 由多個(gè) shard 組成,而一個(gè) shard 其實(shí)就是一個(gè) Lucene 的 index ,它又由多個(gè) segment 組成,且 Lucene 會(huì)不斷地把一些小的 segment 合并成一個(gè)大的 segment ,這個(gè)過(guò)程被稱(chēng)為段merge(參考文末鏈接)。執(zhí)行索引操作時(shí),ES 會(huì)先生成小的segment,ES 有離線的邏輯對(duì)小的 segment 進(jìn)行合并,優(yōu)化查詢(xún)性能。但是合并過(guò)程中會(huì)消耗較多磁盤(pán) IO,會(huì)影響查詢(xún)性能。

          2.2.2 優(yōu)化方向
          2.2.2.1 優(yōu)化 fsync

          為了保證不丟失數(shù)據(jù),就要保護(hù) translog 文件的安全:

          Elasticsearch 2.0 之后, 每次寫(xiě)請(qǐng)求(如 index 、delete、update、bulk 等)完成時(shí), 都會(huì)觸發(fā)fsync將 translog 中的 segment 刷到磁盤(pán), 然后才會(huì)返回200 OK的響應(yīng);

          或者: 默認(rèn)每隔5s就將 translog 中的數(shù)據(jù)通過(guò)fsync強(qiáng)制刷新到磁盤(pán).

          該方式提高數(shù)據(jù)安全性的同時(shí), 降低了一點(diǎn)性能.

          ==> 頻繁地執(zhí)行 fsync 操作, 可能會(huì)產(chǎn)生阻塞導(dǎo)致部分操作耗時(shí)較久. 如果允許部分?jǐn)?shù)據(jù)丟失, 可設(shè)置異步刷新 translog 來(lái)提高效率,還有降低 flush 的閥值,優(yōu)化如下:

          "index.translog.durability":?"async",
          "index.translog.flush_threshold_size":"1024mb",
          "index.translog.sync_interval":?"120s"
          2.2.2.2 優(yōu)化 refresh

          寫(xiě)入 Lucene 的數(shù)據(jù),并不是實(shí)時(shí)可搜索的,ES 必須通過(guò) refresh 的過(guò)程把內(nèi)存中的數(shù)據(jù)轉(zhuǎn)換成 Lucene 的完整 segment 后,才可以被搜索。

          默認(rèn) 1秒后,寫(xiě)入的數(shù)據(jù)可以很快被查詢(xún)到,但勢(shì)必會(huì)產(chǎn)生大量的 segment,檢索性能會(huì)受到影響。所以,加大時(shí)長(zhǎng)可以降低系統(tǒng)開(kāi)銷(xiāo)。對(duì)于日志搜索來(lái)說(shuō),實(shí)時(shí)性要求不是那么高,設(shè)置為 5 秒或者 10s;對(duì)于 SkyWalking,實(shí)時(shí)性要求更低一些,我們可以設(shè)置為 30s。

          設(shè)置如下:

          "index.refresh_interval":"5s"
          2.2.2.3 優(yōu)化 merge

          index.merge.scheduler.max_thread_count 控制并發(fā)的 merge 線程數(shù),如果存儲(chǔ)是并發(fā)性能較好的 SSD,可以用系統(tǒng)默認(rèn)的 max(1, min(4, availableProcessors / 2)),當(dāng)節(jié)點(diǎn)配置的 cpu 核數(shù)較高時(shí),merge 占用的資源可能會(huì)偏高,影響集群的性能,普通磁盤(pán)的話設(shè)為1,發(fā)生磁盤(pán) IO 堵塞。設(shè)置max_thread_count 后,會(huì)有 max_thread_count + 2 個(gè)線程同時(shí)進(jìn)行磁盤(pán)操作,也就是設(shè)置為 1 允許3個(gè)線程。

          設(shè)置如下:

          "index.merge.scheduler.max_thread_count":"1"
          2.2.2 優(yōu)化設(shè)置
          2.2.2.1 對(duì)現(xiàn)有索引做索引設(shè)置
          #?需要先?close?索引,然后再執(zhí)行,最后成功之后再打開(kāi)
          #?關(guān)閉索引
          curl?-XPOST?'http://localhost:9200/_all/_close'

          #?修改索引設(shè)置
          curl?-XPUT?-H?"Content-Type:application/json"?'http://localhost:9200/_all/_settings?preserve_existing=true'?-d?'{"index.merge.scheduler.max_thread_count"?:?"1","index.refresh_interval"?:?"10s","index.translog.durability"?:?"async","index.translog.flush_threshold_size":"1024mb","index.translog.sync_interval"?:?"120s"}'

          #?打開(kāi)索引
          curl?-XPOST?'http://localhost:9200/_all/_open'

          該方式可對(duì)已經(jīng)生成的索引做修改,但是對(duì)于后續(xù)新建的索引不生效,所以我們可以制作 ES 模板,新建的索引按模板創(chuàng)建索引。

          2.2.2.2 制作索引模板
          #?制作模板?大部分索引都是業(yè)務(wù)應(yīng)用的日志相關(guān)的索引,且索引名稱(chēng)是?202*?這種帶著日期的格式
          PUT?_template/business_log
          {
          ??"index_patterns":?["*202*.*.*"],
          ??"settings":?{
          ??"index.merge.scheduler.max_thread_count"?:?"1","index.refresh_interval"?:?"5s","index.translog.durability"?:?"async","index.translog.flush_threshold_size":"1024mb","index.translog.sync_interval"?:?"120s"}
          }

          #?查詢(xún)模板是否創(chuàng)建成功
          GET?_template/business_log

          因?yàn)槲覀兊臉I(yè)務(wù)日志是按天維度創(chuàng)建索引,索引名稱(chēng)示例:user-service-prod-2020.12.12,所以用通配符*202..**匹配對(duì)應(yīng)要?jiǎng)?chuàng)建的業(yè)務(wù)日志索引。

          2.2 優(yōu)化線程池配置

          前文已經(jīng)提到過(guò),write 線程池滿負(fù)荷,導(dǎo)致拒絕任務(wù),而有的數(shù)據(jù)無(wú)法寫(xiě)入。

          而經(jīng)過(guò)上面的優(yōu)化后,拒絕的情況少了很多,但是還是有拒絕任務(wù)的情況。

          所以我們還需要優(yōu)化 write 線程池。

          從 prometheus 監(jiān)控中可以看到線程池的情況:

          為了更直觀看到 ES 線程池的運(yùn)行情況,我們安裝了 elasticsearch_exporter 收集 ES 的指標(biāo)數(shù)據(jù)到 prometheus,再通過(guò) grafana 進(jìn)行查看。

          經(jīng)過(guò)上面的各種優(yōu)化,拒絕的數(shù)據(jù)量少了很多,但是還是存在拒絕的情況,如下圖:

          image.png

          write 線程池如何設(shè)置:

          參考文末鏈接:ElasticSearch線程池

          write

          For single-document index/delete/update and bulk requests. Thread pool type is fixed with a size of # of available processors, queue_size of 200. The maximum size for this pool is 1 + # of available processors.

          write 線程池采用 fixed 類(lèi)型的線程池,也就是核心線程數(shù)與最大線程數(shù)值相同。線程數(shù)默認(rèn)等于 cpu 核數(shù),可設(shè)置的最大值只能是 cpu 核數(shù)加 1,也就是 16 核 CPU,能設(shè)置的線程數(shù)最大值為 17。

          優(yōu)化的方案:

          • 線程數(shù)改為 17,也就是 cpu 總核數(shù)加 1
          • 隊(duì)列容量加大。隊(duì)列在此時(shí)的作用是消峰。不過(guò)隊(duì)列容量加大本身不會(huì)提升處理速度,只是起到緩沖作用。此外,隊(duì)列容量也不能太大,否則積壓很多任務(wù)時(shí)會(huì)占用過(guò)多堆內(nèi)存。

          config/elasticsearch.yml文件增加配置

          #?線程數(shù)設(shè)置
          thread_pool:
          ??write:
          ????#?線程數(shù)默認(rèn)等于cpu核數(shù),即16??
          ????size:?17
          ????#?因?yàn)槿蝿?wù)多時(shí)存在任務(wù)拒絕的情況,所以加大隊(duì)列大小,可以在間歇性任務(wù)量陡增的情況下,緩存任務(wù)在隊(duì)列,等高峰過(guò)去逐步消費(fèi)完。
          ????queue_size:?10000

          優(yōu)化后效果可以看到,已經(jīng)沒(méi)有拒絕的情況,這樣也就是解決了日志丟失的問(wèn)題。

          2.3 鎖定內(nèi)存,不讓 JVM 使用 Swap

          Swap 交換分區(qū):

          當(dāng)系統(tǒng)的物理內(nèi)存不夠用的時(shí)候,就需要將物理內(nèi)存中的一部分空間釋放出來(lái),以供當(dāng)前運(yùn)行的程序使用。那些被釋放的空間可能來(lái)自一些很長(zhǎng)時(shí)間沒(méi)有什么操作的程序,**這些被釋放的空間被臨時(shí)保存到 Swap 中,等到那些程序要運(yùn)行時(shí),再?gòu)?Swap 中恢復(fù)保存的數(shù)據(jù)到內(nèi)存中。**這樣,系統(tǒng)總是在物理內(nèi)存不夠時(shí),才進(jìn)行 Swap 交換。

          參考文末鏈接:ElasticSearch官方解釋為什么要禁用交換內(nèi)存

          Swap 交換分區(qū)對(duì)性能和節(jié)點(diǎn)穩(wěn)定性非常不利,一定要禁用。它會(huì)導(dǎo)致垃圾回收持續(xù)幾分鐘而不是幾毫秒,并會(huì)導(dǎo)致節(jié)點(diǎn)響應(yīng)緩慢,甚至與集群斷開(kāi)連接。

          有三種方式可以實(shí)現(xiàn) ES 不使用 Swap 分區(qū)

          2.3.1 Linux 系統(tǒng)中的關(guān)閉 Swap (臨時(shí)有效)

          執(zhí)行命令

          sudo?swapoff?-a

          可以臨時(shí)禁用 Swap 內(nèi)存,但是操作系統(tǒng)重啟后失效

          2.3.2 Linux 系統(tǒng)中的盡可能減少 Swap 的使用(永久有效)

          執(zhí)行下列命令

          echo?"vm.swappiness?=?1">>?/etc/sysctl.conf

          正常情況下不會(huì)使用 Swap,除非緊急情況下才會(huì) Swap。

          2.3.3 啟用 bootstrap.memory_lock

          config/elasticsearch.yml 文件增加配置

          #鎖定內(nèi)存,不讓?JVM?寫(xiě)入?Swap,避免降低?ES?的性能
          bootstrap.memory_lock:?true

          2.4 減少分片數(shù)、副本數(shù)

          分片

          索引的大小取決于分片與段的大小,分片過(guò)小,可能導(dǎo)致段過(guò)小,進(jìn)而導(dǎo)致開(kāi)銷(xiāo)增加;分片過(guò)大可能導(dǎo)致分片頻繁 Merge,產(chǎn)生大量 IO 操作,影響寫(xiě)入性能。

          因?yàn)槲覀兠總€(gè)索引的大小在 15G 以下,而默認(rèn)是 5 個(gè)分片,沒(méi)有必要這么多,所以調(diào)整為 3 個(gè)。

          "index.number_of_shards":?"3"

          分片的設(shè)置我們也可以配置在索引模板。

          副本數(shù)

          減少集群副本分片數(shù),過(guò)多副本會(huì)導(dǎo)致 ES 內(nèi)部寫(xiě)擴(kuò)大。副本數(shù)默認(rèn)為 1,如果某索引所在的 1 個(gè)節(jié)點(diǎn)宕機(jī),擁有副本的另一臺(tái)機(jī)器擁有索引備份數(shù)據(jù),可以讓索引數(shù)據(jù)正常使用。但是數(shù)據(jù)寫(xiě)入副本會(huì)影響寫(xiě)入性能。對(duì)于日志數(shù)據(jù),有 1 個(gè)副本即可。對(duì)于大數(shù)據(jù)量的索引,可以設(shè)置副本數(shù)為0,減少對(duì)性能的影響。

          "index.number_of_replicas":?"1"

          分片的設(shè)置我們也可以配置在索引模板。

          3.控制數(shù)據(jù)來(lái)源

          3.1 應(yīng)用按規(guī)范打印日志

          有的應(yīng)用 1 天生成 10G 日志,而一般的應(yīng)用只有幾百到 1G。一天生成 10G 日志一般是因?yàn)椴糠謶?yīng)用日志使用不當(dāng),很多大數(shù)量的日志可以不打,比如大數(shù)據(jù)量的列表查詢(xún)接口、報(bào)表數(shù)據(jù)、debug 級(jí)別日志等數(shù)據(jù)是不用上傳到日志服務(wù)器,這些即影響日志存儲(chǔ)的性能,更影響應(yīng)用自身性能

          四、ES性能優(yōu)化后的效果

          優(yōu)化后的兩周內(nèi) ELK 性能良好,沒(méi)有使用上的問(wèn)題:

          • ES 數(shù)據(jù)不再丟失

          • 數(shù)據(jù)延時(shí)在 10 秒之內(nèi),一般在 5 秒可以查出

          • 每個(gè) ES 節(jié)點(diǎn)負(fù)載比較穩(wěn)定,CPU 和內(nèi)存使用率都不會(huì)過(guò)高,如下圖

            ES 節(jié)點(diǎn)運(yùn)行情況.png

          五、參考文檔

          參考

          • 記一次 ElasticSearch 優(yōu)化總結(jié): https://juejin.cn/post/6844903689480568840
          • ElasticSearch 的數(shù)據(jù)寫(xiě)入流程及優(yōu)化: https://www.cnblogs.com/zhangan/p/11231990.html
          • 百億級(jí)實(shí)時(shí)計(jì)算系統(tǒng)性能優(yōu)化–—ElasticSearch篇 : https://www.cnblogs.com/qcloud1001/p/14068642.html
          • CMS GC 默認(rèn)新生代是多大?: https://www.jianshu.com/p/832fc4d4cb53
          • 官方堆內(nèi)存設(shè)置的建議: https://www.elastic.co/guide/en/elasticsearch/reference/current/important-settings.html#heap-size-settings
          • ElasticSearch線程池: https://www.elastic.co/guide/en/elasticsearch/reference/6.3/modules-threadpool.html#modules-threadpool
          • ElasticSearch官方解釋為什么要禁用交換內(nèi)存: https://www.elastic.co/guide/en/elasticsearch/reference/6.3/setup-configuration-memory.html
          • 段 merge: https://www.elastic.co/guide/en/elasticsearch/reference/6.3/index-modules-merge.html
          • https://stackoverflow.com/questions/15426441/understanding-segments-in-elasticsearch
          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美成人网站在线观看 | 国产一区二区免费看 | 色先锋AV| 成人毛片18女人免费 | 成人 在线 欧美 |