❶ Elasticsearch之存儲原理
倒排索引被寫入磁碟後是不可變的,ES解決不變性和更新索引的方式是使用多個索引,利用新增的索引來反映修改,在查詢時從舊的到新的依次查詢,最後來一個結果合並。
ES底層是基於Lucene,最核心的概念就是 Segment(段) ,每個段本身就是一個倒排索引。
ES中的Index由多個段的集合和 commit point(提交點) 文件組成。
提交點文件中有一個列表存放著所有已知的段,下面是一個帶有1個提交點和3個段的Index示意圖:
Doc會先被搜集到內存中的Buffer內,這個時候還無法被搜索到,如下圖所示:
每隔一段時間,會將buffer提交,在flush磁碟後打開新段使得搜索可見,詳細過程如下:
下面展示了這個過程完成後的段和提交點的狀態:
通過這種方式,可以使得新文檔從被索引到可被搜索間的時間間隔在數分鍾,但是還不夠快。因為磁碟需要 fsync ,這個就成為性能瓶頸。我們前面提到過Doc會先被從buffer刷入段寫入文件系統緩存(很快),那麼就自然想到在這個階段就讓文檔對搜索可見,隨後再被刷入磁碟(較慢)。
Lucene支持對新段寫入和打開,可以使文檔在沒有完全刷入硬碟的狀態下就能對搜索可見,而且是一個開銷較小的操作,可以頻繁進行。
下面是一個已經將Docs刷入段,但還沒有完全提交的示意圖:
我們可以看到,新段雖然還沒有被完全提交,但是已經對搜索可見了。
引入refresh操作的目的是提高ES的實時性,使添加文檔盡可能快的被搜索到,同時又避免頻繁fsync帶來性能開銷,依靠的就是文件系統緩存OS cache里緩存的文件可以被打開(open/reopen)和讀取,而這個os cache實際是一塊內存區域,而非磁碟,所以操作是很快的,這就是ES被稱為近實時搜索的原因。
refresh默認執行的間隔是1秒,可以使用 refreshAPI 進行手動操作,但一般不建議這么做。還可以通過合理設置 refresh_interval 在近實時搜索和索引速度間做權衡。
index segment刷入到os cache後就可以打開供查詢,這個操作是有潛在風險的,因為os cache中的數據有可能在意外的故障中丟失,而此時數據必備並未刷入到os disk,此時數據丟失將是不可逆的,這個時候就需要一種機制,可以將對es的操作記錄下來,來確保當出現故障的時候,已經落地到磁碟的數據不會丟失,並在重啟的時候可以從操作記錄中將數據恢復過來。elasticsearch提供了translog來記錄這些操作,結合os cached segments數據定時落盤來實現數據可靠性保證(flush)。
文檔被添加到buffer同時追加到translog:
進行 refresh 操作,清空buffer,文檔可被搜索但尚未 flush 到磁碟。translog不會清空:
每隔一段時間(例如translog變得太大),index會被flush到磁碟,新的translog文件被創建,commit執行結束後,會發生以下事件:
下面示意圖展示了這個狀態:
translog記錄的是已經 在內存生成(segments)並存儲到os cache但是還沒寫到磁碟的那些索引操作 (注意,有一種解釋說,添加到buffer中但是沒有被存入segment中的數據沒有被記錄到translog中,這依賴於寫translog的時機,不同版本可能有變化,不影響理解),此時這些新寫入的數據可以被搜索到,但是當節點掛掉後這些未來得及落入磁碟的數據就會丟失,可以通過trangslog恢復。
當然translog本身也是磁碟文件,頻繁的寫入磁碟會帶來巨大的IO開銷,因此對translog的追加寫入操作的同樣操作的是os cache,因此也需要定時落盤(fsync)。translog落盤的時間間隔直接決定了ES的可靠性,因為宕機可能導致這個時間間隔內所有的ES操作既沒有生成segment磁碟文件,又沒有記錄到Translog磁碟文件中,導致這期間的所有操作都丟失且無法恢復。
translog的fsync是ES在後台自動執行的,默認是每5秒鍾主動進行一次translog fsync,或者當translog文件大小大於512MB主動進行一次fsync,對應的配置是 index.translog.flush_threshold_period 和 index.translog.flush_threshold_size 。
當 Elasticsearch 啟動的時候, 它會從磁碟中使用最後一個提交點去恢復已知的段,並且會重放 translog 中所有在最後一次提交後發生的變更操作。
translog 也被用來提供實時 CRUD 。當你試著通過ID來RUD一個Doc,它會在從相關的段檢索之前先檢查 translog 中最新的變更。
默認 translog 是每5秒或是每次請求完成後被 fsync 到磁碟(在主分片和副本分片都會)。也就是說,如果你發起一個index, delete, update, bulk請求寫入translog並被fsync到主分片和副本分片的磁碟前不會反回200狀態。
這樣會帶來一些性能損失,可以通過設為非同步fsync,但是必須接受由此帶來的丟失少量數據的風險:
flush 就是執行commit清空、幹掉老translog的過程。默認每個分片30分鍾或者是translog過於大的時候自動flush一次。可以通過flush API手動觸發,但是只會在重啟節點或關閉某個索引的時候這樣做,因為這可以讓未來ES恢復的速度更快(translog文件更小)。
滿足下列條件之一就會觸發沖刷操作:
整體流程:
刪除一個ES文檔不會立即從磁碟上移除,它只是被標記成已刪除。因為段是不可變的,所以文檔既不能從舊的段中移除,舊的段也不能更新以反映文檔最新的版本。
ES的做法是,每一個提交點包括一個 .del 文件(還包括新段),包含了段上已經被標記為刪除狀態的文檔。所以,當一個文檔被做刪除操作,實際上只是在 .del 文件中將該文檔標記為刪除,依然會在查詢時被匹配到,只不過在最終返回結果之前會被從結果中刪除。ES將會在用戶之後添加更多索引的時候,在後台進行要刪除內容的清理。
文檔的更新操作和刪除是類似的:當一個文檔被更新,舊版本的文檔被標記為刪除,新版本的文檔在新的段中索引。
該文檔的不同版本都會匹配一個查詢,但是較舊的版本會從結果中刪除。
通過每秒自動刷新創建新的段,用不了多久段的數量就爆炸了,每個段消費大量文件句柄,內存,cpu資源。更重要的是,每次搜索請求都需要依次檢查每個段。段越多,查詢越慢。
ES通過後台合並段解決這個問題。ES利用段合並的時機來真正從文件系統刪除那些version較老或者是被標記為刪除的文檔。被刪除的文檔(或者是version較老的)不會再被合並到新的更大的段中。
可見,段合並主要有兩個目的:
ES對一個不斷有數據寫入的索引處理流程如下:
合並過程如圖:
從上圖可以看到,段合並之前,舊有的Commit和沒Commit的小段皆可被搜索。
段合並後的操作:
合並完成後新的段可被搜索,舊的段被刪除,如下圖所示:
注意 :段合並過程雖然看起來很爽,但是大段的合並可能會佔用大量的IO和CPU,如果不加以控制,可能會大大降低搜索性能。段合並的optimize API 不是非常特殊的情況下千萬不要使用,默認策略已經足夠好了。不恰當的使用可能會將你機器的資源全部耗盡在段合並上,導致無法搜索、無法響應。
❷ 日誌平台的一點思考
日誌平台的對開發、運維人員的幫助是非常大的,它可以方便開發、運維人員快速定位問題,從這個角度,日誌平台是個搜索平台;同時還可以做有效的數據分析,比如分析 pv, uv,httpstatus,用戶行為,資源消耗,網路攻擊、trace等等,應用場景非常豐富,這時候它又是個數據分析平台,在馬上到來的5G時代,物聯網的真正興起,日誌平台會發揮更大的價值。
日誌其實是比較寬泛的概念,應用列印的server log,Linux文件系統的syslog,/var/messages 等等都是日誌,日誌本質上其實是一種時序數據,類似於監控領域的metrics,只不過metrics一般是比較結構化的,每個欄位數據長度都比較小,通常是時間+tag+value ,而日誌也帶有時間,但是單條日誌可能會比較長(有時候不止一行) ,同時大多數都是非結構化的文本數據,它們共同的特點是數據產生後不會被更新。
簡單說日誌平台既要存儲又要計算
功能上,日誌平台應該具備以下幾個基本的功能點
1、日誌的採集
2、日誌數據的存儲
3、日誌數據的快速檢索和分析
日誌要搜索,就要集中存儲,就要採集日誌,以前日誌採集分2種,一種是agent的方式,一種是agentless的方式,前者是在要採集的伺服器上部署一個agent,agent將日誌不斷的發送給日誌server端,agentless的方式是通過類似ssh遠程登錄伺服器去抓日誌。
agentless的方式不需要部署agent,一般是定時的方式去拉日誌過來,這種方式時效性很差,不能實時監聽文件系統獲取最新的日誌數據,基本上業內很少有人採用了,以前阿里巴巴的TLog似乎是採用這種方式。
現在大部分是採用部署agent的方式獲取日誌,比較有名的是flume,logstash,filebeat等等,flume和logstash在使用的時候,不方便控制佔用的cpu和內存資源,在微服務化架構的環境中,採集日誌對agent的性能要求越來越高,同時資源消耗要盡可能的低,filebeat相對比較輕量,功能也非常強大,使用人越來越多。
agent的方式本質上是調用server的api介面將數據發送給日誌的server,因此另一種使用方式就是app直接調用日誌server的api,比如將這個功能做成log4j的插件,或者寫入其它的常用的日誌組件中,這樣日誌採集的成本最低,但是當日誌服務不可用的時候,日誌數據恢復成了稍微麻煩的事情。
通常在一個成規模的企業內部,使用agent的方式採集日誌,管理agent也是一個問題,比如阿里巴巴目前聲稱SLS的agent部署超過200萬個節點,不要說200萬個節點,就是200個節點,我們總不能挨個登陸去修改agent的配置文件吧,因此採集任務的自動下發,生效,更改非常重要,同時還要能夠自動管理agent的狀態,升級agent等等。
以前阿里巴巴的TT也有agent採集,部署規模也較大,在實現方面,有些場景下agent會請求服務端的clientAPI,這種設計在雙11降級恢復的時候,會給clientAPI帶來非常大的壓力,因此,在設計應用於大規模的agent部署場景的時候,應該考慮這種問題。
寫的目的是為了讀,要更好的讀,就要設計更合理的存儲方案。既要滿足檢索,又要做數據統計和分析,似乎解決方案只有倒排索引了?開源社區一提到日誌的存儲,一般都會選擇elasticsearch,一些創業公司也會基於或者借鑒es來做存儲的方案,這個東西的確開箱即用,一個命令拉起來,日誌灌進去,搜索效果似乎也不錯,kibana也能分析,但是當我們實際部署應用起來,就會發現用es存日誌是一個成本非常昂貴的方案。
在一家稍有規模的公司,日誌數據10w/s每秒的寫入是非常容易出現的,實時索引,然後刷到文件系統緩存才可見,es這種實現方式,本身就不適合迎接這種高tps的寫入,同時它讀寫不分離,一般情況下,Lucene的設計在日誌場景下需要經過特殊的優化,比如將那些常駐內存的數據進行lru處理,將不常用的索引關閉,在merge的時候對避免重復IO,segment關系映射內存優化等等,越深入了解,越發現這種方案真的太奢華了,業內用es做日誌存儲的基本上都是土豪,動輒幾百上千的伺服器堆砌 + 精細化運維,性價比極低,真是暴殄天物,日誌規模較大的,財力一般的公司就不要考慮這種敗家的方案了。
日誌的存儲實際上需要實時求是,根據日誌的特點,靈活的設計存儲方案。
日誌搜索也是一種典型的互動式查詢的場景, 當然是越快越好,比較理想的情況是1-3秒返回結果,但是時間跨度非常大的場景,十幾秒用戶也能接受,超大規模查詢最慢不超過30秒等等,檢索方面,除了輸入關鍵字,還希望能夠支持功能強大的分析、過濾、統計。這種特點,其實給存儲留下了非常大的設計空間,也是不小的挑戰。
存儲首先應該是分布式的,可以方便水平擴展的,同時根據日誌的特點,做少量的必要的索引。比如日誌一般是按照時間范圍搜索和分析的,那麼時間顯然是最重要的索引,同時日誌來自哪些機器,屬於哪個應用,什麼機房,應該會有一些標簽,那做一些基於標簽的索引就足夠了,那麼現有的一些存儲系統能不能直接利用呢?
前面說了日誌是一種時序數據,那麼opentsdb能不能做日誌的存儲呢?opentsdb本身依賴hdfs,hbase,從部署角度講,太復雜,同時它一行就存儲一小時的數據,每一行是一個metric,這種方式,你日誌怎麼存,顯然不合理。
kafka這種東西呢,它也給每條消息加了時間戳信息,支持按照時間戳seek,kafka的架構設計其實給了我很多日誌存儲設計的啟發,但是它的索引僅有時間是不夠的,也許你會想能不能在topic名字上做點文章,我想也是不可以,因為我們要索引的東西還是蠻多的,kafka在topic數量非常大的情況下,性能會下降的比較明顯。
日誌統計和分析方面阿里巴巴的SLS是通過標准sql來做的,但是我更喜歡類似shell命令行的風格和方式,sql思維需要一些時間轉變,用戶並不一定都會喜歡sql,但是不管怎麼樣,要分析、統計日誌,需要在日誌存儲系統上面搭建一套DSL分析引擎,能夠加入常用的運算元,同時還能分布式執行這些運算,同時快速的返回結果,曾經想過用MLSQL載入日誌的數據然後用sql分析完將結果取回,這其實也是一條很好的思路,雖然MLSQL不需要每次都提交spark作業的過程,但是搬運數據還是會犧牲掉一部分時效性,好處是計算和存儲是分離的,同時我還希望日誌平台能夠實時的監聽一些我感興趣的日誌事件,然後在自定義的dashboard中展示,支持報警等等。
最近1-2年一直在研究探索更具性價比的日誌管理平台,後續會將一些心得體會、解決方案記錄下來跟大家分享。
❸ ElasticSearch部署架構和容量規劃
前面介紹了ElasticSearch原理和使用相關的內容,在生產環境如何比較科學的進行容量規劃、部署、調優、排查問題呢,業界和官方也對相關的問題進行總結,我這邊也結合自己的經驗對這些使用ElasticSearch經常遇到的問題進行了總結。其中主要包括以下三大模塊:
ElasticSearch有多種類型的節點,在前面概述和核心也已經介紹過了。在這里可以重新回顧下。ElasticSearch的部署節點類型如下:
主節點及其候選節點,負責集群狀態(cluster state)的管理
配置項:node.master,默認為true
數據節點,負責數據存儲及處理客戶端請求
配置項:node.data,默認為true
ingest節點,負責數據處理,腳本執行
配置項:node.ingest,默認為true
協調節點
配置項:設置上面三個參數全部為false,那麼它就是一個純協調節點
機器學習節點,收費屬於x-pack
在生產環境部署推薦配置整體思路就是:盡量是一個節點只承擔一個角色。
因為不同的節點所需要的計算機資源都不一樣。職責分離後可以按需擴展互不影響。
資源要求:中高CPU;中高內存;中低磁碟
一般在生產環境中配置3台
一個集群只有1台活躍的主節點,負責分片管理,索引創建,集群管理等操作
資源要求:CPU、內存、磁碟要求都高
資源要求:高配置CPU;中等配置的RAM;低配置的磁碟
資源要求:一般中高CPU;中高內存;低磁碟
協調節點扮演者負載均衡、結果的聚合,在大型的es集群中條件允許可以使用高配的cpu和內存。因為如果客戶端發起了深度分頁等請求可能會導致oom,這個在之前也有過分析。
注意:
如果和數據節點或者Coordinate節點混合部署,數據節點本來相對有比較大的內存佔用。
而Coordinate節點有時候可能會有開銷很高的查詢導致OOM,這些甚至都有可能影響Master節點,導致集群的不穩定。
搭建一個es集群是由模式可循的。
這是一個基礎版的職責分離的部署架構:
但是如果大量的聚合查詢等操作,這種架構不太適合了。
當系統中有大量的復雜查詢或者聚合時候,我們可增加Coordinating節點,增加查詢的性能,這里增加了負載均衡層,通過負載均衡擴展時應用程序無感知。
這樣部署部署相互影響,寫入多的話,多部署ingetst節點,讀的時候聚合查詢較多可以多部署協調節點,存儲數據量大,可以適當對數據節點進行調優。
我們知道數據有冷熱之分,比如寫入頻繁的日誌數據,近期的索引將會頻繁寫入。es根據數據這些特徵引入了hot節點和warm節點。
使用ssd,該節點上的索引不斷的有新文檔寫入和查詢,對cpu、io的要求較高。
可以使用HDD,上面的索引不會有寫入,查詢較少。上面只保存只讀索引或者舊索引,使用大容量便宜的機械硬碟。
配置步驟:
針對多機房災備,ElasticSearch業界有多種不同的通用解決方案:
一個集群中的節點分布在不同的機房
應用程序同時將數據寫入兩個集群
應用程序先將數據寫入消息隊列,然後由下游的消費者消費並寫入集群
ElasticSearch官方的跨集群復制功能,基於文檔操作實現訂閱復制
定期將索引備份到外部存儲,如hdfs等設備
寫請求交給網關,網關實時寫入主集群,然後非同步寫備集群
如下是基於CCR跨集群復制的部署架構,因為篇幅有限,異地多活又是一個很大的話題,其它方案和其細節可以查閱相關資料。
我們知道當es集群的節點數大於索引的分片數時,集群將無法通過水平擴展提升集群的性能。而分片數過多,對於聚合查詢以及集群的元數據管理也都有影響。我們可以總結為:
分片數量較多
優點:
缺點:
通常建議一個集群總分片數小於10w。
如何設計分片的數量呢?一個分片保持多大的數據量比較合適呢?
我們需要根據使用場景來設置:
避免使用非常大的分片,因為這會對群集從故障中恢復的能力產生負面影響。而每個分片也會消耗相應的文件句柄,內存和CPU資源,分片太多會互相競爭,影響性能。
主分片數一旦確定就無法更改,只能新建創建並對數據進行重新索引(reindex),雖然reindex會比較耗時,但至少能保證你不會停機。所以我們一定要科學的設計分片數。
這里摘錄於官方關於分片大小的建議:
主分片與副本都能處理查詢請求,它們的唯一區別在於只有主分片才能處理索引請求。副本對搜索性能非常重要,同時用戶也可在任何時候添加或刪除副本。額外的副本能給帶來更大的容量,更高的呑吐能力及更強的故障恢復能力
3.1.3. 小結
根據實際經驗我們稍微總結下:
對於數據量較小(100GB以下)的index
對於數據量較大(100GB以上)的index:
綜合考慮整個index的shard數量,如果shard數量(不包括副本)超過50個,就很可能引發拒絕率上升的問題,此時可考慮把該index拆分為多個獨立的index,分攤數據量,同時配合routing使用,降低每個查詢需要訪問的shard數量。
關閉交換分區的方法是:
這里是官方的jvm推薦配置鏈接:
https://www.elastic.co/cn/blog/a-heap-of-trouble
es的節點提供查詢的時候使用較多的內存來存儲查詢緩存,es的lucene寫入到磁碟也會先緩存在內存中,我們開啟設計這個es節點時需要根據每個節點的存儲數據量來進行判斷。這里有一個流行的推薦比例配置:
示例:
有一個業務的數據量預估實際有1T,我們把副本設置1個,那麼es中總數據量為2T。
這里31G表示的是jvm設置不超過32g否則不會使用java的指針壓縮優化了。
前面也提到過,數據節點推薦使用ssd
可以考慮:
寫入的目標在於增大寫入的吞吐量,這里主要從兩個方面進行優化:
這里可以針對myindex索引優化的示例:
首先有幾個原則我們需要清楚:
我們可以通過health相關的api進行查看
我們可以使用profile api來定位慢查詢。
在查詢條件中設置profile為true的參數,將會顯示查詢經歷的細節。
其結果為:
這里會返回一個shards列表。其中:
主要包含了如下信息:
Profile API讓我們清楚地看到查詢耗時。提供了有關子查詢的詳細信息,我們可以清楚地知道在哪個環節查詢慢,另外返回的結果中,關於Lucene的詳細信息也讓我們深入了解到ES是如何執行查詢的。
ES記錄了兩類慢日誌:
慢搜索日誌
用來記錄哪些查詢比較慢,每個節點可以設置不同的閾值。
之前我們已經詳細分析了ES的搜索由兩個階段組成:
慢搜索日誌給出了每個階段所花費的時間和整個查詢內容本身。慢搜索日誌可以為查詢和取回階段單獨設置以時間為單位的閾值,在定義好每個級別的時間後,通過level決定輸出哪個級別的日誌。
示例如下
前面參考官方鏈接:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-moles-slowlog.html
如果出現節點佔用CPU很高,我們需要知道CPU在運行什麼任務,一般通過線程堆棧來查看。
這里有兩種方式可以查看哪些線程CPU佔用率比較高:
這里推薦使用hot_threads api
通過返回的結果可以看到什麼線程佔用更高,正在做什麼操作。更詳細的內容可以參考官網:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-hot-threads.html
4.3.2 內存使用率過高
1)緩存類型
首先我們需要了解ES中的緩存類型,緩存主要分成如圖所示三大類,如下圖所示,一個es節點的內存結構:
Node Query Cache(Filter Context)
Shard Query Cache(Cache Query的結果)
Fielddata Cache
Segments Cache
(segments FST數據的緩存),為了加速查詢,FST永駐堆內內存,無法被GC回收。該部分內存無法設置大小,長期佔用50%~70%的堆內存,只能通過delete index,close index以及force-merge index釋放內存
ES底層存儲採用Lucene(搜索引擎),寫入時會根據原始數據的內容,分詞,然後生成倒排索引。查詢時,先通過查詢倒排索引找到數據地址(DocID)),再讀取原始數據(行存數據、列存數據)。
但由於Lucene會為原始數據中的每個詞都生成倒排索引,數據量較大。所以倒排索引對應的倒排表被存放在磁碟上。
這樣如果每次查詢都直接讀取磁碟上的倒排表,再查詢目標關鍵詞,會有很多次磁碟IO,嚴重影響查詢性能。為了解磁碟IO問題,Lucene引入排索引的二級索引FST[Finite State Transcer]。原理上可以理解為前綴樹,加速查詢
2)節點的內存查看
3)案例分析
如果節點出現了集群整體響應緩慢,也沒有特別多的數據讀寫。但是發現節點在持續進行Full GC。
常見原因:
Segments個數過多,導致Full GC
我們可以通過查看ElasticSearch的內存分析命令發現:
segments.memory佔用很大空間。
解決方案:
Field data cache 過大,導致Full GC
我們可以查看ElasticSearch的內存使用,發現fielddata.memory.size佔用很大空間。同時,數據不存在寫入和更新,也執行過segments merge。
解決方案:
復雜的嵌套聚合,導致集群Full GC
節點響應緩慢,持續進行Full GC。導出Dump分析。發現內存中有大量 bucket對象,查看日誌,發現復雜的嵌套聚合
解決方案:
4)斷路器
es有多種斷路器,我們可以合理使用,避免不合理操作引發的OOM,每個斷路器可以指定內存使用的限制。
關於es的斷路器使用可以參考官網文檔:
https://www.elastic.co/cn/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker
在排查es問題時,我們會使用一些常見的命令來分析cpu、io、網路等問題。常見的命令如下
我們這里按照1s的頻率輸出磁碟信息
如果想查看和進程關聯的信息,可以使用pidstat或者iotop。
例如,下面為iotop的輸出結果
sar命令可以診斷操作系統內存相關情況。
PS:我們需要關閉內存交換,內存交換會嚴重損害性能 。
我們知道,操作系統有內核態和用戶態,該命令可以輸出相關信息
Recv-Q和Send-Q代表該連接在內核中等待發送和接收的數據長度。
如果改數據太多,可能原因為應用程序處理不及時或者對端的數據接收不及時,比如網路擁塞之類
本片文章先介紹了es的部署架構,回顧了es節點類型以及它們的配置方式,也了解了不同類型對硬體的要求不一樣。然後總結了幾種不同的架構模式,比如基礎部署、讀寫分離、冷熱分離、異地多活等架構模式,在生產環境中一般我們推薦讀寫分離架構模式,如果可以最好加上冷熱分離,不過配置可能稍微復雜點。
對於容量規劃與調優,首先要明確存儲的數據量和使用場景,推薦內存磁碟比為:搜索類比例(1:16),日誌類(1:48);比如2T的總數據,搜索如果要保持良好的性能的話,每個節點31*16=496G。每個節點實際有400G的存儲空間。那麼2T/400G,則需要5個es存儲節點,每個節點分片數多少合適,文中也有介紹。副本分片數需要根據我們的容錯需求。我們還總結了集群配置和jvm配置相關的優化。
es的使用優化,我們分別總結了寫入和查詢的優化。寫入是其單次數據量、索引refresh、分詞等情況都會影響其吞吐量,我們需要根據實際情況來優化。針對於查詢,我們可以使用api工具進行分析,分析慢耗時發在在哪一步。當es集群出現異常時,如cpu過高、內存fullgc、卡頓、變紅,我們逐一分析了可能的原因和解決辦法,同時也介紹了一些常見的診斷工具和監控api。
我們需要先了解es內部運作的原理,這樣才能根據實際情況正確的設置集群參數和數據模型,還需要結合實際工作遇到的問題不斷的總結經驗,才能用好ElasticSearch。
❹ ES數據存儲可靠性和寫入流程
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/near-real-time.html
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/merge-process.html
1、數據存儲可靠性保證原理
1.1 translog機制
當一個文檔寫入Lucence後是存儲在內存中的,即使執行了refresh操作仍然是在文件系統緩存中,如果此時伺服器宕機,那麼這部分數據將會丟失
當進行文檔寫操作時會先將文檔寫入Lucene,然後寫入一份到translog,寫入translog是落盤的
tips:如果對可靠性要求不是很高,也可以設置非同步落盤,可以提高性能,由配置index.translog.rability和index.translog.sync_interval控制
tips:translog是追加寫入,因此性能比較好
先寫入Lucene再寫入translog。原因是寫入Lucene可能會失敗,為了減少寫入失敗回滾的復雜度,因此先寫入Lucene
1.2 flush操作
refresh_interval定時觸發 或當translog達到index.translog.flush_threshold_size(默認512mb),ES會觸發一次flush操作:先執行refresh操作將buffer中的數據生成segment,然後調用lucene的commit方法將所有內存中的segment fsync到磁碟,最後會清空translog中的數據(6.x版本為了實現sequenceIDs,不刪除translog) 。
1.3 merge操作
refresh操作會產生大量的小segment,因此產生的每個文件都會消耗文件句柄,內存,CPU 使用等各種資源。更重要的是每個查詢請求都要順序檢查每個segment; segment越多檢索會越慢.
ES會運行一個檢測任務,在後台把近似大小的segment合並成一個新的大segment,並刪除舊segment
1.4、多副本機制
ES有多副本機制(默認是1個副本),一個分片的主副分片不能分片在同一個節點上,進一步保證數據的可靠性。
2、ES寫索引的流程