日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
從10秒到2秒!ElasticSearch性能調(diào)優(yōu)實(shí)踐

 “ELK”是 ElasticSearch、Logstash、Kibana 三門技術(shù)的簡(jiǎn)稱,如今 ELK 技術(shù)棧在互聯(lián)網(wǎng)行業(yè)數(shù)據(jù)開發(fā)領(lǐng)域使用率越來越高。

成都創(chuàng)新互聯(lián)是一家專業(yè)提供木蘭企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、H5網(wǎng)站設(shè)計(jì)、小程序制作等業(yè)務(wù)。10年已為木蘭眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。

做過數(shù)據(jù)收集、數(shù)據(jù)開發(fā)、數(shù)據(jù)存儲(chǔ)的同學(xué)相信對(duì)這個(gè)簡(jiǎn)稱并不陌生,而 ElasticSearch(以下簡(jiǎn)稱 ES)則在 ELK 棧中占著舉足輕重的地位。

前一段時(shí)間,我親身參與了一個(gè) ES 集群的調(diào)優(yōu),今天把我所了解與用到的調(diào)優(yōu)方法與大家分享,如有錯(cuò)誤,請(qǐng)大家包涵與指正。

系統(tǒng)層面的調(diào)優(yōu)

系統(tǒng)層面的調(diào)優(yōu)主要是內(nèi)存的設(shè)定與避免交換內(nèi)存。ES 安裝后默認(rèn)設(shè)置的堆內(nèi)存是 1GB,這很明顯是不夠的,那么接下來就會(huì)有一個(gè)問題出現(xiàn):我們要設(shè)置多少內(nèi)存給 ES 呢?

其實(shí)這是要看我們集群節(jié)點(diǎn)的內(nèi)存大小,還取決于我們是否在服務(wù)器節(jié)點(diǎn)上還要部署其他服務(wù)。

如果內(nèi)存相對(duì)很大,如 64G 及以上,并且我們不在 ES 集群上部署其他服務(wù),那么我建議 ES 內(nèi)存可以設(shè)置為 31G-32G,因?yàn)檫@里有一個(gè) 32G 性能瓶頸問題。

直白的說就是即使你給了 ES 集群大于 32G 的內(nèi)存,其性能也不一定會(huì)更加優(yōu)良,甚至?xí)蝗缭O(shè)置為 31G-32G 時(shí)候的性能。

以我調(diào)優(yōu)的集群為例,我所調(diào)優(yōu)的服務(wù)器節(jié)點(diǎn)內(nèi)存為 64G,服務(wù)器節(jié)點(diǎn)上也基本不跑其他服務(wù),所以我把 ES 集群內(nèi)存大小設(shè)置為了 31G,以充分發(fā)揮集群性能。

設(shè)置 ES 集群內(nèi)存的時(shí)候,還有一點(diǎn)就是確保堆內(nèi)存最小值(Xms)與***值(Xmx)的大小是相同的,防止程序在運(yùn)行時(shí)改變堆內(nèi)存大小,這是一個(gè)很耗系統(tǒng)資源的過程。

還有一點(diǎn)就是避免交換內(nèi)存,可以在配置文件中對(duì)內(nèi)存進(jìn)行鎖定,以避免交換內(nèi)存(也可以在操作系統(tǒng)層面進(jìn)行關(guān)閉內(nèi)存交換)。

對(duì)應(yīng)的參數(shù):

 
 
 
 
  1. bootstrap.mlockall: true

分片與副本

分片 (shard)

ES 是一個(gè)分布式的搜索引擎, 索引通常都會(huì)分解成不同部分, 分布在不同節(jié)點(diǎn)的部分?jǐn)?shù)據(jù)就是分片。

ES 自動(dòng)管理和組織分片, 并在必要的時(shí)候?qū)Ψ制瑪?shù)據(jù)進(jìn)行再平衡分配, 所以用戶基本上不用擔(dān)心分片的處理細(xì)節(jié)。創(chuàng)建索引時(shí)默認(rèn)的分片數(shù)為 5 個(gè),并且一旦創(chuàng)建不能更改。

副本 (replica)

ES 默認(rèn)創(chuàng)建一份副本,就是說在 5 個(gè)主分片的基礎(chǔ)上,每個(gè)主分片都相應(yīng)的有一個(gè)副本分片。

額外的副本有利有弊,有副本可以有更強(qiáng)的故障恢復(fù)能力,但也占了相應(yīng)副本倍數(shù)的磁盤空間。

那我們?cè)趧?chuàng)建索引的時(shí)候,應(yīng)該創(chuàng)建多少個(gè)分片與副本數(shù)呢?對(duì)于副本數(shù),比較好確定,可以根據(jù)我們集群節(jié)點(diǎn)的多少與我們的存儲(chǔ)空間決定。

