91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Elasticsearch使用優化之拙見

發布時間:2020-07-23 20:35:36 來源:網絡 閱讀:2809 作者:wx5d6cccb1cb158 欄目:建站服務器

Elasticsearch常常作為日志存儲和分析的工具,在企業級應用中常常使用。Elasticsearch提供強大的搜索、分析功能,已經是后端技術棧不可缺少的一部分。

在維護ElastciSearch集群的時候,對Elasticsearch進行了一些調優和分析,現整理成文,純屬拙見,如果有不合理之處,歡迎指出探討。我所使用的Elasticsearch版本為5.x。

Elasticsearch有大量的查詢數據和插入數據的請求,需要大量文件句柄,centos系統默認的1024個文件句柄。如果文件句柄用完了,這就意味著操作系統會拒絕連接,意味著數據可能丟失,這是災難性的后果,

不能被接受。登陸Elasticsearch的啟動用戶,用一下命令查看:

ulimit?-a

查看結果:

core?file?size?(blocks,?-c)?0
data?seg?size?(kbytes,?-d)?unlimited
scheduling?priority?(-e)?0
file?size?(blocks,?-f)?unlimited
pending?signals?(-i)?127673
max?locked?memory?(kbytes,?-l)?unlimited
max?memory?size?(kbytes,?-m)?unlimited
open?files?(-n)?1024
pipe?size?(512?bytes,?-p)?8
POSIX?message?queues?(bytes,?-q)?819200
real-time?priority?(-r)?0
stack?size?(kbytes,?-s)?8192
cpu?time?(seconds,?-t)?unlimited
max?user?processes?(-u)?2056474
virtual?memory?(kbytes,?-v)?unlimited
file?locks?(-x)?unlimited

上面的文件句柄(open files)的個數為1024,在ElasticSearch大量請求的情況下,這個句柄數量是不夠的,可以改成655360。

臨時修改可以通過執行以下命令,即可立即生效,但是機器重啟后又會失效:

ulimit?-n?655360

永久生效,修改/etc/security/limits.conf,需要重啟機器生效:

u_es?-?nofile?655360

上述配置中u_es為啟動ElasticSearch的用戶,設置了該用戶的ElasticSearch的文件句柄為655360、

JVM參數優化

Elasticsearch是運行在JVM上的,對其做JVM參數調優至關重要。最常見的調優是Java內存的分配。下面是JVM的內存模型,具體每塊的作用,不在這里闡述。

Elasticsearch使用優化之拙見


新生代和老年代分配的內存比例給多大?

Jvm內存分為新生代和老年代。

  • 新生代(或者伊甸園)

  • 新實例化的對象分配的空間。新生代空間通常都非常小,一般在 100 MB–500 MB。新生代也包含兩個 幸存 空間。

  • 老年代

  • 較老的對象存儲的空間。這些對象預計將長期留存并持續上很長一段時間。老生代通常比新生代大很多。

新生代、老生代的垃圾回收都有一個階段會“stop the world”。在這段時間里,JVM 停止了程序運行,以便對對象進行可達性分析,收集死亡對象。在這個時間停止階段,一切都不會發生。請求不被服務,ping 不被回應,分片不被分配。整個世界都真的停止了。

對于新生代,這不是什么大問題;那么小的空間意味著 GC 會很快執行完。但是老生代大很多,而這里面一個慢 GC 可能就意味著 1 秒乃至 15 秒的暫停——對于服務器軟件來說這是不可接受的。

那一般我們給新生代和老年代分配多大的內存呢?他們的比例是多少呢?

一般來說,老年代和新生代的內存比例為2:1是比較合適的。比如給堆內存分配3G,則新生代分配1G,其余都給老年代。在ElasticSearce的配置文件jvm.options文件配置:

-Xms3g?//配置堆初始化大小
-Xmx3g?//配置堆的最大內存
-Xmn1g?//配置新生代內存。

該分配多大的內存給Elasticesearch?

在使用Elasticesearch的時候,我們對裝Elasticesearch的機器進行了升級,從最小的8G內存升級到了16G內存,然后到目前的32G內存。一臺機器裝一個Elasticesearch節點,我們應該怎么分配機器的內存呢?

