關於作者:
李萌,他是資料領域的專家,是國內頂級的Elastic Stack實務專家,也是中國首批21位Elastic官方認證工程師之一。 他於 2012 年創立了 Elasticsearch,在 Elastic Stack 技術棧的開發、架構、運維、原始碼和演算法方面擁有豐富的實踐經驗。 他負責過多個 Elastic Stack 專案,包括大資料分析、機器學習、業務查詢加速、日誌分析和基本指標監控。 擁有超過10年的技術實踐經驗,擅長大資料、混合技術棧和系統架構。
序言
圖:Elasticsearch目前在db-engine中排名第8位
Elasticsearch博大精深,提供了非常豐富的應用場景功能,以及豐富的API命令操作,有些API非常好用,有些API使用起來很難防範。
以下圍繞某客戶在客戶端應用中誤用集群狀態命令展開,從問題定位到問題解決,記錄自己的流程和方法,以及一些經驗總結(注:具體客戶資訊不方便透露,以下部分**資訊僅為示意圖)。
一、案例介紹一、專案背景簡介
客戶使用ES解決日常資料查詢和儲存問題,並利用ES優異的水平擴充套件特性,滿足多種場景應用。
ES 集群版本屬於 56.已經超過Elastic官方支援的版本,集群中節點少於10個,節點硬體配置均衡一致,標準基於效能的硬體配置在合理範圍內,應用於業務系統提供查詢或更新等,並提供日常定期巡檢, 基本正常穩定,但一直專注於集群運維本身,很少深入應用端程式進行檢查分析,業務線太多,資金有限。
ES 集群配置不採用主節點與資料分離的設計,所有節點都具有相同的角色許可權。 ES集群中的資料量也在正常支援容量範圍內,集群索引中的分片數量在2W以上。
客戶端應用基於 Spring Data Elasticsearch 開發框架,該框架引用了 trasnport-client 直連模式,不使用任何代理載入產品。
客戶端應用部署多個例項,遞增2倍,需要在ES集群中做一些“大”的資料寫入和查詢,以及瞬時併發操作,不管怎麼操作,ES的併發性都不高,但是應用端程式就是執行速度不快,這是非常不合理和不合理的,常識告訴我這是不正常的。
圖:客戶公司應用專案架構示意圖,客戶端採用傳輸-客戶端直連方式。
二、問題現象及事故原因
只要客戶端應用開始執行,ES集群就會立刻變慢,但從ES集群的整體資源消耗來看,ES所在節點的CPU MEM硬碟IO並不高,其資料節點甚至很低,遠遠沒有達到節點的瓶頸。
仔細觀察發現,集群的主節點流量特別高,其他節點的資料流量傳輸到主節點,超出了主節點單節點網路IO的限制,明顯異常。 但是,在生產環境中進行故障排除並不容易。 後來,在本地開發環境進行模擬壓測後,最終確定問題是由客戶端的集群管理操作API引起的。
最終找到了集群狀態 api statistics 命令,客戶端應用在做實際業務之前,每次都會呼叫這個 api 命令來獲取集群的一些索引和對映資訊,因為客戶端是多執行緒的,部署了多個例項,只要併發數量高,所有流量都不可避免地會打到主節點, 導致整個集群的響應速度較慢。由於整個集群有近 2 個 W 分片,因此需要執行 state 命令收集集群中的所有索引分片,最後彙總到主節點,導致主節點的實際網路 I/O 超出限制。
圖:集群狀態 API 返回內容,索引越多,返回的內容越大。
二、調查過程與分析手段我們已經簡要地談到了問題現象和事故原因,現在我們將重點介紹問題排除過程以及所採用的工具和方法。
特別是由於遠端協同分析排查和客戶公司的行業特點,外部無法直接操作任何遠端節點,必須由客戶公司的運維人員間接指導操作和排查,過程略顯曲折。
1. 檢查伺服器端集群
首先是ES集群問題的調查,這是一種非常正常和直接的思維,調查是在問題的爆發點進行(PS:類似於警察先趕到案發現場取證)。 由於集群版本為 56.X,由於一些原因沒有開啟官方的xpack功能,所以沒有內建的Kibana監控視覺化報表,國內早期使用者大多都是在使用開源免費版搭建集群,客戶公司基於Zabbix搭建了集群節點的基礎指標監控,最後還有乙個,非常罕見。
1) Zabbix監控與分析
很快,基於Zabbix,對每個ES機器節點的指標進行監控分析,按照常規例程,對CPU、記憶體、磁碟IO等進行分析,一切正常,但不高。 這是非常令人困惑的,顯然集群響應速度很慢,客戶端應用開發者也如實響應,而且部署的例項很少,所以經過初步分析,並沒有明顯的問題所在。
然後,對節點網路IO進行分析,發現問題點,其中主節點流量特別高,超出了網絡卡的限制。 按照這個套路,我繼續檢視其他資料節點的網路IO,也比較高,然後觀察到資料節點的網路IO流量剛好等於Master節點的網路IO流量,終於找到了突破口。
需要注意的是,雖然Zabbix可以監控每個獨立節點的網路流量,但它無法看到節點之間以及應用客戶端和伺服器之間的網路流量,這是非常不友好的。
圖:Zabbix網路流量的圖,提供單個節點的快速檢視。
2) IFTOP監測與分析
在zabbix的幫助下,已經找到了突破口,下一步就是需要網路流量關聯圖。 這時,首先想到的就是對Elastic Stack Packetbeat網路IO流量報文的視覺化監控和監控,客戶公司當即討論是否可以安裝配置。 後來,客戶公司的運維工程師臨時安裝了Linux網路命令iftop,終於能夠分析出ES各節點網路中IO流量的流向,但觀察分析比較辛苦,無法繪製網路圖, 所以觀察仍然不夠全面。
iftop 只在單個節點上執行,所以你只能看到進出單個節點的網路流量,但這已經很好了,但需要更長的時間。
基於對網路IO流量進出的初步分析和觀察,迅速做出決策,先重啟已有的Master節點,讓ES集群重新選擇新的Master節點,但發現新選的Master節點的流量仍然很大。 然後,我也臨時申請了新增 2 個 ES 節點,以為可以分散客戶端訪問的壓力,但實際上並沒有從根本上調研。 這時判斷是,有些業務指標查詢導致流量比較大,恰好在主節點中進行了轉移和彙總,但是這裡沒有分析客戶端的流量,所以做了一些無用的緊急伺服器端調整,但也證明問題不在ES伺服器上。
圖:IFTOP網路流量示意圖,可以分析單個節點的流量進出,也不錯。
3) Packetbeat 監控分析
由於某些原因,Elastic Stack 監控分析產品沒有部署,尤其是 packetbeat 網路流量監控分析產品,官方預設提供的網路流量圖非常有用,可以更快速地定位流量方向,相比 ITTOP,更全面,可以概括為網路版的 IFTOP。 PacketBeat 內建了一些官方視覺化報表,如果覺得還不夠,可以根據 ES 提供的分析能力自行設計。
圖:PacketBeta網路IO流量監控分析圖表、輸入和輸出。
2. 客戶端故障排除
第二種是從客戶端應用進行檢查。 但事實上,當客戶公司的運維人員發現問題並第一時間聯絡我時,我的第乙個問題是客戶端應用在做什麼業務,業務型別是什麼。 運維人員也如實告知了正在做的業務型別和應用,其實我只能總結一下,並不知道詳細的業務運營流程和影響,對我來說,反正我知道有業務運營影響集群,還要繼續調查到底是怎麼影響的。 必須說明的是,這可能是國內IT運維行業的乙個通病,似乎運維屬於端支撐,本質應該更多地參與到業務系統的前沿,而其背後的運維問題應該從業務中去理解。
然後,通過ES伺服器端的排查,已經掌握了一些資訊,但是遠遠不夠定位問題,客戶端排查還有很長的路要走,必須找到問題。 ES集群中有很多慢響應,但是服務端只能發現問題,卻無法從根本上解決,所以通過在伺服器上執行執行緒池和任務命令,發現集群的管理執行緒池非常大,任務一直都滿載著, 這是不正常的,這更能確定客戶端的某些應用程式一定是惡意操作這些命令。
1) 執行緒池監控與分析
集群響應慢,集群執行緒池是必須考慮的乙個點,會看到累計任務量,開啟指令觀察後,管理執行緒池特別高,所以判斷客戶端正在做一些任務,並且屬於管理執行緒池,具體還不確定, 因為客戶端應用程式沒有看到特定的**呼叫模式。
圖:執行緒池示意圖,用於監控 ES 節點上的任務數。
2) 任務監控和分析
借助執行緒池分析,您可以定位管理執行緒池來大規模執行任務,並使用該任務檢視正在分析的具體任務。 (ps:在實際客戶環境中,發現有大量的狀態和統計任務,其中狀態任務數量明顯高,非常異常,這裡不方便透露,這個結果如何壓測,後面會詳細列出)。
圖:任務的示意圖,可用於檢視特定任務型別。
3)統計監控分析
借助任務監控分析,發現有大量的統計指令,然後在服務端執行一次,看看情況如何,實際響應速度比較慢,但邏輯上正常,生成的佇列數量不高, 但是執行速度較慢,根據上面的判斷,應該是其他任務阻塞造成的。
stats 負責集群監控和檢查響應,常規集群黃、紅、綠三色由此而來; 另外,它還收集索引和節點的統計資訊,返回的資料量不多,所以一般可以忽略,但要注意後期需要傳輸客戶端訪問。
圖:stats 命令執行示意圖。
4) 狀態監測和分析
借助任務監控分析,發現有大量的狀態指令,然後在伺服器上執行一次,找到了問題點,執行時間很長,響應返回的內容超過70MB,這就是問題所在,可以回答為什麼之前的主節點流量這麼高。 最後,問題變得越來越清晰和確定。
圖:狀態命令執行示意圖。
5) 傳輸客戶端應用程式訪問
借助前面的伺服器端現象分析,越來越確定問題出在客戶端應用**上,最有可能的是操作錯誤。
首先,與客戶溝通,讓客戶端應用**訪問ES和程式版本,客戶端開發團隊配合很好的,很快就得知應用客戶端是基於Spring Data Elasticsearch框架的,使用transport-client機制來訪問操作ES,但是這時候無法定位為客戶端導致的, 也不能要求客戶匆忙提供原始碼。不久之後,相應的測試程式原始碼在本地編寫。
傳輸客戶端繫結。
模擬 Spring Data Elasticsearch 配置 transport-client,示例來自官方文件*
configuration
public class transportclientconfig extends elasticsearchconfigurationsupport
bean(name = )
public elasticsearchtemplate elasticsearchtemplate() throws unknownhostexception
6)JMe壓力測試模擬
由於某種原因,我們只能提供間接服務,所以為了徹底解決上述問題,我們需要在本地模擬測試,並且必須先模擬生產問題,然後才能要求客戶端提供原始碼。 根據之前從伺服器和客戶端應用中學到的資訊,下一步是做乙個壓力測試,特別是選擇jmeter工具,快速配置本地集群,並附加客戶端應用訪問**。 在壓力測試過程中,可以同步觀察ES伺服器的ThreadPool和Task,並可以重現生產問題,並快速獲得所需的結果。
圖:JMe壓測示例,開啟執行緒數,執行緒數超過ES測試伺服器上的執行緒數。
圖:JMe壓力測試示例,乙個狀態命令的執行會消耗大量資源。
由於在生產中也發現了同樣的問題,借助 jmeter 壓力測試在本地環境中,最後一步是審核客戶應用開發團隊,速度非常快,很快就能找到客戶應用端,然後再進行具體的業務操作,就會呼叫集群狀態 api 來判斷業務邏輯, 確定索引是否存在,確定索引字段是否存在等。
最終,問題找到了,原因知道了,事情也就結束了。
對客戶申請的訪問。
使用狀態確定索引的對映資訊
public map getmappingbyfield(string indexname, string type) throws ioexception
map mapping = mappings.get(type).getsourceasmap();
map properties = (map) mapping.get(es_properties);
return properties;
3. 回顧問題分析過程
伺服器端分析,尋找突破口。
客戶端分析,以縮小故障排除範圍。
模擬測試以複製生產問題並確定問題的原因。
分析應用端,找出問題所在。
修改觀察結果以確認問題已解決。
吸取的經驗教訓,審查所有其他相關**。
圖:故障排除過程和過程。
3. ES技術架構原理
本次 ES 故障排除涉及到很多知識點和技術原理,這裡專門講解與此相關的架構原理,供大家日後參考和分析。
1. ES架構原理
雖然 ES 聲稱是可以水平擴充套件的分布式架構,但它指的是資料節點或其他非管理節點。 實際上,ES 是一種典型的主從架構模式,乙個集群只有乙個活躍的主節點,主節點負責管理集群的所有元資料資訊,包括節點資訊、索引資訊、分片資訊、節點和索引路由資訊、節點和分片路由資訊等,集群需要先在主節點中執行乙個管理命令, 然後將其分發到其他節點。
這對於理解和解釋為什麼主節點的網路流量正好等於此 ES 故障中其餘節點的網路流量之和非常重要。 當客戶端應用發起狀態計數時,主節點先接受指令,然後分發給其他節點進行狀態統計,最後彙總到主節點,導致主節點網路流量極高,超出網絡卡限制,ES集群響應緩慢, 但實際CPU和記憶體消耗並不高。
隨著集群規模越來越大,大老闆的壓力越來越大,如果大老闆失敗了,大老闆就會連任,這聽起來好像不符合社會組織。 下次能不能修改一下,設計乙個大老闆和第二個主人的模型,然後把大老闆和兩個主人的職責分開,大老闆太忙了,兩個主人分擔一些。
圖:ES主從架構的分布式示意圖,集群只有乙個活動主節點。
2. ES執行緒池
ES是內部設計了多個任務執行緒池的資料庫產品,不同的執行緒池有不同的任務和職責; 執行緒池也分為各種型別,不同的執行緒池型別響應不同的任務場景。 執行緒池的數量和型別因 ES 版本而異,尤其是在 5 中x 與 7X版,這種跨專業版,差別挺大的。
作為機構的ES老師,我經常與J**A學生交流,發現了一些嚴重的認知誤區: 1很多同學認為,由於GC機制的原因,J**A無法開發資料庫產品; 2.大部分人學習掌握 J**執行緒池只用於簡單的多執行緒業務場景,從未想過 ES 整合了幾十個執行緒池。 因此,必須承認,ES對於J**A開發大師來說是乙個非常好的產品,特別是對於做後端開發,想要更深入、更高階的同學來說。
了解 ES 執行緒池的內部設計非常重要,這可以解釋為什麼在這次 ES 故障中,只有 Active Master 節點的管理執行緒池特別忙,其餘的執行緒池一般都非常空閒,其餘節點的執行緒池也非常繁忙。 客戶端應用發起狀態計數,第乙個接收任務的任務是主節點的管理執行緒池,執行緒池型別為伸縮,最大執行緒數為固定值,不超過實際CPU復合數,也不能超過固定值5, 而不是根據節點的CPU核心數自動彈性設計。
當客戶端應用採用多執行緒執行模式時,每次在執行業務操作之前,都會執行一次狀態統計,做出業務邏輯判斷,無形中增加了集群的負載和主節點的任務數量。 正是因為負責執行狀態任務的執行緒池是固定值,主節點的CPU不會滿,導致所有業務操作受阻。
有時候官方文件沒有列出,需要通過ES原始碼來檢查,我還是沒弄清楚,不僅在以前的歷史版本中,而且在現在的最新版本中,比如現在的715.x,有些執行緒池在官方文件中沒有列出,但可以在集群監控中檢視。
圖示:ES 內部執行緒池劃分(版本 7。13.x,來自機構的 ESVIP 課程)。
ES 執行緒池初始化原始碼:orgelasticsearch.threadpool.threadpool */
public class threadpool implements reportingservice, scheduler
3. ES集群統計的執行過程
集群狀態 API 執行一條指令一次,指令傳輸到主動主節點,主動主節點將指令分發給每個節點,每個節點收集資訊併發送回主節點,然後主節點響應客戶端。
在故障排除之初,最初的判斷是錯誤的,認為客戶端在做大量的業務資料查詢任務,並且所有節點的資料量都很高,其中很多都依賴於主節點的外部輸出,但事實並非如此。
圖:集群狀態API執行過程示意圖。
4. ES動態建立索引
ES是典型的免費schema資料產品,可以動態建立索引,也可以動態建立索引字段,無需優先順序宣告,也無需邏輯判斷應用中是否存在**,是否需要建立,這是ES非常優秀的動態擴充套件能力之一, 基於此為應用開發帶來了很多便利,比如著名的“大寬表模式”查詢場景,解決了海量資料關聯的實時查詢問題。
ES可以提前建立索引,也可以不建立索引,可以通過寫入第一條資料來動態建立索引,同時可以自動對映索引的內部結構。 如果在第二次資料寫入中新增了大量新的資料內容結構,則當前索引的對映將自動更新,並且對映將自動重新整理。 如果缺少新新增的資料字段,則不會出現錯誤。 預設情況下,ES 內部會根據字段計算欄位的型別。
動態建立空索引。
put my-index-000001
新增資料,動態建立索引,並自動估計字段型別。
put my-index-000001/_doc/1
create_date": "2015/09/02"
更新資料並動態新增新的字段型別。
put my-index-000001/_doc/1
my_float": "1.0",
my_integer": "1" ,"create_date": "2015/09/02"
5、transport-client
Transport Client 是早期正式推出的應用訪問機制,自 REST API 上線以來,官方一直試圖要求切換,原因沒有具體說明。 transport 是一種直接連線方式,直接連線到 ES 集群,連線後保持持久連線,需要定期執行一些內部 stats 命令來檢查集群監控狀態,這實際上是非常冗餘的,極端情況下會消耗集群資源。
ES 集群中其他指令的內部通訊或執行是通過 Transport 機制進行的,即使由 REST API 執行,也會在內部轉換為 Transport 機制進行執行。
REST訪問比傳輸更解耦,也可以盡量避免惡意干擾傳輸通訊。
圖:transport-client 和 REST API 之間的連線示意圖。
四、專家建議
這一次,花了幾天時間才找到問題,定位問題,解決問題,還有一些經驗建議需要解釋。
1.全面的監控系統
監控系統是運維之眼,集群的各類執行資訊需要借助強大的監控系統來提供實時分析。 在這種情況下,客戶公司的監控系統比較傳統和落後,雖然有Zabbix,但在一些新的問題分析方式上並不好,而且非常缺乏,比如分析集群每個節點的流量,包括伺服器和客戶端之間的關係。
選擇一款全面且具有非常獨立視角的監控產品非常重要,而 Elastic Stack 是新時代的產品,可以幫助我們改進優化故障排除思維。
2. 許可權安全隔離
大多數資料庫產品都提供了一些基本的安全策略和保護,可以通過設定一些安全使用者組和角色許可權來限制這些策略和保護。
例如,傳統的關聯式資料庫 MySQL 可以通過為客戶端應用程式分配較少的許可權來限制。 在早期的 ES 版本中,由於 ES 沒有提供安全保護機制,很多應用團隊直接使用它,並沒有實現基於使用者組的許可權隔離。 最新版本的 ES 提供了開源且免費的基礎安全策略,可以避免客戶端應用程式通過使用者組許可權進行無意操作。
3. 全面的知識體系
在這種情況下,從集群的後端運營分析,到應用端的原始碼分析,再到本地環境的模擬測試,涉及的技術點非常廣泛,無法從單一維度發現和解決,也不能僅從ES知識層面解決。 沒有人可以只從ES集群中跑出表面定位問題,很多問題都在盡頭,但原因其實在另一端,這需要跨界能力和思維,當然最重要的是建立自己的知識體系,有自己獨立的解決問題的想法,也要掌握必要的工具和軟體, 不僅限於 ES 的範圍。
為了用好 ES,我們需要掌握開發技能,熟練使用 ES 提供的開發特性,了解 ES 各種特性的邊界,防止濫用。 我們需要掌握ES集群架構的基本原理和基本操作機制,避免認知誤區,比如ES是典型的主從架構分布,而不是無中心分布。 我們需要掌握一般的運維技能,從作業系統的基礎環境到ES執行的各種指標資訊。
4. 全棧工程師理念
隨著業務需求和社會的發展,我們需要更多的全棧工程師,當然也要說明,不需要乙個工程師同時承擔多個工作,也不是按照國內一些企業的“擠全棧”的說法。 相反,強調工程師的專業水平,工程師可以根據自己的工作崗位輕鬆轉換角色,而不僅僅是固定的崗位。 很多優秀的IT產品,不是由在自己工作崗位上工作的人製作的,而是由一些跨界人士製作的。
在這種情況下,看似集群的問題是伺服器,其實是開發知識的侷限性造成的,最終的解決方案也是修改應用端來解決,這是乙個典型的跨界問題,逐漸被伺服器發現是應用端的問題。 為了模擬生產環境的問題,需要使用壓力測試工具,這似乎是測試的責任,但為了解決問題,有必要從後向前工作。 為了確定執行緒池設定問題,對應的版本原始碼,去檢查並閱讀相應的執行緒池設定,因為官方文件沒有。 若要識別客戶端應用問題,請根據客戶端開發人員提供的資訊編寫模擬的客戶端應用行為。
目前,公司在中國的工程師大多是單一職責的崗位和技能,尤其是專注於前後端分離後,前端和後端的技能比較認真,前端很多工資都很高,上公升速度快,看不起後端, 後端逐漸遠離前端應用,更關注前端操作模式;後端應用和大資料開發也分離,將大資料開發與應用開發分開,導致工程師的專業素質迅速下降,很多大資料工程師沒有良好的程式設計技能,這是乙個值得思考的問題。
引用
狀態參考文件。
ThreadPool 參考文件。
Elasticsearch 傳輸客戶端參考文件。
Spring Data Elasticsearch 參考文件。
JMemeter HTTP 請求參考文件。
DBAPLUS 社群歡迎 editor@dbaplus 技術人員的貢獻cn