當前位置:首頁 » 服務存儲 » es存儲日誌原理
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

es存儲日誌原理

發布時間: 2023-08-25 09:19:50

❶ 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寫索引的流程