我們的集群服務(wù)器多,并且有足夠大多存儲(chǔ)空間,可以多設(shè)置副本數(shù),一般是 1-3 個(gè)副本數(shù),如果集群服務(wù)器相對(duì)較少并且存儲(chǔ)空間沒有那么寬松,則可以只設(shè)定一份副本以保證容災(zāi)(副本數(shù)可以動(dòng)態(tài)調(diào)整)。

對(duì)于分片數(shù),是比較難確定的,因?yàn)橐粋€(gè)索引分片數(shù)一旦確定,就不能更改。

所以我們?cè)趧?chuàng)建索引前,要充分的考慮到,以后我們創(chuàng)建的索引所存儲(chǔ)的數(shù)據(jù)量,否則創(chuàng)建了不合適的分片數(shù),會(huì)對(duì)我們的性能造成很大的影響。

對(duì)于分片數(shù)的大小,業(yè)界一致認(rèn)為分片數(shù)的多少與內(nèi)存掛鉤,認(rèn)為 1GB 堆內(nèi)存對(duì)應(yīng) 20-25 個(gè)分片,而一個(gè)分片的大小不要超過 50G,這樣的配置有助于集群的健康。

但是我個(gè)人認(rèn)為這樣的配置方法過于死板,我個(gè)人在調(diào)優(yōu) ES 集群的過程中,根據(jù)總數(shù)據(jù)量的大小,設(shè)定了相應(yīng)的分片,保證每一個(gè)分片的大小沒有超過 50G(大概在 40G 左右),但是相比之前的分片數(shù)查詢起來,效果并不明顯。

之后又嘗試了增加分片數(shù),發(fā)現(xiàn)分片數(shù)增多之后,查詢速度有了明顯的提升,每一個(gè)分片的數(shù)據(jù)量控制在 10G 左右。

查詢大量小分片使得每個(gè)分片處理數(shù)據(jù)速度更快了,那是不是分片數(shù)越多,我們的查詢就越快,ES 性能就越好呢?

其實(shí)也不是,因?yàn)樵诓樵冞^程中,有一個(gè)分片合并的過程,如果分片數(shù)不斷的增加,合并的時(shí)間則會(huì)增加。

而且隨著更多的任務(wù)需要按順序排隊(duì)和處理,更多的小分片不一定要比查詢較小數(shù)量的更大的分片更快。如果有多個(gè)并發(fā)查詢,則有很多小碎片也會(huì)降低查詢吞吐量。

如果現(xiàn)在你的場(chǎng)景是分片數(shù)不合適了,但是又不知道如何調(diào)整,那么有一個(gè)好的解決方法就是按照時(shí)間創(chuàng)建索引,然后進(jìn)行通配查詢。

如果每天的數(shù)據(jù)量很大,則可以按天創(chuàng)建索引,如果是一個(gè)月積累起來導(dǎo)致數(shù)據(jù)量很大,則可以一個(gè)月創(chuàng)建一個(gè)索引。

如果要對(duì)現(xiàn)有索引進(jìn)行重新分片,則需要重建索引,我會(huì)在文章的***總結(jié)重建索引的過程。

參數(shù)調(diào)優(yōu)

下面我會(huì)介紹一些 ES 關(guān)鍵參數(shù)的調(diào)優(yōu)。有很多場(chǎng)景是,我們的 ES 集群占用了多大的 CPU 使用率,該如何調(diào)節(jié)呢?

CPU 使用率高,有可能是寫入導(dǎo)致的,也有可能是查詢導(dǎo)致的,那要怎么查看呢?

可以先通過 GET _nodes/{node}/hot_threads 查看線程棧,查看是哪個(gè)線程占用 CPU 高:

  • 如果是 elasticsearch[{node}][search][T#10] 則是查詢導(dǎo)致的。
  • 如果是 elasticsearch[{node}][bulk][T#1] 則是數(shù)據(jù)寫入導(dǎo)致的。

我在實(shí)際調(diào)優(yōu)中,CPU 使用率很高,如果不是 SSD,建議把 index.merge.scheduler.max_thread_count: 1 索引 merge ***線程數(shù)設(shè)置為 1 個(gè),該參數(shù)可以有效調(diào)節(jié)寫入的性能。

因?yàn)樵诖鎯?chǔ)介質(zhì)上并發(fā)寫,由于尋址的原因,寫入性能不會(huì)提升,只會(huì)降低。

還有幾個(gè)重要參數(shù)可以進(jìn)行設(shè)置,各位同學(xué)可以視自己的集群情況與數(shù)據(jù)情況而定。

index.refresh_interval:這個(gè)參數(shù)的意思是數(shù)據(jù)寫入后幾秒可以被搜索到,默認(rèn)是 1s。

