聲明:
本文轉(zhuǎn)自我的個(gè)人博客觉义,有興趣的可以查看原文。
轉(zhuǎn)發(fā)請(qǐng)注明來(lái)源浴井。
前段時(shí)間和運(yùn)維小伙伴一起完善了公司 Elasticsearch 集群的監(jiān)控和報(bào)警晒骇,整理成此文,涉及到公司架構(gòu)和系統(tǒng)信息的不便透露的磺浙,都隱去了洪囤。
系統(tǒng)架構(gòu)
談監(jiān)控之前,先看看我們的系統(tǒng)架構(gòu)撕氧,下圖是個(gè)簡(jiǎn)化的搜索架構(gòu):
![搜索系統(tǒng)架構(gòu)](http://7sbmb0.com1.z0.glb.clouddn.com/es-architecture.png)
系統(tǒng)分兩部分:
- 藍(lán)色部分箍鼓,表示用戶查詢部分,客戶端請(qǐng)求到達(dá)Tengine呵曹,Tengine將請(qǐng)求轉(zhuǎn)發(fā)到AS(Advanced Search)款咖,AS將請(qǐng)求轉(zhuǎn)發(fā)到Elasticsearch,Elasticsearch查詢奄喂,然后將結(jié)果原路返回铐殃。其中,AS是我們自主研發(fā)的跨新,用于Query驗(yàn)證富腊、改寫(xiě)、記日志域帐、相關(guān)性計(jì)算等等赘被。在這里,AS和ES都是一個(gè)集群肖揣。
- 綠色部分民假,表示實(shí)時(shí)同步部分,系統(tǒng)日志龙优、DB數(shù)據(jù)等通過(guò)消息隊(duì)列到到我們的Sync程序羊异,Sync將數(shù)據(jù)實(shí)時(shí)寫(xiě)入到ES集群。
上圖覆蓋了最重要的兩個(gè)部分——實(shí)時(shí)索引與查詢彤断,全量索引僅需周期性進(jìn)行一次野舶,并未體現(xiàn)在此圖中。對(duì)搜索集群添加監(jiān)控宰衙,主要是針對(duì)圖中各組件添加監(jiān)控平道。
具體監(jiān)控
基礎(chǔ)監(jiān)控
基礎(chǔ)監(jiān)控主要是一些常用的運(yùn)維監(jiān)控,主要包括:
- CPU 使用率
- IO
- 內(nèi)存
- load
- 磁盤空間供炼、INode
- 重傳率
- fd
- ntp
- coredump
- JVM
- ...
這部分一屋,運(yùn)維都有很豐富的經(jīng)驗(yàn)句伶,不用操心。
網(wǎng)關(guān)監(jiān)控
網(wǎng)關(guān)監(jiān)控陆淀,主要關(guān)注兩個(gè)指標(biāo),RT和狀態(tài)碼先嬉,當(dāng)RT > 1s 或者出現(xiàn)5XX的時(shí)候轧苫,進(jìn)行報(bào)警。
AS監(jiān)控
- 進(jìn)程監(jiān)控疫蔓,當(dāng)進(jìn)程數(shù)發(fā)生變化時(shí)含懊,報(bào)警;
- 日志監(jiān)控衅胀,當(dāng)日志出現(xiàn)ERROR時(shí)岔乔,報(bào)警。
Elasticsearch 進(jìn)程監(jiān)控
- 進(jìn)程監(jiān)控滚躯,進(jìn)程數(shù)發(fā)生變化時(shí)雏门,報(bào)警。
- ES 產(chǎn)生ERROR日志時(shí)掸掏,報(bào)警茁影。
Elasticsearch指標(biāo)監(jiān)控
Elasticsearch 提供了豐富的API接口以便于采集集群、node丧凤、index等狀態(tài)指標(biāo)募闲,可以根據(jù)這些指標(biāo)做監(jiān)控和報(bào)警。我們主要在集群級(jí)別愿待、node 級(jí)別浩螺、index 級(jí)別三個(gè)層次進(jìn)行采集和監(jiān)控報(bào)警。
下面是一些主要關(guān)注的指標(biāo)仍侥。
一要出、集群級(jí)別監(jiān)控,采用GET _cluster/health
农渊,返回?cái)?shù)據(jù)如下:
{
"cluster_name": "cluster_name_1",
"status": "green",
"timed_out": false,
"number_of_nodes": 6,
"number_of_data_nodes": 4,
"active_primary_shards": 38,
"active_shards": 68,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
對(duì)于我們來(lái)說(shuō)厨幻,一般重點(diǎn)關(guān)注集群狀態(tài) status以及其中的node數(shù)量。當(dāng)集群狀態(tài)變?yōu)閥ellow或red時(shí)報(bào)警腿时。
另外况脆,Elasticsearch 提供API對(duì)集群進(jìn)行修改,而且批糟,Elasticsearch 沒(méi)有提供有效的權(quán)限控制格了,從而,也給我們帶來(lái)了風(fēng)險(xiǎn)徽鼎,所以盛末,我們還加了一層監(jiān)控弹惦,當(dāng)集群配置發(fā)生變化時(shí),報(bào)警悄但。
二棠隐、node級(jí)別的監(jiān)控,采用GET _nodes/stats
接口取回node相關(guān)監(jiān)控?cái)?shù)據(jù)檐嚣。
![node_stats](http://7sbmb0.com1.z0.glb.clouddn.com/es_node.jpg)
大部分?jǐn)?shù)據(jù)在基礎(chǔ)監(jiān)控里已經(jīng)做了助泽,所以,這里主要關(guān)注紅框部分——indices嚎京、thread_pool和fielddata_breaker三部分嗡贺。
indices部分如下:
"indices": {
"docs": {
"count": 3344,
"deleted": 983
},
"store": {
"size_in_bytes": 6529920,
"throttle_time_in_millis": 2263
},
"indexing": {
"index_total": 114516,
"index_time_in_millis": 66226,
"index_current": 969,
"delete_total": 802,
"delete_time_in_millis": 93,
"delete_current": 0
},
"get": {
"total": 449,
"time_in_millis": 13,
"exists_total": 571,
"exists_time_in_millis": 1847,
"missing_total": 878,
"missing_time_in_millis": 56,
"current": 0
},
"search": {
"open_contexts": 0,
"query_total": 3419,
"query_time_in_millis": 262,
"query_current": 0,
"fetch_total": 319,
"fetch_time_in_millis": 189,
"fetch_current": 0
},
"merges": {
"current": 1,
"current_docs": 175,
"current_size_in_bytes": 374,
"total": 557,
"total_time_in_millis": 77614,
"total_docs": 3878,
"total_size_in_bytes": 9545
},
"refresh": {
"total": 4036,
"total_time_in_millis": 3788
},
"flush": {
"total": 07,
"total_time_in_millis": 03
},
"warmer": {
"current": 0,
"total": 45,
"total_time_in_millis": 233
},
"filter_cache": {
"memory_size_in_bytes": 124,
"evictions": 778
},
"id_cache": {
"memory_size_in_bytes": 0
},
"fielddata": {
"memory_size_in_bytes": 1348,
"evictions": 0
},
"percolate": {
"total": 0,
"time_in_millis": 0,
"current": 0,
"memory_size_in_bytes": -1,
"memory_size": "-1b",
"queries": 0
},
"completion": {
"size_in_bytes": 0
},
"segments": {
"count": 350,
"memory_in_bytes": 392,
"index_writer_memory_in_bytes": 961,
"version_map_memory_in_bytes": 8
},
"translog": {
"operations": 12025,
"size_in_bytes": 0
},
"suggest": {
"total": 0,
"time_in_millis": 0,
"current": 0
}
}
- doc 部分顯示node中的所有documents數(shù)量,以及已經(jīng)被標(biāo)記刪除的鞍帝。當(dāng)每分鐘被標(biāo)記刪除的數(shù)量突然增大時(shí)诫睬,需要關(guān)注下。
- store顯示物理存儲(chǔ)信息帕涌。
- indexing 顯示了被索引的docs數(shù)量摄凡,是一個(gè)累計(jì)遞增值,只要內(nèi)部進(jìn)行index操作就會(huì)增加蚓曼,所以架谎,index、create辟躏、update都會(huì)增加谷扣。可以利用這個(gè)累計(jì)值捎琐,監(jiān)控每分鐘的變化会涎,從而做出預(yù)警。
- get 顯示的是調(diào)用 GET | HEAD 方法的次數(shù)瑞凑,也是累計(jì)值末秃。
- search 描述search 相關(guān)監(jiān)控?cái)?shù)據(jù),
query_time_in_millis/query_total
可以用來(lái)粗略估計(jì)搜索引擎的查詢效率籽御。fetch 相關(guān)統(tǒng)計(jì)描述搜索過(guò)程(query-then-fetch)中fetch 操作的統(tǒng)計(jì)數(shù)據(jù)练慕。 - merge 包含Lucene 段合并的一些信息,對(duì)于實(shí)時(shí)寫(xiě)數(shù)據(jù)量大的ES集群技掏,merge相關(guān)指標(biāo)十分重要铃将,因?yàn)閙erge操作會(huì)消耗大量的CPU和IO秧骑。
- fielddata 描述fielddata占的內(nèi)存以及被淘汰的情況耗帕,需要關(guān)注
fielddata.eviction
,這個(gè)值應(yīng)該很小刨沦。另外鸠真,fielddata很耗內(nèi)存悯仙,如果fielddata統(tǒng)計(jì)占內(nèi)存很多龄毡,也要考慮下這樣使用的業(yè)務(wù)場(chǎng)景是否合理。 - segment 統(tǒng)計(jì)Lucene 的segments相關(guān)信息锡垄,這個(gè)值應(yīng)該不會(huì)太大沦零。
Elasticsearch 自身維護(hù)它的線程池,一般來(lái)講货岭,我們不需要配置路操,默認(rèn)的即可。在API返回的結(jié)果中茴她,有很多種線程池,格式都是統(tǒng)一的程奠,如下:
"index": {
"threads": 24,
"queue": 0,
"active": 0,
"rejected": 0,
"largest": 24,
"completed": 676231817
}
上面的信息展示了線程池里現(xiàn)場(chǎng)的數(shù)量丈牢,有多少現(xiàn)成正在work,有多少在隊(duì)列里瞄沙。如果隊(duì)列滿了己沛,新的請(qǐng)求將被rejected掉,顯示在rejected距境,這時(shí)候申尼,通常說(shuō)明我們的系統(tǒng)到了瓶頸了,因?yàn)榈婀穑覀兊南到y(tǒng)以最大的速度處理都處理不過(guò)來(lái)了师幕,所以,這個(gè)指標(biāo)要注意诬滩。
除了上面顯示的index 線程池霹粥,還有很多線程池,不過(guò)很多都可以忽略疼鸟,但有些重要的還是需要關(guān)注:
- index: 處理一般index請(qǐng)求的線程池后控。
- bulk:處理bulk indexing請(qǐng)求的線程池。
- get:處理get-by-ID請(qǐng)求的線程池空镜。
- search:處理所有search和query請(qǐng)求的線程池浩淘。
- merge:管理 Lucene merge的線程池。
最后吴攒,需要關(guān)注Circuit Breaker的相關(guān)指標(biāo):
"fielddata_breaker": {
"maximum_size_in_bytes": 11699,
"maximum_size": "0.7gb",
"estimated_size_in_bytes": 568,
"estimated_size": "1.2gb",
"overhead": 1.03,
"tripped": 0
}
簡(jiǎn)單來(lái)說(shuō)张抄,fielddata的大小只有在加載完了之后才會(huì)知道,如果fielddata的大小比分配內(nèi)存還大洼怔,那就會(huì)導(dǎo)致OOM欣鳖,于是,Elasticsearch 引入了斷路器茴厉,用于預(yù)先估算內(nèi)存夠不夠泽台,如果不夠什荣,斷路器就會(huì)被觸發(fā)(tripped)并返回異常,而不至于導(dǎo)致OOM怀酷。
所以稻爬,這個(gè)指標(biāo)里,最重要的就是 tripped
了蜕依,如果這個(gè)值很大或者說(shuō)一直在增長(zhǎng)桅锄,那么,就說(shuō)明你的查詢需要優(yōu)化或者說(shuō)需要更多內(nèi)存了样眠。
三友瘤、index 級(jí)別監(jiān)控
index 級(jí)別的監(jiān)控可以以index為單位進(jìn)行統(tǒng)計(jì),如某個(gè)index有多少search請(qǐng)求檐束、search時(shí)耗費(fèi)了多少時(shí)間等辫秧,可以用于發(fā)現(xiàn)熱點(diǎn)索引或比較慢的索引。
然而被丧,在實(shí)際應(yīng)用中盟戏,index級(jí)別的監(jiān)控并不是很有用,一般來(lái)說(shuō)甥桂,瓶頸都出現(xiàn)在node級(jí)別柿究,不會(huì)到index級(jí)別;而且黄选,index級(jí)別的數(shù)據(jù)采集自不同機(jī)器蝇摸,不同環(huán)境也會(huì)受影響。
查看index 級(jí)別的監(jiān)控命令是 GET index_name/_stats
办陷,如果index_name改成 _all
探入,則統(tǒng)計(jì)所有index的數(shù)據(jù)。
同步程序監(jiān)控
同步程序監(jiān)控主要包括三個(gè)方面:
- 基礎(chǔ)監(jiān)控懂诗。同步數(shù)據(jù)量大蜂嗽,同步程序單獨(dú)部署了一個(gè)集群,也需要相應(yīng)的基礎(chǔ)監(jiān)控殃恒。
- 同步程序進(jìn)程數(shù)監(jiān)控植旧。
- 同步程序日志監(jiān)控,如版本沖突等ERROR都能采集到离唐。
業(yè)務(wù)監(jiān)控
我們還做了業(yè)務(wù)層面的監(jiān)控病附,針對(duì)不同index進(jìn)行基礎(chǔ)埋點(diǎn),同時(shí)亥鬓,新上業(yè)務(wù)時(shí)完沪,也會(huì)添加使用的Query語(yǔ)句進(jìn)行埋點(diǎn),系統(tǒng)定時(shí)跑這些埋點(diǎn),當(dāng)出現(xiàn)異常時(shí)報(bào)警覆积。
總結(jié)
Elasticsearch 集群的監(jiān)控是在運(yùn)維同事的幫助下搭建的听皿,到目前為止,基本能滿足需求宽档,但因?yàn)樽陨硪郧皼](méi)有這方面經(jīng)驗(yàn)尉姨,所以,這方面也許做得還不夠吗冤,還望批評(píng)指正又厉。