天天看點

Loggly:提高ElasticSearch性能的九個進階配置技巧

Loggly日志管理服務在其很多核心功能裡使用ElasticSearch作為搜尋引擎。Jon Gifford在其文章“ElasticSearch vs Solr”中指出,日志管理領域對搜尋技術有了更高的要求。總的來說,它必須能夠:

可靠地進行大規模實時索引-對我們來說,每秒處理10萬條以上日志資料;

高性能、可靠地處理同一索引上的高并發搜尋請求。

當我們搭建Gen2日志管理服務時,我們對ElasticSearch的各項配置資訊進行了反複研究,以便能獲得索引和搜尋的最高性能。不幸的是,這些配置項散落各處,一一找到它們并不容易。這篇文章總結了我們的經驗,您可以參考本文列出的這些項,優化ES在您應用中的使用效果。

技巧1:在開始前,要搞清楚部署拓撲結構

Loggly 使用ES 0.90.13,采用主節點與資料節點互相分離的部署拓撲結構,這裡我們不過多講解其中的細節,但我們要強調的是在決定如何配置之前,你要對部署拓撲結構非常清晰。

此外,我們使用ES節點用戶端(ES node client)與資料節點互動。這使得用戶端對資料節點是透明的;它隻關心與節點用戶端(node client)的互動。要設定節點為主節點還是資料節點,隻需要通過将兩個屬性設定為true或false。例如要設定一個ElasticSearch為資料節點,可以這樣設定:

node.master:false 和node.data: true

很容易對吧。那麼下面我們将讨論一些你可能感興趣的ES進階屬性。在大部分情況下,ES的預設配置都是夠用的,但如果你想讓你的服務表現不論何時都能像我們看到的高性能日志管理服務一樣,那下面的建議就對你有用了。

技巧2:mlockall屬性是擷取性能效率回報的終極武器

Linux将它的實體記憶體(RAM)分成一組稱為pages的記憶體塊。而Swapping是将記憶體頁拷貝到硬碟上一塊預定義空間(swapspace,交換空間),進而釋放記憶體的處理過程。實體記憶體和交換空間的合并大小是可用的虛拟記憶體的數量。

Swapping有個缺點。與記憶體相比,磁盤速度很慢。記憶體速度以納秒計,而硬碟速度卻以毫秒計;是以通路磁盤的時間開銷是通路記憶體的數十萬倍。通路磁盤次數越多,性能就越慢,是以要想方設法避免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.TransportShardReplicationOperationAction$AsyncShardOperationAction$1@13fe9be];

總結:ES的配置屬性對它的靈活伸縮性至關重要

ElasticSearch配置項對其有效性越深入,Loggly的收益也就越大,因為在我們的使用案例中,已經将ES的設計參數用到了極緻(有時更甚,後續文章我們将繼續分享)。如果在使用預設配置的情況下,已經能滿足你應用現階段需要,那麼請放心,随着應用增長,你還有很大的優化空間。

原文位址:https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/

譯者:日志幫(微信ID:rizhibang)

繼續閱讀