官方給出了解決方案,把一半(少于)的內存分配給Luence,另外的內存分配給ElasticSearch.

內存對于 Elasticsearch 來說絕對是重要的,它可以被許多內存數據結構使用來提供更快的操作。但是說到這里, 還有另外一個內存消耗大戶 非堆內存 (off-heap):Lucene。

Lucene 被設計為可以利用操作系統底層機制來緩存內存數據結構。Lucene 的段是分別存儲到單個文件中的。因為段是不可變的,這些文件也都不會變化,這是對緩存友好的,同時操作系統也會把這些段文件緩存起來,以便更快的訪問。

Lucene 的性能取決于和操作系統的相互作用。如果你把所有的內存都分配給 Elasticsearch 的堆內存,那將不會有剩余的內存交給 Lucene。這將嚴重地影響全文檢索的性能。

標準的建議是把 50% 的可用內存作為 Elasticsearch 的堆內存,保留剩下的 50%。當然它也不會被浪費,Lucene 會很樂意利用起余下的內存。

我們實際的解決辦法是將機器的一半分給Elasticesearch的堆,棧內存、方法區、常量池、非堆內存占用另外一半。

分配給堆最大內存應該小于 32766 mb(~31.99 gb)

JVM 在內存小于 32 GB 的時候會采用一個內存對象指針壓縮技術。

對于 32 位的系統,意味著堆內存大小最大為 4 GB。對于 64 位的系統, 可以使用更大的內存,但是 64 位的指針意味著更大的浪費,因為你的指針本身大了。更糟糕的是, 更大的指針在主內存和各級緩存(例如 LLC,L1 等)之間移動數據的時候,會占用更多的帶寬。

Java 使用一個叫作 內存指針壓縮(compressed oops)的技術來解決這個問題。它的指針不再表示對象在內存中的精確位置,而是表示 偏移量 。這意味著 32 位的指針可以引用 40 億個 對象 , 而不是 40 億個字節。最終, 也就是說堆內存增長到 32 GB 的物理內存,也可以用 32 位的指針表示。

一旦你越過那個神奇的 ~32 GB 的邊界,指針就會切回普通對象的指針。每個對象的指針都變長了,就會使用更多的 CPU 內存帶寬,也就是說你實際上失去了更多的內存。事實上,當內存到達 40–50 GB 的時候,有效內存才相當于使用內存對象指針壓縮技術時候的 32 GB 內存。

這段描述的意思就是說:即便你有足夠的內存,也盡量不要 超過 32 GB。因為它浪費了內存,降低了 CPU 的性能,還要讓 GC 應對大內存。

關掉swap

內存交換 到磁盤對服務器性能來說是 致命 的。

如果內存交換到磁盤上,一個 100 微秒的操作可能變成 10 毫秒。再想想那么多 10 微秒的操作時延累加起來。不難看出 swapping 對于性能是多么可怕。

用以下命令關掉swap:

sudo?swapoff?-a


不要碰以下的配置

所有的調整就是為了優化,但是這些調整,你真的不需要理會它。因為它們經常會被亂用,從而造成系統的不穩定或者糟糕的性能,甚至兩者都有可能。

線程池配置

許多人 喜歡 調整線程池。無論什么原因,人們都對增加線程數無法抵抗。索引太多了?增加線程!搜索太多了?增加線程!節點空閑率低于 95%?增加線程!

Elasticsearch 默認的線程設置已經是很合理的了。對于所有的線程池(除了 搜索 ),線程個數是根據 CPU 核心數設置的。如果你有 8 個核,你可以同時運行的只有 8 個線程,只分配 8 個線程給任何特定的線程池是有道理的。

搜索線程池設置的大一點,配置為 int(( 核心數 * 3 )/ 2 )+ 1 。

垃圾回收器

Elasticsearch 默認的垃圾回收器( GC )是 CMS。這個垃圾回收器可以和應用并行處理,以便它可以最小化停頓。然而,它有兩個 stop-the-world 階段,處理大內存也有點吃力。

盡管有這些缺點,它還是目前對于像 Elasticsearch 這樣低延遲需求軟件的最佳垃圾回收器。官方建議使用 CMS。

