(點(diǎn)擊底部“閱讀原文”獲取許鵬演講完整PPT) 講師介紹 許鵬,攜程機(jī)票大數(shù)據(jù)基礎(chǔ)平臺(tái)Leader,負(fù)責(zé)平臺(tái)的構(gòu)建和運(yùn)維。深度掌握各種大數(shù)據(jù)開源產(chǎn)品,如Spark、Presto及Elasticsearch。著有《Apache Spark源碼剖析》一書。 今天跟大家分享的是攜程機(jī)票ElasticSearch集群的規(guī)劃和具體設(shè)置,內(nèi)容相對(duì)細(xì)致,同時(shí)也會(huì)涉及到集群的監(jiān)控分享。 為什么采用ES作為搜索引擎呢?在做任何事情的時(shí)候,不要一上來(lái)就急著了解怎么做這件事情,而是去想想這件事情為什么值得去做。 這個(gè)是比較通用的數(shù)據(jù)的流程,一般會(huì)通過(guò)Kafka分離產(chǎn)生數(shù)據(jù)的應(yīng)用程序和后面的平臺(tái),通過(guò)ETL落到不同的地方,按照優(yōu)先級(jí)和冷熱程度采取不同的存儲(chǔ)方式。一般來(lái)說(shuō),冷數(shù)據(jù)存放到HDFS,如果溫?cái)?shù)據(jù)、或者熱數(shù)據(jù)會(huì)采用Database以及Cache,目前分布式Cache還沒有明顯的強(qiáng)者出現(xiàn),這將會(huì)成為未來(lái)的一個(gè)競(jìng)爭(zhēng)點(diǎn)。 一旦數(shù)據(jù)落地,我們會(huì)做兩方面的應(yīng)用,第一個(gè)方面的應(yīng)用是傳統(tǒng)BI,比如會(huì)產(chǎn)生各種各樣的報(bào)表,報(bào)表的受眾是更高的決策層和管理層,他們看了之后,會(huì)有相應(yīng)的業(yè)務(wù)調(diào)整和更高層面的規(guī)劃或轉(zhuǎn)變。這個(gè)使用路徑比較傳統(tǒng)的,在數(shù)據(jù)倉(cāng)庫(kù)時(shí)代就已經(jīng)存在了?,F(xiàn)在有一種新興的場(chǎng)景就是利用大數(shù)據(jù)進(jìn)行快速?zèng)Q策,數(shù)據(jù)不是喂給人的,數(shù)據(jù)分析結(jié)果由程序來(lái)消費(fèi),其實(shí)是再次的反饋到數(shù)據(jù)源頭即應(yīng)用程序中,讓他們基于快速分析后的結(jié)果,調(diào)整已有策略,這樣就形成了一個(gè)數(shù)據(jù)使用的循環(huán)。 這樣我們從它的輸入到輸出會(huì)形成一種閉環(huán),而且這個(gè)閉環(huán)全部是機(jī)器參與的,這也是為什么去研究這種大規(guī)模的,或者快速?zèng)Q策的原因所在。如果數(shù)據(jù)最終還會(huì)給人本身來(lái)看的話,就沒有必要更新那么快,因?yàn)橐幻腌娝⑿乱淮位蛘?0秒鐘刷新一次對(duì)人是沒有意義的,因?yàn)槲覀兡X子不可能一直轉(zhuǎn)那么快,基于數(shù)據(jù)一直的做調(diào)整也是不現(xiàn)實(shí)的,但是對(duì)機(jī)器來(lái)講,就完全沒有問(wèn)題。 這是大體上的一個(gè)規(guī)劃,當(dāng)然,從左到右有一個(gè)結(jié)點(diǎn),這個(gè)節(jié)點(diǎn)本身不存在數(shù)據(jù)的,你可以簡(jiǎn)單地認(rèn)為它只是負(fù)責(zé)查詢的入口。第二層用來(lái)承載具體的數(shù)據(jù),然后這些數(shù)據(jù)的搜索本身會(huì)發(fā)生在這里。最后一層是MASTER的節(jié)點(diǎn),主要是管理元數(shù)據(jù),元數(shù)據(jù)包含有集群中的機(jī)器信息,以及寫入到我的數(shù)據(jù)節(jié)點(diǎn)上的這些索引設(shè)置信息、索引Schema都是由Master管理。 我這里是以ES5.X版本為依據(jù)的,大家看ES文檔,我這上面有一個(gè)節(jié)點(diǎn)沒有寫,就是沒有寫它的Ingest節(jié)點(diǎn),它可以在數(shù)據(jù)真正寫入到Index之前做一些轉(zhuǎn)換。 下面要講的設(shè)置就非常具體了,從三個(gè)層面來(lái)講:第一個(gè)有關(guān)Linux的系統(tǒng)配置,第二是集群層面的參數(shù)設(shè)置,最后會(huì)涉及到存儲(chǔ)到集群上的索引設(shè)置。 1、OS參數(shù)設(shè)置 像OS這個(gè)參數(shù)設(shè)置,首先提到的是內(nèi)存相關(guān)的參數(shù),由于ES采用Mapping機(jī)制,將文件映射到內(nèi)存,在系統(tǒng)級(jí)別有一些相關(guān)的參數(shù)要設(shè)置。另一個(gè)就是文件數(shù),假設(shè)我們所有都設(shè)置到最大65535。 這個(gè)設(shè)置之后還需要在下面加入加入login這個(gè)文件,這里講得非常具體,可以說(shuō)是一個(gè)教程。 這里我只是做了一個(gè)示例,在Ext4文件系統(tǒng)中,每一次訪問(wèn)一個(gè)文件或者目錄時(shí),其實(shí)OS級(jí)別會(huì)記錄訪問(wèn)時(shí)間,如果只是在海量文件的情況,上述的記錄信息就會(huì)對(duì)IO有影響。有一篇文章提到,關(guān)閉文件訪問(wèn)時(shí)間信息之后,系統(tǒng)IO性能可以提升20%—30%。 我們知道Linux里面文件信息,不是直接改一次之后就寫入到磁盤,它會(huì)先有一個(gè)文件的緩存,文件的緩存什么情況下會(huì)被寫入到disk里面?有兩個(gè)相應(yīng)的系統(tǒng)參數(shù)可以設(shè)置的,一個(gè)是vm.dirty_background_ratio,一個(gè)是vm.dirty_ratio,一旦緩存占據(jù)內(nèi)存超過(guò)百分比(默認(rèn)值是20%)之后,內(nèi)核就停止其它方面的操作,而只做文件的緩存吐到disk的操作,這時(shí)效果有點(diǎn)像Java里進(jìn)行垃圾回收一樣,對(duì)外界停止響應(yīng)。 vm.dirty_ratio就是當(dāng)它緩存量達(dá)到20%時(shí),它就其它的什么都不干了,只做數(shù)據(jù)同步到disk一件。 內(nèi)存不夠時(shí),會(huì)使用swap空間, 內(nèi)存很大的話,可以不用創(chuàng)建swap空間。默認(rèn)值是60,但是我們把它設(shè)置為零的話,是跟swap off效果一樣。但為了避免內(nèi)核出現(xiàn)OOM, 只是將其設(shè)置為1。 2、ElasticSearch參數(shù)設(shè)置 剛才兩個(gè)講的都是系統(tǒng)級(jí)別的設(shè)置,一個(gè)是內(nèi)存,另一個(gè)是系統(tǒng)級(jí)別的IO,下面講的是針對(duì)ES—JVM的設(shè)置。 這里建議,不管物理內(nèi)存有多大,分配給Elasticsearch的只設(shè)成32G,同時(shí)后面如果出現(xiàn)OOM,進(jìn)程直接退出。 為什么說(shuō)要把它改成這個(gè)呢?因?yàn)槲覀冊(cè)谑褂靡粋€(gè)集群時(shí)看到,有時(shí)因?yàn)榫酆喜僮鞯脑?,?huì)導(dǎo)致某一臺(tái)機(jī)器上的JAVA進(jìn)程出現(xiàn)OOM,但是這個(gè)JVM進(jìn)程還在,并沒有退出,退出的話可以通過(guò)monit捕捉到,也可以進(jìn)行重啟。如果沒有退出,而是一直掛在那的話,就不能提供正常的服務(wù)。 此外加上這個(gè)參數(shù)的話,需要升級(jí)一下JDK版本,JDK要求1.8.0_92, 從這個(gè)版本開始支持ExitOnOutOfMemoryError參數(shù)。 另外一種辦法就是如果我們內(nèi)存不能升級(jí)JDK、存在種種現(xiàn)實(shí)約束的話,可以在這個(gè)時(shí)候用另一種方式來(lái)實(shí)現(xiàn),在JVM啟動(dòng)參數(shù)中加入 -XX:OnOutOfMemoryError='kill -9 %p'。 這里就是講輸入到ElasticSearch里面每個(gè)集群的一些參數(shù),一些相對(duì)比較主要的一些參數(shù)。這里的參數(shù)配了一幅圖,這幅圖最想表明的意思是說(shuō),我的參數(shù)的配置要使得我從整個(gè)集群的角度上來(lái)看,它每一臺(tái)機(jī)器上的shard數(shù)目基本是相當(dāng)?shù)摹?/p> 這里有一點(diǎn),參數(shù)設(shè)置能保證shard數(shù)目是基本相當(dāng)?shù)?,但并不是保證每一個(gè)shard的大小相等,這兩者還是有差異的。決定每個(gè)集群上shard相等的參數(shù)是由這個(gè)balance決定,它默認(rèn)一個(gè)是0.5,把它往下調(diào)的話,就不可以傾斜;往上調(diào)的話對(duì)傾斜的容忍度相對(duì)比較高。 ElasticSearch是一個(gè)高可靠的系統(tǒng),集群的一個(gè)節(jié)點(diǎn)掛掉了,另一個(gè)節(jié)點(diǎn)是可以繼續(xù)的。掛掉的節(jié)點(diǎn)是進(jìn)行恢復(fù),為了避免恢復(fù)工作對(duì)集群造成太多影響,主要是避免大的I/O消耗,需要進(jìn)行參數(shù)設(shè)置。比如集群中同時(shí)在進(jìn)行恢復(fù)的索引可以是多少個(gè),還有就是一個(gè)node上能允許shard在做恢復(fù)。 這兩個(gè)參數(shù)是cluster_concurrent_rebalance和node_concurrent_recoveries。 如果要縮容、對(duì)某一臺(tái)機(jī)器進(jìn)行維護(hù)、將其從集群中拉出來(lái)該怎么辦?這個(gè)時(shí)候可以設(shè)定exclude名單,名單可以通過(guò)ip地址或主機(jī)名來(lái)指定。一旦設(shè)置的exlude名單,該名單上節(jié)點(diǎn)中的索引數(shù)據(jù)被拉到別的機(jī)器上面,數(shù)據(jù)被拉完之后,就可以被這個(gè)集群拉出去的機(jī)器進(jìn)行維護(hù),避免維護(hù)帶來(lái)的數(shù)據(jù)丟失。 3、索引參數(shù)設(shè)置 這是具體到一個(gè)索引參數(shù)的設(shè)置。在講具體參數(shù)之前,我們可以先講一下ElasticSearch索引參數(shù)的設(shè)置、輸入以及中間發(fā)生的過(guò)程。當(dāng)真正的數(shù)據(jù)請(qǐng)求到達(dá)ElasticSearch節(jié)點(diǎn)之后,它一方面會(huì)寫入到內(nèi)存中,另外一部分會(huì)寫入到TransactionLog。 寫入到內(nèi)存并不意味著可以被搜索,要通過(guò)Refresh操作,才可以被搜索到。Refresh之后,數(shù)據(jù)可以被搜索到,此刻數(shù)據(jù)還在內(nèi)存中,如果很不巧的話,在這個(gè)時(shí)候斷電,或者出現(xiàn)其它故障不可用了,那么等到這臺(tái)機(jī)器再恢復(fù)時(shí),我剛才寫的內(nèi)容就丟失掉了, 因?yàn)椴]有被持久化到磁盤。 為了持久化這個(gè)內(nèi)容,需要進(jìn)行一次FLUSH操作, flush的內(nèi)容會(huì)被寫到一個(gè)segment中。 可想而知,隨著時(shí)間的推移,系統(tǒng)會(huì)產(chǎn)生大量的segments,這些segment需要把它合并成一個(gè)大的。不合并成一個(gè)大的會(huì)怎樣呢?不合并成一個(gè)大的,就是說(shuō)每一個(gè)segment都會(huì)吃掉一些文件句柄,文件句柄數(shù)是有限的。另一個(gè)帶來(lái)的就是查詢性能下降,因?yàn)椴樵兊臅r(shí)候,要對(duì)所有segments進(jìn)行訪問(wèn),效率就比較低了。 有了剛才講的三步之后,再來(lái)看下面的參數(shù)就比較容易好理解了。 Refresh_interval 過(guò)多久可以讓你查詢到,時(shí)間越短就可以被越快地檢索到,但是意味著我相應(yīng)的I/O也上去了,在有大批量數(shù)據(jù)導(dǎo)入時(shí),這個(gè)數(shù)值會(huì)適當(dāng)?shù)恼{(diào)大。 在我們目前部署的集群中,高峰時(shí)候每秒寫入量,有十幾萬(wàn)。 為了應(yīng)對(duì)這種場(chǎng)景,將refresh_interval設(shè)置為100多秒或者90秒以上。 Number_of_shards索引分片的數(shù)目,這個(gè)數(shù)目可以設(shè)置得大一些,還有每一個(gè)分片的副本,在大批量導(dǎo)入時(shí),由于副本數(shù)目是可以動(dòng)態(tài)調(diào)整的,副本數(shù)也可以先設(shè)置為零,等數(shù)據(jù)全部導(dǎo)入后,再設(shè)置為非0值。 副本數(shù)可以動(dòng)態(tài)調(diào)整,但是分片數(shù)目是無(wú)法動(dòng)態(tài)調(diào)整的,也就是說(shuō),除非重建另外一個(gè)索引,不然原先設(shè)置的是啥樣就只能啥樣。 這個(gè)FLUSH也可以調(diào)大,需要的時(shí)候可以設(shè)置得大一些。 下面就是做segments合并的線程數(shù),如果是spin disk的話,就使用默認(rèn)值1,如果是SSD的話,可以把它調(diào)大一些。 講到SSD代碼的話, 為了進(jìn)一步優(yōu)化性能,可以將系統(tǒng)的i/o scheduler設(shè)置為noop 。 這里是針對(duì)每個(gè)Index的Schema設(shè)置。假設(shè)事先并不能確定索引,大部分我們可以采用動(dòng)態(tài)的template。 上述的動(dòng)態(tài)模板表示的是, 如果字符串小于10915, 就采用keyword來(lái)存儲(chǔ)。 下面一欄對(duì)應(yīng)特別特別大的字段,如果我們只是存儲(chǔ)這個(gè)字段的內(nèi)容,不對(duì)這個(gè)字段做搜索也不做任何分詞,可以將類型設(shè)置為object,enabled設(shè)置為false,即便包含嵌套信息也不會(huì)被解析。 前面講的是一些設(shè)置方面的內(nèi)容,下面講如何放開這個(gè)ElasticSearch的使用。想法跟大的原則一樣,盡量避免開發(fā)人員直接調(diào)用Elasticsearch的API來(lái)操作ElasticSearch,因?yàn)檫@樣產(chǎn)生的問(wèn)題不容易控制,畢竟每個(gè)人對(duì)ElasticSearch的熟悉程度不一樣。 建議先統(tǒng)一入口,在包裹之后的API對(duì)ES進(jìn)行操作。 利用BigQuery API對(duì)寫入到Elasticserch的數(shù)據(jù)進(jìn)行查詢,開發(fā)人員直接寫SQL語(yǔ)句。如果SQL語(yǔ)句本身有問(wèn)題的話,在Elasticsearch-SQL一側(cè)就可以將其擋掉。 1、監(jiān)控內(nèi)容 維護(hù)一個(gè)集群的話,肯定離不開對(duì)集群的監(jiān)控。監(jiān)控的內(nèi)容,大體上來(lái)說(shuō)分成OS層面還有ES索引層面的內(nèi)容。 OS層面就是內(nèi)存、CPU,索引層面就是分片還有它的Field Data以及其它占用的內(nèi)存數(shù)。索引的話就是每個(gè)索引數(shù)設(shè)置得合理,這些分片數(shù)設(shè)置得合理與否,分片是否在每個(gè)集群里比較均勻地分布;針對(duì)每一個(gè)索引的話,它的查詢量是不是過(guò)大,如果過(guò)大的話,那么整個(gè)集群也會(huì)有問(wèn)題。ElasticSearch并不是一個(gè)能夠很好地支持高并發(fā)查詢的系統(tǒng)。每一個(gè)索引中包含的字段數(shù)不能過(guò)多。 2、監(jiān)控工具 監(jiān)控工具是eyeones,是我們自己寫的一個(gè)工具, Elasticsearch 5.x中提供的x-pack基本版與elasticsearch 1.x中提供的marvel相比,精簡(jiǎn)掉了好多有用的信息,這是我們?yōu)槭裁醋约簩懸粋€(gè)監(jiān)控面板的原因。 從這里你可以看到這是針對(duì)節(jié)點(diǎn)的負(fù)載情況,然后它的內(nèi)存使用情況,還有就是我這上面所承載的索引數(shù)目、每個(gè)節(jié)點(diǎn)上的查詢數(shù)、分片落了多少。 這是一個(gè)針對(duì)索引內(nèi)容更加明細(xì)的量化指標(biāo),上面是索引的情況,點(diǎn)擊任意一個(gè)具體的索引,都會(huì)有相關(guān)內(nèi)容。 這個(gè)的話我們是把它放到Github,如果大家有興趣可以在上面繼續(xù)改造。 |
|
來(lái)自: sjw0923cn > 《計(jì)算機(jī)辦公》