每次索引的 refresh 會(huì)產(chǎn)生一個(gè)新的 lucene 段, 這會(huì)導(dǎo)致頻繁的合并行為,如果業(yè)務(wù)需求對(duì)實(shí)時(shí)性要求沒那么高,可以將此參數(shù)調(diào)大,實(shí)際調(diào)優(yōu)告訴我,該參數(shù)確實(shí)很給力,CPU 使用率直線下降。

indices.memory.index_buffer_size:如果我們要進(jìn)行非常重的高并發(fā)寫入操作,那么***將 indices.memory.index_buffer_size 調(diào)大一些。

index buffer 的大小是所有的 shard 公用的,一般建議(看的大牛博客),對(duì)于每個(gè) shard 來說,最多給 512mb,因?yàn)樵俅笮阅芫蜎]什么提升了。

ES 會(huì)將這個(gè)設(shè)置作為每個(gè) shard 共享的 index buffer,那些特別活躍的 shard 會(huì)更多的使用這個(gè) buffer。默認(rèn)這個(gè)參數(shù)的值是 10%,也就是 jvm heap 的 10%。

translog:ES 為了保證數(shù)據(jù)不丟失,每次 index、bulk、delete、update 完成的時(shí)候,一定會(huì)觸發(fā)刷新 translog 到磁盤上。

在提高數(shù)據(jù)安全性的同時(shí)當(dāng)然也降低了一點(diǎn)性能。如果你不在意這點(diǎn)可能性,還是希望性能優(yōu)先,可以設(shè)置如下參數(shù):

 
 
 
 
  1. "index.translog": {
  2.             "sync_interval": "120s",     --sync間隔調(diào)高
  3.             "durability": "async",       -– 異步更新
  4.             "flush_threshold_size":"1g"  --log文件大小
  5.         }

這樣設(shè)定的意思是開啟異步寫入磁盤,并設(shè)定寫入的時(shí)間間隔與大小,有助于寫入性能的提升。

還有一些超時(shí)參數(shù)的設(shè)置:

  • discovery.zen.ping_timeout 判斷 master 選舉過程中,發(fā)現(xiàn)其他 node 存活的超時(shí)設(shè)置。
  • discovery.zen.fd.ping_interval 節(jié)點(diǎn)被 ping 的頻率,檢測(cè)節(jié)點(diǎn)是否存活。
  • discovery.zen.fd.ping_timeout 節(jié)點(diǎn)存活響應(yīng)的時(shí)間,默認(rèn)為 30s,如果網(wǎng)絡(luò)可能存在隱患,可以適當(dāng)調(diào)大。
  • discovery.zen.fd.ping_retries ping 失敗/超時(shí)多少導(dǎo)致節(jié)點(diǎn)被視為失敗,默認(rèn)為 3。

其他建議

還有一些零碎的優(yōu)化建議如下:

插入索引自動(dòng)生成 id:當(dāng)寫入端使用特定的 id 將數(shù)據(jù)寫入 ES 時(shí),ES 會(huì)檢查對(duì)應(yīng)的索引下是否存在相同的 id。

這個(gè)操作會(huì)隨著文檔數(shù)量的增加使消耗越來越大,所以如果業(yè)務(wù)上沒有硬性需求,建議使用 ES 自動(dòng)生成的 id,加快寫入速率。

避免稀疏索引:索引稀疏之后,會(huì)導(dǎo)致索引文件增大。ES 的 keyword,數(shù)組類型采用 doc_values 結(jié)構(gòu)。

即使字段是空值,每個(gè)文檔也會(huì)占用一定的空間,所以稀疏索引會(huì)造成磁盤增大,導(dǎo)致查詢和寫入效率降低。

我的調(diào)優(yōu)

下面說一說我的調(diào)優(yōu):主要是重建索引,更改了現(xiàn)有索引的分片數(shù)量,經(jīng)過不斷的測(cè)試,找到了一個(gè)***的分片數(shù)量。

重建索引的時(shí)間是漫長(zhǎng)的,在此期間,又對(duì) ES 的寫入進(jìn)行了相應(yīng)的調(diào)優(yōu),使 CPU 使用率降低下來。

附上我的調(diào)優(yōu)參數(shù):

 
 
 
 
  1. index.merge.scheduler.max_thread_count:1 # 索引 merge ***線程數(shù)
  2. indices.memory.index_buffer_size:30%     # 內(nèi)存
  3. index.translog.durability:async # 這個(gè)可以異步寫硬盤,增大寫的速度
  4. index.translog.sync_interval:120s #translog 間隔時(shí)間
  5. discovery.zen.ping_timeout:120s # 心跳超時(shí)時(shí)間
  6. discovery.zen.fd.ping_interval:120s     # 節(jié)點(diǎn)檢測(cè)時(shí)間
  7. discovery.zen.fd.ping_timeout:120s     #ping 超時(shí)時(shí)間
  8. discovery.zen.fd.ping_retries:6     # 心跳重試次數(shù)
  9. thread_pool.bulk.size:20 # 寫入線程個(gè)數(shù) 由于我們查詢線程都是在代碼里設(shè)定好的,我這里只調(diào)節(jié)了寫入的線程數(shù)
  10. thread_pool.bulk.queue_size:1000 # 寫入線程隊(duì)列大小
  11. index.refresh_interval:300s #index 刷新間隔復(fù)制代碼