合理設置最小主節點

minimum_master_nodes 設置及其重要,為了防止集群腦裂,這個參數應該設置為法定個數就是 ( master 候選節點個數 / 2) + 1。

分片均勻,磁盤優化,剔除掉高負載的Master競選?

筆者在實際生產環境中遇到了有一個節點的負載是其他節點的幾倍,從虛擬機監控上看,所有的節點的qps是差不多的。機器的配置是一樣的,為什么負載會有如此大的差距?

  • 首先,我們懷疑數據分配不均勻,我們排查了下,沒有這種現象。

  • 然后,我們監控到了高負載的節點磁盤IO非常的高,經常達到100%,我們懷疑是那個虛擬機磁盤性能不行。但是我們當時沒有更好的磁盤。

  • 我們找到了一個適中的解決辦法是將這臺高負載的節點剔除Master競選,即將elasticsearch.yml文件中的node.master改為false然后重啟,負載下降了一些。

數據存儲天數的優化

存儲天數的優化,這個需要根據實際的業務來,下面是刪除過期數據的腳本,該腳本來源于https://stackoverflow.com/questions/33430055/removing-old-indices-in-elasticsearch#answer-39746705 ;

#!/bin/bash
searchIndex=logstash-monitor
elastic_url=logging.core.k94.kvk.nl
elastic_port=9200
date2stamp?()?{
?date?--utc?--date?"$1"?+%s
}
dateDiff?(){
?case?$1?in
?-s)?sec=1;?shift;;
?-m)?sec=60;?shift;;
?-h)?sec=3600;?shift;;
?-d)?sec=86400;?shift;;
?*)?sec=86400;;
?esac
?dte1=$(date2stamp?$1)
?dte2=$(date2stamp?$2)
?diffSec=$((dte2-dte1))
?if?((diffSec?<?0));?then?abs=-1;?else?abs=1;?fi
?echo?$((diffSec/sec*abs))
}
for?index?in?$(curl?-s?"${elastic_url}:${elastic_port}/_cat/indices?v"?|?grep?-E?"?${searchIndex}-20[0-9][0-9]\.[0-1][0-9]\.[0-3][0-9]"?|?awk?'{?print?$3?}');?do
?date=$(echo?${index:?-10}?|?sed?'s/\./-/g')
?cond=$(date?+%Y-%m-%d)
?diff=$(dateDiff?-d?$date?$cond)
?echo?-n?"${index}?(${diff})"
?if?[?$diff?-gt?1?];?then
?echo?"?/?DELETE"
?#?curl?-XDELETE?"${elastic_url}:${elastic_port}/${index}?pretty"
?else
?echo?""
?fi
done

然后使用crontab每天定時執行一次這個腳本。

集群分片設置

ES一旦創建好索引后,就無法調整分片的設置,而在ES中,一個分片實際上對應一個lucene 索引,而lucene索引的讀寫會占用很多的系統資源,因此,分片數不能設置過大;所以,在創建索引時,合理配置分片數是非常重要的。一般來說,我們遵循一些原則:

  1. 控制每個分片占用的硬盤容量不超過ES的最大JVM的堆空間設置(一般設置不超過32G,參加上文的JVM設置原則),因此,如果索引的總容量在500G左右,那分片大小在16個左右即可;當然,最好同時考慮原則2。

  2. 考慮一下node數量,一般一個節點有時候就是一臺物理機,如果分片數過多,大大超過了節點數,很可能會導致一個節點上存在多個分片,一旦該節點故障,即使保持了1個以上的副本,同樣有可能會導致數據丟失,集群無法恢復。所以, 一般都設置分片數不超過節點數的3倍。


索引優化

1.修改index_buffer_size 的設置,可以設置成百分數,也可設置成具體的大小,大小可根據集群的規模做不同的設置測試。

