ElasticSearch不停機重建索引延伸思考及優(yōu)化詳解
前言
距離我第一次上手ES過去了一年半多了吧,當時我是從零開始花了大半年時間搭建了一整套Filebeat+Kafka+數(shù)據(jù)處理服務+Elasticsearch+Kibana+Skywalking日志收集系統(tǒng)。感覺還是很刺激的,畢竟同時去深度學習和運用多個剛上手的中間件對我來說是個極大的磨練。日志收集系統(tǒng)的數(shù)據(jù)處理服務切換到了Flink,這個后面總結完畢后我會出一篇單獨的文章講講Flink和改造過程。但是始終有一個問題困擾著我,團隊內(nèi)部對于ES的應用尚淺,僅僅用來做日志收集,導致我對ES的認識一直不算深刻,所以我之前也沒有寫一篇優(yōu)秀的文章來闡述我的認知。當然現(xiàn)在我依舊算個小白,但是因為一兩個需求重新深刻認識了ES,算是一段不錯的經(jīng)歷,因此分享給大家,有問題的話請各位大佬指正。
需求
同事提給我的,說是需要對過去半年時間做一個系統(tǒng)應用的用戶使用情況統(tǒng)計,很急。具體是需要按照系統(tǒng)分組統(tǒng)計每個用戶的使用情況,很好,之前完全沒有單獨設計過相關的統(tǒng)計入口,因此只能根據(jù)日志內(nèi)容硬寫查詢語句了。因為需求比較麻煩,所以注定是個復雜聚合查詢,不巧的是我對于ES的查詢API有點忘了,只能現(xiàn)學現(xiàn)賣了。為啥不熟呢?我自己總結的原因一是日志場景單一,JavaAPI只需要布爾查詢拼條件即可,不會很復雜,后面改成Kibana后索引模式用上就不存在什么API調(diào)用了。原因二是由于工作繁忙,沒有別的技術場景,因此沒有太關注ES的API部分,重點都是在性能優(yōu)化和日志收集系統(tǒng)的完善上面。
除了上面的復雜查詢讓我稍微感到難度之外,在聚合查詢的時候還發(fā)現(xiàn)了歷史遺留的問題,新索引優(yōu)化了映射并沒有修改老索引,因此新老索引映射是有一點區(qū)別的,需要重建索引。重建索引自然要上真實場景,不停機重建索引。
查詢本體
對應查詢語句和執(zhí)行結果如上圖,簡要提幾點限制打開的方法和一些優(yōu)化的手段。
查詢限制
1.查詢總數(shù)默認限制10000條
查詢時帶上"track_total_hits": true,打開限制,返回真實條數(shù)
2.聚合查詢時使用term,默認限制10條
聚合查詢參數(shù)中加上"size": 50,配置展示最多50條
聚合查詢優(yōu)化
聚合查詢?yōu)榱吮M量返回少的數(shù)據(jù)量,提升查詢效率,通常設置size為0,體現(xiàn)為查詢結果中hits不返回具體文檔數(shù)據(jù)。
遇到問題
1.text類型不支持聚合
報錯內(nèi)容:
Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [userId] in order to load field data by uninverting the inverted index. Note that this can use significant memory(文本字段未針對需要每個文檔字段數(shù)據(jù)的操作(如聚合和排序)進行優(yōu)化,因此默認情況下禁用這些操作。請改用關鍵字字段?;蛘?,在 [userId] 上設置 fielddata=true,以便通過反轉(zhuǎn)倒排索引來加載字段數(shù)據(jù)。請注意,這可能會占用大量內(nèi)存)
解決方案:
text類型默認不支持聚合和排序,因此要么修改mapping增加屬性fielddata=true,或者直接修改字段類型為keyword
2.分詞查詢時不知道寫哪些詞
查詢文檔分詞結果--索引=log-zero-pro-202302-alias1,id=1xKdCoYBeajfMMIRdyre,字段=msg
GET /log-zero-pro-202302-alias1/_doc/1xKdCoYBeajfMMIRdyre/_termvectors?fields=msg
我想這是大多數(shù)新手遇到的問題,配了分詞后,我就隨便亂輸發(fā)現(xiàn)匹配不了,開始懵逼,疑惑這分詞怎么沒有效果。但是我們把分詞當作一個模糊查詢?nèi)ビ昧?,兩者還是有一定區(qū)別的,特別是粗分詞的時候,不太熟練的情況下,還是先查一下分成啥樣再去查詢比較好。
不停機重建索引
為啥要重建索引呢?因為索引創(chuàng)建之后是不允許修改映射的,如果修改只能重建。不停機重建索引的步驟還是比較簡單,就三步。
新建索引
新建索引正常建就行,因為重建索引用到了reIndex這個API,內(nèi)部是由scroll+bulk實現(xiàn),本質(zhì)上就是先查詢再批量插入。因此可以做一些寫入優(yōu)化,副本數(shù)可以先設置為0,刷新間隔禁用,落盤機制調(diào)整異步和延遲。
PUT /log-zero-pro-202206_re/_settings { "index" : { "number_of_replicas" : 0, "refresh_interval": "-1" } }
切換別名指向新索引
ES的索引設計時最好提前加上一個別名,用別名去管理索引,它就像一層代理,讓我們不用在意底層索引,可以隨時切換。我們建立一個新的索引后,將別名指向新的索引,這樣新數(shù)據(jù)就會灌到新索引中,避免老索引在遷移中仍有數(shù)據(jù)進入,導致數(shù)據(jù)遷移不完整,需要二次遷移。
POST /_aliases { "actions" : [ { "remove" : { "index" : "log-zero-pro-202207-alias1", "alias" : "log-zero-pro-202207" } }, { "add" : { "index" : "log-zero-pro-202207_re", "alias" : "log-zero-pro-202207" } } ] }
遷移數(shù)據(jù)
選擇ES自帶的reIndex進行遷移,這里盡量優(yōu)化一下
- slices=auto&refresh,因為內(nèi)部使用scroll查詢,因此可以選擇分片查詢提升效率,auto意思是自動改成索引分片數(shù)
- wait_for_completion=false,為了避免遷移時間過長超時,所以選擇異步執(zhí)行
- size: 5000,也是提升單次查詢數(shù)據(jù),默認1000條,根據(jù)實際插入效率動態(tài)調(diào)整
POST _reindex?slices=auto&refresh&wait_for_completion=false { "conflicts": "proceed", "source": { "index": "log-zero-pro-202207-alias1", "size": 5000 }, "dest": { "index": "log-zero-pro-202207_re" } } 結果 { "task" : "iDnr1JBPRjyPVqwl2TcqqA:889565588" }
查詢異步遷移任務詳情
有兩個API可以調(diào)用,上面是查詢所有reindex任務,下面是查詢某個任務的詳情,一般用下面的查看任務是否完成
GET _tasks?detailed=true&actions=*reindex GET /_tasks/iDnr1JBPRjyPVqwl2TcqqA:889578807
調(diào)整正常索引配置
把之前的副本和刷新禁用重新打開
PUT /log-zero-pro-202206_re/_settings { "index" : { "number_of_replicas" : 1, "refresh_interval": "1s" } }
莫名想到了MySQL擴容,就順道來聊聊,擴容和重建索引不是一回事哈,不能直接對比。
MySQL擴容
當前已存在n臺數(shù)據(jù)庫,并且通過id取模。一般是m*n擴容m倍,這樣做元素遷移時比較方便,當然更建議一開始給足數(shù)據(jù)庫,盡量不要擴容,增加操作風險。擴容通常分為停機和不停機兩種,各有優(yōu)劣。
停機擴容
最簡單的方案,找個沒人的深夜停機,寫個程序讀取老的n臺數(shù)據(jù)庫,按照id重新取模輸入到新的m*n臺數(shù)據(jù)庫上,修改應用配置再重新上線。
回滾也方便,發(fā)現(xiàn)出問題,把配置修改為之前的,繼續(xù)用老數(shù)據(jù)庫,啥時候新的弄對了再遷過去。
優(yōu)點就是簡單明了,缺點就是費人,而且萬一運行了一段時間后發(fā)現(xiàn)搞錯了,只能回退到擴容前,會丟失部分數(shù)據(jù)。
不停機擴容
這個就相對復雜,假設現(xiàn)在有兩臺數(shù)據(jù)庫A和B,選擇兩倍擴容,也就是增加到四臺ABCD。
- A和C,B和D分別配置雙主同步,等待數(shù)據(jù)同步完成。
- 修改應用路由配置同時寫入ABCD四臺數(shù)據(jù)庫,取模規(guī)則變成四等分
- 刪除雙主同步,同時刪除四臺數(shù)據(jù)庫里的冗余數(shù)據(jù)(不屬于當前取模規(guī)則的數(shù)據(jù))
優(yōu)點很多啊,最重要的就是不停機,而且占用資源也少,原來兩臺數(shù)據(jù)庫也用上了?;貪L也簡單,只要不刪除冗余數(shù)據(jù),隨時都能切回來,直接修改取模規(guī)則即可。缺點就是比較復雜,雙主同步、雙寫,而且老數(shù)據(jù)庫較大的時候,擴容相當費時費力。
隨便聊聊
其實在做ES不停機重建索引的時候,我一開始是沒想到這么簡單的,居然幾條命令就搞定了,WTF。但是事實就是這樣,分布式架構面對單體架構的優(yōu)勢是碾壓式的,這也是我最近在看分布式數(shù)據(jù)庫TiDB的原因,遲早會遷移過去的。啥也不說,運維成本相對就低了,幾條命令就完成了,細節(jié)不用管還更有保障,排除了單體架構時人為原因,這可太爽了。
最后
最近有個問題難住我了,flink往es寫數(shù)據(jù)放在服務器上跑老是報錯,我這菜的還解決不了,少年痛苦祈禱中。回到ES,本次也算是再次加深了我對ES的認識,還可以,有所收獲。下一篇絕對是口語化系列了,這篇屬于臨時小插曲,大約2個晚上寫完,還算不錯。鴨梨很大,日子難過啊,啊啊啊啊啊,我一定要讓這痛苦壓抑的世界綻放幸??鞓分?。
以上就是ElasticSearch不停機重建索引延伸思考及優(yōu)化詳解的詳細內(nèi)容,更多關于ElasticSearch不停機重建索引的資料請關注腳本之家其它相關文章!
相關文章
Idea配置maven-tomcat-plugin插件實現(xiàn)項目部署
今天小編就為大家分享一篇關于Idea配置maven-tomcat-plugin插件實現(xiàn)項目部署,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-02-02