Loggly日志管理服務(wù)在其很多核心功能里使用ElasticSearch作為搜索引擎。Jon Gifford在其文章“ElasticSearch vs Solr”中指出劈榨,日志管理領(lǐng)域?qū)λ阉骷夹g(shù)有了更高的要求史辙」╄担總的來說诵姜,它必須能夠:
可靠地進行大規(guī)模實時索引-對我們來說朱沃,每秒處理10萬條以上日志數(shù)據(jù);
高性能、可靠地處理同一索引上的高并發(fā)搜索請求逗物。
當我們搭建Gen2日志管理服務(wù)時,我們對ElasticSearch的各項配置信息進行了反復(fù)研究瑟俭,以便能獲得索引和搜索的最高性能翎卓。不幸的是,這些配置項散落各處摆寄,一一找到它們并不容易失暴。這篇文章總結(jié)了我們的經(jīng)驗,您可以參考本文列出的這些項微饥,優(yōu)化ES在您應(yīng)用中的使用效果逗扒。
技巧1:在開始前,要搞清楚部署拓撲結(jié)構(gòu)
Loggly 使用ES 0.90.13欠橘,采用主節(jié)點與數(shù)據(jù)節(jié)點相互分離的部署拓撲結(jié)構(gòu)矩肩,這里我們不過多講解其中的細節(jié),但我們要強調(diào)的是在決定如何配置之前肃续,你要對部署拓撲結(jié)構(gòu)非常清晰黍檩。
此外,我們使用ES節(jié)點客戶端(ES node client)與數(shù)據(jù)節(jié)點交互始锚。這使得客戶端對數(shù)據(jù)節(jié)點是透明的刽酱;它只關(guān)心與節(jié)點客戶端(node client)的交互。要設(shè)置節(jié)點為主節(jié)點還是數(shù)據(jù)節(jié)點瞧捌,只需要通過將兩個屬性設(shè)置為true或false棵里。例如要設(shè)置一個ElasticSearch為數(shù)據(jù)節(jié)點,可以這樣設(shè)置:
node.master:false 和node.data: true
很容易對吧姐呐。那么下面我們將討論一些你可能感興趣的ES高級屬性殿怜。在大部分情況下,ES的默認配置都是夠用的皮钠,但如果你想讓你的服務(wù)表現(xiàn)不論何時都能像我們看到的高性能日志管理服務(wù)一樣稳捆,那下面的建議就對你有用了。
技巧2:mlockall屬性是獲取性能效率回報的終極武器
Linux將它的物理內(nèi)存(RAM)分成一組稱為pages的內(nèi)存塊麦轰。而Swapping是將內(nèi)存頁拷貝到硬盤上一塊預(yù)定義空間(swapspace乔夯,交換空間),從而釋放內(nèi)存的處理過程款侵。物理內(nèi)存和交換空間的合并大小是可用的虛擬內(nèi)存的數(shù)量末荐。
Swapping有個缺點。與內(nèi)存相比新锈,磁盤速度很慢甲脏。內(nèi)存速度以納秒計,而硬盤速度卻以毫秒計;所以訪問磁盤的時間開銷是訪問內(nèi)存的數(shù)十萬倍块请。訪問磁盤次數(shù)越多娜氏,性能就越慢,所以要想方設(shè)法避免Swapping墩新。
mlockall 屬性可以讓ES節(jié)點不進行Swapping贸弥。(注意僅適用于Linux/Unix系統(tǒng))。這個屬性可以在yaml文件中設(shè)置海渊。
bootstrap.mlockall:true
mlockall 默認是false的绵疲,意味著ES節(jié)點被允許Swapping。注意臣疑,如果你在文件中設(shè)置了該屬性盔憨,就必須重啟ES節(jié)點。你可以通過執(zhí)行以下語句查看屬性設(shè)置是否生效:
curlhttp://localhost:9200/_nodes/process?pretty
如果你決定設(shè)置這個屬性讯沈,一定確保通過-DXmx選項或ES_HEAP_SIZE給ES節(jié)點預(yù)留足夠的內(nèi)存郁岩。
技巧3: discovery.zen 屬性集合控制ElasticSearch的發(fā)現(xiàn)協(xié)議
Zen發(fā)現(xiàn)協(xié)議用于ElasticSearch發(fā)現(xiàn)集群中的其它節(jié)點,并建立通訊芙盘。discovery.zen.*屬性集合構(gòu)成了zen發(fā)現(xiàn)協(xié)議驯用。單播和多播均是發(fā)現(xiàn)協(xié)議的有效組成部分:
1、多播是指當發(fā)送一個或多個請求給所有節(jié)點時儒老,集群中的節(jié)點將被發(fā)現(xiàn)蝴乔。
2、單播是在節(jié)點和discovery.zen.ping.unicast.hosts中的IP地址之間的一對一連接驮樊。
為了使單播生效薇正,你需要將discovery.zen.ping.multicast.enabled設(shè)置為false。還需要通過discovery.zen.ping.unicast.hosts來設(shè)置一組主機域名囚衔,其中應(yīng)包含用于通信的主節(jié)點域名挖腰。
discovery.zen.minimum_master_nodes用于設(shè)置為了進行集群操作,一個節(jié)點需要能看見“see”的最小數(shù)量的合格主節(jié)點练湿。強烈建議在集群中超過2個節(jié)點時猴仑,將該值設(shè)置為比1大的值。該值的一個計算方法是N/2+ 1肥哎,N是主節(jié)點數(shù)量辽俗。
數(shù)據(jù)節(jié)點和主節(jié)點通過以下兩種不同方式相互檢查:
主節(jié)點通過pinging集群中所有其它節(jié)點,判斷它們是否正常運行篡诽;
所有其它節(jié)點通過pinging主節(jié)點確認它們是否正常運行崖飘,否則就需要啟動選舉程序。
節(jié)點檢測過程由discover.zen.fd.ping_timeout屬性控制杈女。該屬性定義了節(jié)點等待反饋的最長時間朱浴,默認值是30s吊圾。如果你的網(wǎng)速條件不好,需要適當調(diào)整該值大小翰蠢。如果網(wǎng)速很慢项乒,這個值應(yīng)該設(shè)置更高一些。值越高梁沧,發(fā)現(xiàn)失敗的可能性就越小板丽。
Loggly設(shè)置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″]
以上屬性的含義是,節(jié)點檢測超時為30s趁尼,通過設(shè)置discovery.zen.fd.ping_timeout即可。此外猖辫,至少兩個主節(jié)點要能被其它節(jié)點檢測到(我們一共3個主節(jié)點)酥泞。采用單播協(xié)議,單播域名列表是:esmaster01,esmaster02, esmaster03啃憎。
技巧4:謹慎對待delete_all_indices芝囤!
有個特別重要的事情是ES中的curl API并沒有內(nèi)置很好認證機制。一共簡單的curlAPI就能導(dǎo)致索引全部被刪辛萍,丟失所有數(shù)據(jù)悯姊。下面就是一個會導(dǎo)致誤刪的指令:
curl-XDELETE ‘http://localhost:9200/*/’
為了避免這樣的悲劇發(fā)生,你只需要設(shè)置以下屬性:
action.disable_delete_all_indices:true.
這個屬性可以確保即便以上curl指令被執(zhí)行贩毕,也不會刪除索引導(dǎo)致錯誤悯许。
技巧5: 字段數(shù)據(jù)緩存會導(dǎo)致極慢的分類搜索(facet search)
這是ElasticSearch指南中如何描述字段數(shù)據(jù)緩存的:
字段數(shù)據(jù)緩存主要用在對一個字段進行排序或分類時。它將把所有字段值加載到內(nèi)存辉阶。為一個字段建立字段數(shù)據(jù)緩存將是代價高昂的先壕,需要分配足夠的內(nèi)存,確保能完全加載谆甜。
你要牢記垃僚,該值設(shè)置不當將導(dǎo)致:
分類搜索和排序性能低下
如果你對很大的索引進行分類查詢,將導(dǎo)致ES節(jié)點內(nèi)存溢出
例如:
indices.fielddata.cache.size:25%
在設(shè)置這個值時规辱,關(guān)鍵要考慮你的應(yīng)用將要進行什么類型分類搜索谆棺。
技巧6: 優(yōu)化索引請求
在Loggly,我們構(gòu)建了自己的索引管理系統(tǒng)罕袋,因為日志管理的本質(zhì)意味著將有頻繁的更新和映射關(guān)系變更改淑。這個索引管理系統(tǒng)的功能就是管理ES集群的索引。當索引需要根據(jù)現(xiàn)有配置策略被創(chuàng)建或關(guān)閉時炫贤,它會做檢查溅固。索引管理有很多策略。例如兰珍,當索引大小增長到特定值或者存在時間超過某個時間值侍郭,索引管理系統(tǒng)將關(guān)閉舊的,創(chuàng)建新的。
本文由日志幫(公眾號id:rizhibang)翻譯整理亮元。
當索引管理系統(tǒng)發(fā)送一個索引請求給節(jié)點處理時猛计,節(jié)點更新它自己的映射關(guān)系表并發(fā)給主節(jié)點。主節(jié)點會發(fā)送給那個節(jié)點一共更舊版本的映射關(guān)系表爆捞。如果有沖突奉瘤,并不是壞事(也就是說集群實際上有正確的映射關(guān)系表),我們只需要從這個節(jié)點向主節(jié)點發(fā)送一個更新煮甥。為了索引請求更高效盗温,我們在數(shù)據(jù)節(jié)點上設(shè)置了這個屬性。
indices.cluster.send_refresh_mapping:false
而反過來成肘,發(fā)送更新的映射關(guān)系表更重要卖局,因為某些原因,主節(jié)點上的映射關(guān)系表與實際節(jié)點上的沖突双霍。這種情況砚偶,更新映射關(guān)系表將會在主節(jié)點上記錄一個警告。
技巧7: 教你使用ElasticSearch分配相關(guān)屬性
分片(Shard)分配是分配分片給節(jié)點的處理過程洒闸。這可能發(fā)生在初始恢復(fù)染坯、副本分配或再平衡過程中。也可能發(fā)生在添加或刪除節(jié)點時丘逸。
cluster.routing.allocation.cluster_concurrent_rebalance屬性指定用于并發(fā)再平衡的分片數(shù)单鹿。此屬性的設(shè)置要取決于硬盤條件,如CPU數(shù)量鸣个,IO性能等羞反。如果該屬性設(shè)置不當,將影響ElasticSearch索引性能囤萤。
cluster.routing.allocation.cluster_concurrent_rebalance:2
該值默認為2昼窗,意思是任何時間點,只能有2個分片被移動涛舍。該值設(shè)置低一些澄惊,能降低分片再平衡,從而避免影響索引富雅。
另一個分片分配屬性是cluster.routing.allocation.disk.threshold_enabled掸驱。如果該屬性設(shè)置為true,在給節(jié)點分配分片時將考慮磁盤空間没佑。
當設(shè)置為true時毕贼,分片分配會考慮兩種情況:低位值、高位值蛤奢。
低位值對應(yīng)的磁盤使用率鬼癣, 達到后ES不再分配新分片陶贼。在下面的例子中,磁盤使用率97%時待秃,ES將停止分配分片
高位值對應(yīng)的磁盤使用率拜秧,達到后分片開始移出節(jié)點(下面示例中為99%)
cluster.routing.allocation.disk.threshold_enabled:true
cluster.routing.allocation.disk.watermark.low:.97
cluster.routing.allocation.disk.watermark.high:.99
技巧8:設(shè)置恢復(fù)相關(guān)屬性可以縮短重啟時間
ES包含幾個恢復(fù)相關(guān)的屬性項,使用它們可以改進ElasticSearch集群的恢復(fù)和重啟時間章郁。我們下面將展示幾個簡單的示例枉氮。對你來說,最佳的值取決于正在使用的硬件條件暖庄,我們能給的建議就是測試聊替、測試,還是測試培廓。
這個屬性定義的是佃牛,在任何時間,一個節(jié)點可以有多少分片被用于執(zhí)行恢復(fù)医舆。回收分片是一個IO密集型操作象缀,所以需要謹慎設(shè)置該屬性值蔬将。
cluster.routing.allocation.node_initial_primaries_recoveries:18
這個屬性控制的是單個節(jié)點上同時初始化的主要分片(primaryshards)數(shù)量。從節(jié)點傳輸?shù)綄Φ裙?jié)點的回收分片的平行流數(shù)量是由indices.recovery.concurrent_streams屬性控制央星。下面的值是給亞馬遜云的實例設(shè)置的霞怀,如果你是使用了自己的硬件,這個值可能需要設(shè)置更高莉给。max_bytes_per_sec屬性用于設(shè)置每秒傳輸多少字節(jié)毙石,這個屬性也是需要根據(jù)硬件條件來配置的。
indices.recovery.concurrent_streams:4
indices.recovery.max_bytes_per_sec:40mb
所有上述屬性颓遏,需要在重啟集群后生效徐矩。
技巧9:Threadpool屬性防止數(shù)據(jù)丟失
ES節(jié)點有幾個threadpools屬性,用于改進節(jié)點內(nèi)管理的線程數(shù)量叁幢。在Loggly滤灯,我們廣泛使用塊請求(bulkrequest),我們發(fā)現(xiàn)使用threadpool.bulk.queue_size屬性給批量線程池設(shè)置正確的數(shù)值至關(guān)重要曼玩,能避免數(shù)據(jù)丟失或者批量重試鳞骤。
threadpool.bulk.queue_size:3000
這個屬性值是關(guān)于塊請求的。它指定了在沒有更多線程來處理批量請求時黍判,ES節(jié)點隊列中等待處理的請求數(shù)豫尽。根據(jù)你的塊請求負載情況設(shè)置該值。如果你的塊請求數(shù)量比這個值高顷帖,你將收到像下方示例中的一個RemoteTransportException異常美旧。
注意渤滞,在ES中,塊請求隊列中陈症,一個分片對應(yīng)一個的項蔼水,所以如果你想發(fā)送的塊請求數(shù)包含很多給分片的數(shù)據(jù)項,那么這個屬性的數(shù)值需要設(shè)置為比你要發(fā)送的批量請求數(shù)更高的數(shù)值录肯。例如趴腋,單個塊請求中包含了10個分片的數(shù)據(jù)項,那即使你只發(fā)送一個塊請求论咏,也必須至少將隊列大小設(shè)置為10优炬。這個值設(shè)置過大,會消耗你的JVM堆厅贪,但卻可以讓ES充分發(fā)揮隊列功效蠢护,解放你的客戶端。
你要么把這個值設(shè)置高一些养涮,要么在客戶端妥善處理好RemoteTransportException異常葵硕。如果沒有妥善處理異常,你將丟失數(shù)據(jù)贯吓。下面我們將通過發(fā)送超過10個塊請求(隊列值設(shè)置為10)的方式模擬展示異常懈凹。
RemoteTransportException[[<Bantam>][inet[/192.168.76.1:9300]][bulk/shard]];nested: EsRejectedExecutionException[rejected execution (queue capacity 10) on org.elasticsearch.action.support.replication.TransportShardReplicationOperationAction1@13fe9be];
總結(jié):ES的配置屬性對它的靈活伸縮性至關(guān)重要
ElasticSearch配置項對其有效性越深入,Loggly的收益也就越大悄谐,因為在我們的使用案例中介评,已經(jīng)將ES的設(shè)計參數(shù)用到了極致(有時更甚爬舰,后續(xù)文章我們將繼續(xù)分享)们陆。如果在使用默認配置的情況下,已經(jīng)能滿足你應(yīng)用現(xiàn)階段需要情屹,那么請放心坪仇,隨著應(yīng)用增長,你還有很大的優(yōu)化空間垃你。
原文地址:https://www.loggly.com/blog/nine-tips-configuring-elasticsearch-for-high-performance/
譯文轉(zhuǎn)自日志幫(微信公眾號id:rizhibang)