indices.memory.index_buffer_size:10%(默認)
indices.memory.min_index_buffer_size:48mb(默認)
indices.memory.max_index_buffer_size
  1. _id字段的使用,應盡可能避免自定義_id, 以避免針對ID的版本管理;建議使用ES的默認ID生成策略或使用數字類型ID做為主鍵。

  2. _all字段及_source字段的使用,應該注意場景和需要,_all字段包含了所有的索引字段,方便做全文檢索,如果無此需求,可以禁用;_source存儲了原始的document內容,如果沒有獲取原始文檔數據的需求,可通過設置includes、excludes 屬性來定義放入_source的字段。

  3. 合理的配置使用index屬性,analyzed 和not_analyzed,根據業務需求來控制字段是否分詞或不分詞。只有 groupby需求的字段,配置時就設置成not_analyzed, 以提高查詢或聚類的效率。

查詢優化

  • 查詢優化,調整filter過濾順序


如果把過濾效果不明顯的條件放在了前面,導致查詢出大量不需要的數據,導致查詢變慢。

把過濾效果明顯的條件提前,按照過濾效果把過濾條件排序

  • 索引時間精度優化


研究Filter的工作原理可以看出,它每次工作都是遍歷整個索引的,所以時間粒度越大,對比越快,搜索時間越短,在不影響功能的情況下,時間精度越低越好,有時甚至犧牲一點精度也值得,當然最好的情況是根本不作時間限制。

es重新刷索引,增加冗余的時間字段,精確到天。帶有時間范圍的查詢使用該字段進行查詢

  • 查詢Fetch Source優化


業務查詢語句獲取的數據集比較大,并且從source中獲取了非必須的字段,導致查詢較慢。

舉例:只需要從es中查詢id這一個字段,卻把所有字段查詢了出來

  • 預索引數據


利用索引查詢數據是最優的方式。例如,如果所有的文檔都有 price 字段,并且大多數查詢都在一個固定的范圍列表中運行范圍聚合,那么可以通過將 index 預索引到 index 和使用 terms 聚合來更快地實現聚合。

例如,像下面這樣:

PUT?index/type/1
{
?"designation":?"spoon",
?"price":?13
}

像這樣的查詢:

GET?index/_search
{
?"aggs":?{
?"price_ranges":?{
?"range":?{
?"field":?"price",
?"ranges":?[
?{?"to":?10?},
?{?"from":?10,?"to":?100?},
?{?"from":?100?}
?]
?}
?}
?}
}

文檔在索引的時候要使用 price_range ,應該被映射為關鍵詞:

PUT?index
{
?"mappings":?{
?"type":?{
?"properties":?{
?"price_range":?{
?"type":?"keyword"
?}
?}
?}
?}
}
PUT?index/type/1
{
?"designation":?"spoon",
?"price":?13,
?"price_range":?"10-100"
}

然后這個請求就直接聚合新字段,而不是在 price 字段運行范圍查詢:

GET?index/_search
{
?"aggs":?{
?"price_ranges":?{
?"terms":?{
?"field":?"price_range"
?}
?}
?}
}

總結

總的來說,ElasticSearch的優化,優化可以從以下方面的考慮:

  • 硬件的優化:機器分配,機器配置,機器內存,機器CPU,機器網絡,機器磁盤性能

  • 操作系統設置優化:文件句柄優化、swap關閉

  • ElasticSearch合理分配節點,合理分配參加競選Master的節點

  • ElasticSearch的存儲的優化,副本數量、索引數量、分片數量

  • ElasticSearch的使用優化,索引的優化,查詢的優化

?最后,分享一份面試寶典《Java核心知識點整理.pdf》,覆蓋了JVM、鎖、高并發、反射、Spring原理、微服務、Zookeeper、數據庫、數據結構等等

有需要的朋友可以加入Java架構技術交流Q群328993819交流、探討、


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盖州市| 万山特区| 工布江达县| 武威市| 宁陕县| 西和县| 黎平县| 磴口县| 澄江县| 铁岭市| 天峻县| 大庆市| 广南县| 皋兰县| 周口市| 绵竹市| 巴楚县| 东丽区| 杭锦后旗| 遵义县| 三穗县| 合川市| 名山县| 江达县| 安顺市| 十堰市| 芜湖县| 武乡县| 巴中市| 漳州市| 花莲市| 西充县| 祁门县| 河西区| 湖北省| 太谷县| 连平县| 潞城市| 仁化县| 城固县| 衡水市|