Loggly:提高ElasticSearch效能的九個高階配置技巧
Loggly日誌管理服務在其很多核心功能裡使用ElasticSearch作為搜尋引擎。Jon Gifford在其文章“ElasticSearch vs Solr”中指出,日誌管理領域對搜尋技術有了更高的要求。總的來說,它必須能夠:
-
可靠地進行大規模實時索引-對我們來說,每秒處理10萬條以上日誌資料;
-
高效能、可靠地處理同一索引上的高併發搜尋請求。
當我們搭建Gen2日誌管理服務時,我們對ElasticSearch的各項配置資訊進行了反覆研究,以便能獲得索引和搜尋的最高效能。不幸的是,這些配置項散落各處,一一找到它們並不容易。這篇文章總結了我們的經驗,您可以參考本文列出的這些項,優化
技巧1:在開始前,要搞清楚部署拓撲結構
Loggly 使用ES 0.90.13,採用主節點與資料節點相互分離的部署拓撲結構,這裡我們不過多講解其中的細節,但我們要強調的是在決定如何配置之前,你要對部署拓撲結構非常清晰。
此外,我們使用ES節點客戶端(ES node client)與資料節點互動。這使得客戶端對資料節點是透明的;它只關心與節點客戶端(node client)的互動。要設定節點為主節點還是資料節點,只需要通過將兩個屬性設定為true或false。例如要設定一個ElasticSearch為資料節點,可以這樣設定:
node.master:false
很容易對吧。那麼下面我們將討論一些你可能感興趣的ES高階屬性。在大部分情況下,ES的預設配置都是夠用的,但如果你想讓你的服務表現不論何時都能像我們看到的高效能日誌管理服務一樣,那下面的建議就對你有用了。
技巧2:mlockall屬性是獲取效能效率回報的終極武器
Linux將它的實體記憶體(RAM)分成一組稱為pages的記憶體塊。而Swapping是將記憶體頁拷貝到硬碟上一塊預定義空間(swapspace,交換空間),從而釋放記憶體的處理過程。實體記憶體和交換空間的合併大小是可用的虛擬記憶體的數量。
Swapping有個缺點。與記憶體相比,磁碟速度很慢。記憶體速度以納秒計,而硬碟速度卻以毫秒計;所以訪問磁碟的時間開銷是訪問記憶體的數十萬倍。訪問磁碟次數越多,效能就越慢,所以要想方設法避免
mlockall 屬性可以讓ES節點不進行Swapping。(注意僅適用於Linux/Unix系統)。這個屬性可以在yaml檔案中設定。
bootstrap.mlockall:true
mlockall 預設是false的,意味著ES節點被允許Swapping。注意,如果你在檔案中設定了該屬性,就必須重啟ES節點。你可以通過執行以下語句檢視屬性設定是否生效:
curlhttp://localhost:9200/_nodes/process?pretty
如果你決定設定這個屬性,一定確保通過-DXmx選項或ES_HEAP_SIZE給ES節點預留足夠的記憶體。
技巧3: discovery.zen 屬性集合控制ElasticSearch的發現協議
Zen發現協議用於ElasticSearch發現叢集中的其它節點,並建立通訊。discovery.zen.*屬性集合構成了zen發現協議。單播和多播均是發現協議的有效組成部分:
1、多播是指當傳送一個或多個請求給所有節點時,叢集中的節點將被發現。
2、單播是在節點和discovery.zen.ping.unicast.hosts中的IP地址之間的一對一連線。
為了使單播生效,你需要將discovery.zen.ping.multicast.enabled設定為false。還需要通過discovery.zen.ping.unicast.hosts來設定一組主機域名,其中應包含用於通訊的主節點域名。
discovery.zen.minimum_master_nodes用於設定為了進行叢集操作,一個節點需要能看見“see”的最小數量的合格主節點。強烈建議在叢集中超過2個節點時,將該值設定為比1大的值。該值的一個計算方法是N/2+ 1,N是主節點數量。
資料節點和主節點通過以下兩種不同方式相互檢查:
-
主節點通過pinging叢集中所有其它節點,判斷它們是否正常執行;
-
所有其它節點通過pinging主節點確認它們是否正常執行,否則就需要啟動選舉程式。
節點檢測過程由discover.zen.fd.ping_timeout屬性控制。該屬性定義了節點等待反饋的最長時間,預設值是30s。如果你的網速條件不好,需要適當調整該值大小。如果網速很慢,這個值應該設定更高一些。值越高,發現失敗的可能性就越小。
Loggly設定discovery.zen屬性集合如下:
discovery.zen.fd.ping_timeout:30s
discovery.zen.minimum_master_nodes:2
discovery.zen.ping.multicast.enabled:false
discovery.zen.ping.unicast.hosts:[“esmaster01″,”esmaster02″,”esmaster03″]
以上屬性的含義是,節點檢測超時為30s,通過設定discovery.zen.fd.ping_timeout即可。此外,至少兩個主節點要能被其它節點檢測到(我們一共3個主節點)。採用單播協議,單播域名列表是:esmaster01,esmaster02, esmaster03。
技巧4:謹慎對待delete_all_indices!
有個特別重要的事情是ES中的curl API並沒有內建很好認證機制。一共簡單的curlAPI就能導致索引全部被刪,丟失所有資料。下面就是一個會導致誤刪的指令:
curl-XDELETE ‘http://localhost:9200/*/’
為了避免這樣的悲劇發生,你只需要設定以下屬性:
action.disable_delete_all_indices:true.
這個屬性可以確保即便以上curl指令被執行,也不會刪除索引導致錯誤。
技巧5: 欄位數據緩存會導致極慢的分類搜尋(facet search)
這是ElasticSearch指南中如何描述欄位資料快取的:
欄位資料快取主要用在對一個欄位進行排序或分類時。它將把所有欄位值載入到記憶體。為一個欄位建立欄位資料快取將是代價高昂的,需要分配足夠的記憶體,確保能完全載入。
你要牢記,該值設定不當將導致:
-
分類搜尋和排序效能低下
-
如果你對很大的索引進行分類查詢,將導致ES節點記憶體溢位
例如:
indices.fielddata.cache.size:25%
在設定這個值時,關鍵要考慮你的應用將要進行什麼型別分類搜尋。
技巧6: 優化索引請求
在Loggly,我們構建了自己的索引管理系統,因為日誌管理的本質意味著將有頻繁的更新和對映關係變更。這個索引管理系統的功能就是管理ES叢集的索引。當索引需要根據現有配置策略被建立或關閉時,它會做檢查。索引管理有很多策略。例如,當索引大小增長到特定值或者存在時間超過某個時間值,索引管理系統將關閉舊的,建立新的。
本文由日誌幫(公眾號id:rizhibang)翻譯整理。
當索引管理系統傳送一個索引請求給節點處理時,節點更新它自己的對映關係表併發給主節點。主節點會發送給那個節點一共更舊版本的對映關係表。如果有衝突,並不是壞事(也就是說叢集實際上有正確的對映關係表),我們只需要從這個節點向主節點發送一個更新。為了索引請求更高效,我們在資料節點上設定了這個屬性。
indices.cluster.send_refresh_mapping:false
而反過來,傳送更新的對映關係表更重要,因為某些原因,主節點上的對映關係表與實際節點上的衝突。這種情況,更新對映關係表將會在主節點上記錄一個警告。
技巧7: 教你使用ElasticSearch分配相關屬性
分片(Shard)分配是分配分片給節點的處理過程。這可能發生在初始恢復、副本分配或再平衡過程中。也可能發生在新增或刪除節點時。
cluster.routing.allocation.cluster_concurrent_rebalance屬性指定用於併發再平衡的分片數。此屬性的設定要取決於硬碟條件,如CPU數量,IO效能等。如果該屬性設定不當,將影響ElasticSearch索引效能。
cluster.routing.allocation.cluster_concurrent_rebalance:2
該值預設為2,意思是任何時間點,只能有2個分片被移動。該值設定低一些,能降低分片再平衡,從而避免影響索引。
另一個分片分配屬性是cluster.routing.allocation.disk.threshold_enabled。如果該屬性設定為true,在給節點分配分片時將考慮磁碟空間。
當設定為true時,分片分配會考慮兩種情況:低位值、高位值。
-
低位值對應的磁盤使用率, 達到後ES不再分配新分片。在下面的例子中,磁碟使用率97%時,ES將停止分配分片
-
高位值對應的磁盤使用率,達到後分片開始移出節點(下面示例中為99%)
cluster.routing.allocation.disk.threshold_enabled:true
cluster.routing.allocation.disk.watermark.low:.97
cluster.routing.allocation.disk.watermark.high:.99
技巧8:設定恢復相關屬性可以縮短重啟時間
ES包含幾個恢復相關的屬性項,使用它們可以改進ElasticSearch叢集的恢復和重啟時間。我們下面將展示幾個簡單的示例。對你來說,最佳的值取決於正在使用的硬體條件,我們能給的建議就是測試、測試,還是測試。
這個屬性定義的是,在任何時間,一個節點可以有多少分片被用於執行恢復。回收分片是一個IO密集型操作,所以需要謹慎設定該屬性值。
cluster.routing.allocation.node_initial_primaries_recoveries:18
這個屬性控制的是單個節點上同時初始化的主要分片(primaryshards)數量。從節點傳輸到對等節點的回收分片的平行流數量是由indices.recovery.concurrent_streams屬性控制。下面的值是給亞馬遜雲的例項設定的,如果你是使用了自己的硬體,這個值可能需要設定更高。max_bytes_per_sec屬性用於設定每秒傳輸多少位元組,這個屬性也是需要根據硬體條件來配置的。
indices.recovery.concurrent_streams:4
indices.recovery.max_bytes_per_sec:40mb
所有上述屬性,需要在重啟集群后生效。
技巧9:Threadpool屬性防止數據丟失
ES節點有幾個threadpools屬性,用於改進節點內管理的執行緒數量。在Loggly,我們廣泛使用塊請求(bulkrequest),我們發現使用threadpool.bulk.queue_size屬性給批量執行緒池設定正確的數值至關重要,能避免資料丟失或者批量重試。
threadpool.bulk.queue_size:3000
這個屬性值是關於塊請求的。它指定了在沒有更多執行緒來處理批量請求時,ES節點佇列中等待處理的請求數。根據你的塊請求負載情況設定該值。如果你的塊請求數量比這個值高,你將收到像下方示例中的一個RemoteTransportException異常。
注意,在ES中,塊請求佇列中,一個分片對應一個的項,所以如果你想傳送的塊請求數包含很多給分片的資料項,那麼這個屬性的數值需要設定為比你要傳送的批量請求數更高的數值。例如,單個塊請求中包含了10個分片的資料項,那即使你只發送一個塊請求,也必須至少將佇列大小設定為10。這個值設定過大,會消耗你的JVM堆,但卻可以讓ES充分發揮佇列功效,解放你的客戶端。
你要麼把這個值設定高一些,要麼在客戶端妥善處理好RemoteTransportException異常。如果沒有妥善處理異常,你將丟失資料。下面我們將通過傳送超過10個塊請求(佇列值設定為10)的方式模擬展示異常。
RemoteTransportException[[<Bantam>][inet[/192.168.76.1:9300]][bulk/shard]];nested: EsRejectedExecutionException[rejected execution (queue capacity 10) on org.elasticsearch.action.support.replication.Trans[email protected]13fe9be];
總結:ES的配置屬性對它的靈活伸縮性至關重要
ElasticSearch配置項對其有效性越深入,Loggly的收益也就越大,因為在我們的使用案例中,已經將ES的設計引數用到了極致(有時更甚,後續文章我們將繼續分享)。如果在使用預設配置的情況下,已經能滿足你應用現階段需要,那麼請放心,隨著應用增長,你還有很大的優化空間。
原文地址:https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/
譯文轉自日誌幫(微信公眾號id:rizhibang)