關(guān)于重建索引

在重建索引之前,首先要考慮一下重建索引的必要性,因?yàn)橹亟ㄋ饕欠浅:臅r(shí)的。

ES 的 reindex api 不會(huì)去嘗試設(shè)置目標(biāo)索引,不會(huì)復(fù)制源索引的設(shè)置,所以我們應(yīng)該在運(yùn)行_reindex 操作之前設(shè)置目標(biāo)索引,包括設(shè)置映射(mapping),分片,副本等。

***步,和創(chuàng)建普通索引一樣創(chuàng)建新索引

當(dāng)數(shù)據(jù)量很大的時(shí)候,需要設(shè)置刷新時(shí)間間隔,把 refresh_intervals 設(shè)置為 -1,即不刷新。

number_of_replicas 副本數(shù)設(shè)置為 0(因?yàn)楦北緮?shù)可以動(dòng)態(tài)調(diào)整,這樣有助于提升速度)。

 
 
 
 
  1. {
  2.     "settings": {
  3.         "number_of_shards": "50",
  4.         "number_of_replicas": "0",
  5.         "index": {
  6.             "refresh_interval": "-1"
  7.         }
  8.     }
  9.     "mappings": {
  10.     }
  11. }

第二步,調(diào)用 reindex 接口

建議加上 wait_for_completion=false 的參數(shù)條件,這樣 reindex 將直接返回 taskId。

 
 
 
 
  1. POST _reindex?wait_for_completion=false
  2. {
  3.   "source": {
  4.     "index": "old_index",   //原有索引
  5.     "size": 5000            //一個(gè)批次處理的數(shù)據(jù)量
  6.   },
  7.   "dest": {
  8.     "index": "new_index",   //目標(biāo)索引
  9.   }
  10. }

第三步:等待

可以通過 GET _tasks?detailed=true&actions=*reindex 來查詢重建的進(jìn)度。如果要取消 task 則調(diào)用_tasks/node_id:task_id/_cancel。

第四步:刪除舊索引,釋放磁盤空間

更多細(xì)節(jié)可以查看 ES 官網(wǎng)的 reindex api。那么有的同學(xué)可能會(huì)問,如果我此刻 ES 是實(shí)時(shí)寫入的,那咋辦呀?

這個(gè)時(shí)候,我們就要重建索引的時(shí)候,在參數(shù)里加上上一次重建索引的時(shí)間戳。

直白的說就是,比如我們的數(shù)據(jù)是 100G,這時(shí)候我們重建索引了,但是這個(gè) 100G 在增加,那么我們重建索引的時(shí)候,需要記錄好重建索引的時(shí)間戳。

記錄時(shí)間戳的目的是下一次重建索引跑任務(wù)的時(shí)候不用全部重建,只需要在此時(shí)間戳之后的重建就可以,如此迭代,直到新老索引數(shù)據(jù)量基本一致,把數(shù)據(jù)流向切換到新索引的名字。

 
 
 
 
  1. POST /_reindex
  2. {
  3.     "conflicts": "proceed",          //意思是沖突以舊索引為準(zhǔn),直接跳過沖突,否則會(huì)拋出異常,停止task
  4.     "source": {
  5.         "index": "old_index"         //舊索引
  6.         "query": {
  7.             "constant_score" : {
  8.                 "filter" : {
  9.                     "range" : {
  10.                         "data_update_time" : {
  11.                             "gte" : 123456789   //reindex開始時(shí)刻前的毫秒時(shí)間戳
  12.                             }
  13.                         }
  14.                     }
  15.                 }
  16.             }
  17.         },
  18.     "dest": {
  19.         "index": "new_index",       //新索引
  20.         "version_type": "external"  //以舊索引的數(shù)據(jù)為準(zhǔn)
  21.         }
  22. }

以上就是我在 ES 調(diào)優(yōu)上的一點(diǎn)總結(jié),希望能夠幫助到對(duì) ES 性能有困惑的同學(xué)們,謝謝大家。


網(wǎng)站標(biāo)題:從10秒到2秒!ElasticSearch性能調(diào)優(yōu)實(shí)踐
地址分享:http://www.dlmjj.cn/article/djesooi.html