Elasticsearch 是一個(gè)基于Lucene構(gòu)建的開源、分布式、RESTful接口的全文搜索引擎,其每個(gè)字段均可被索引,且能夠橫向擴(kuò)展至數(shù)以百計(jì)的服務(wù)器存儲(chǔ)以及處理TB級(jí)的數(shù)據(jù),其可以在極短的時(shí)間內(nèi)存儲(chǔ)、搜索和分析大量的數(shù)據(jù)。
滴滴ES發(fā)展至今,承接了公司絕大部分端上檢索和日志場(chǎng)景,包括地圖POI檢索、訂單檢索、客服、內(nèi)搜及把脈ELK場(chǎng)景等。
近幾年圍繞穩(wěn)定性、成本、效率和數(shù)據(jù)安全這幾個(gè)方向持續(xù)探索:
滴滴ES有很多在線P0級(jí)檢索場(chǎng)景,為了提升集群穩(wěn)定性,我們自研了跨數(shù)據(jù)中心復(fù)制能力,實(shí)現(xiàn)多機(jī)房數(shù)據(jù)寫入強(qiáng)一致性,并配合管控平臺(tái)讓ES支持多活能力;
為了提升查詢性能和解決查詢毛刺問題,我們?cè)?.6版本上原地升級(jí)支持JDK 17;
ES日志場(chǎng)景每天寫入量在5PB-10PB量級(jí),寫入壓力和業(yè)務(wù)成本壓力大,為了提升ES的寫入性能,我們讓ES支持ZSTD壓縮算法;
由于ES索引里包含很多敏感數(shù)據(jù),我們又完善了ES的安全認(rèn)證能力。
基于以上探索,我們總結(jié)了一定的經(jīng)驗(yàn),現(xiàn)分成4篇文章詳細(xì)介紹。本篇文章介紹滴滴ES如何實(shí)現(xiàn)索引的跨數(shù)據(jù)中心復(fù)制從而保證索引的高可用。
滴滴跨數(shù)據(jù)中心復(fù)制能力 - Didi Cross Datacenter Replication,由滴滴自研,簡稱DCDR,它能夠?qū)?shù)據(jù)從一個(gè) Elasticsearch 集群原生復(fù)制到另一個(gè) Elasticsearch 集群。如圖所示,DCDR工作在索引模板或索引層面,采用主從索引設(shè)計(jì)模型,由Leader索引主動(dòng)將數(shù)據(jù)push到Follower索引,從而保證了主從索引數(shù)據(jù)的強(qiáng)一致性。
DCDR跨數(shù)據(jù)中心復(fù)制能力圖
DCDR在滴滴內(nèi)部的主要生產(chǎn)應(yīng)用如下:
災(zāi)難恢復(fù)(DR)/高可用性(HA):如果主集群發(fā)生故障,能夠通過切換主從集群快速恢復(fù),從而實(shí)現(xiàn)異地多活
索引遷移:索引可以在不同集群間遷移,保證集群間的數(shù)據(jù)均衡,同時(shí)實(shí)現(xiàn)索引在集群級(jí)別的分級(jí)保障
主從查詢隔離:由于主從索引的強(qiáng)一致性保證,配合自研ES Admin管控平臺(tái),不同業(yè)務(wù)方可以查詢不同的集群,避免相互之間的查詢影響? ? ? ? ?
背景及目標(biāo)
原生的Elasticsearch提供了集群內(nèi)部的高可用,能夠保證集群內(nèi)部的數(shù)據(jù)可靠性。但這種高可用無法滿足對(duì)可靠性有進(jìn)一步需求的用戶。原生Elasticsearch主要有以下痛點(diǎn):
對(duì)于數(shù)據(jù)中心級(jí)別故障無法實(shí)現(xiàn)快速恢復(fù)
數(shù)據(jù)在集群間搬遷成本很高,需借助外部工具來完成多個(gè)復(fù)雜操作
最初,滴滴內(nèi)部應(yīng)對(duì)跨數(shù)據(jù)中心的高可用,借助了外部同步平臺(tái)將數(shù)據(jù)雙寫到不同集群來實(shí)現(xiàn)。該方式依賴較重,不支持歷史數(shù)據(jù)同步,并且無法保證主從索引數(shù)據(jù)的強(qiáng)一致性。隨著外部平臺(tái)的收斂,雙寫的方式已經(jīng)無法使用。ES 官方在6.7.0版本提供了跨集群數(shù)據(jù)復(fù)制功能,該功能需付費(fèi)且只能保證主從索引數(shù)據(jù)的最終一致性。滴滴內(nèi)部核心業(yè)務(wù),如POI檢索(滴滴APP上下車地點(diǎn)檢索服務(wù))、訂單檢索業(yè)務(wù),都要求主從索引數(shù)據(jù)強(qiáng)一致性。
為解決上述問題,滿足業(yè)務(wù)方訴求,滴滴ES團(tuán)隊(duì)決定自研跨數(shù)據(jù)中心復(fù)制能力,即上文的DCDR。
DCDR在設(shè)計(jì)時(shí)主要有以下幾個(gè)目標(biāo):
保證主從數(shù)據(jù)的強(qiáng)一致性
保證高可用性,快速實(shí)現(xiàn)災(zāi)難恢復(fù)
實(shí)現(xiàn)不停機(jī)跨集群索引遷移
可靠的版本升級(jí)(Elasticsearch的Rolling upgrades和Full cluster restart upgrade方案都無法做到升級(jí)后回滾)
技術(shù)基礎(chǔ)
DCDR功能支持將遠(yuǎn)程集群中的索引復(fù)制到本地集群,在復(fù)制過程中需要考慮兩個(gè)重點(diǎn):實(shí)時(shí)數(shù)據(jù)的同步、歷史數(shù)據(jù)的同步。實(shí)時(shí)數(shù)據(jù)同步依賴ES寫入機(jī)制,數(shù)據(jù)同步依賴ES副本恢復(fù)機(jī)制。因此,在介紹DCDR的方案設(shè)計(jì)以及實(shí)現(xiàn)細(xì)節(jié)之前,對(duì)這兩個(gè)流程簡單概述:
基本寫入機(jī)制
ES寫入是先寫主分片,主分片寫完后再將請(qǐng)求并行轉(zhuǎn)發(fā)到副本,副本處理完再由主分片返回寫入結(jié)果,具體流程如下:(注:本文中Si代表ES具體分片,P代表主分片,R代表副本)? ? ? ?
副本恢復(fù)流程
為了保證數(shù)據(jù)副本的一致性,副本的數(shù)據(jù)需要恢復(fù)到和主分片一致才能正常對(duì)外提供服務(wù)。ES的副本恢復(fù)是分片級(jí)別的,分為主分片恢復(fù)流程和副分片恢復(fù)流程。由于ES的副本恢復(fù)流程極為復(fù)雜,并且DCDR的數(shù)據(jù)恢復(fù)過程中僅與副分片恢復(fù)流程相關(guān),因此這里只簡單地介紹下副分片恢復(fù)流程。
副本recovery的目標(biāo)是要將本地?cái)?shù)據(jù)恢復(fù)到和主分片一致,主流程分為兩個(gè)階段:
階段一是主分片給副本發(fā)送segment文件(存儲(chǔ)的是已經(jīng)落盤并解析后的具體數(shù)據(jù))
階段二是主分片向副本發(fā)送translog日志(未落盤的數(shù)據(jù),類似mysql 的WAL Log),兩階段結(jié)束后副本的恢復(fù)流程就結(jié)束了
具體流程如下圖:? ? ?
方案設(shè)計(jì)
設(shè)計(jì)思想
DCDR的核心思想是將從索引對(duì)應(yīng)分片看做主索引對(duì)應(yīng)分片的一個(gè)遠(yuǎn)程副本來處理。如下圖,從索引的shard0主分片,會(huì)被當(dāng)做主索引shard0主分片的一個(gè)遠(yuǎn)程副本。? ? ? ? ?? ?
為了讓大家更好地理解這個(gè)思路,簡單介紹下遠(yuǎn)程副本:遠(yuǎn)程副本是由ES數(shù)據(jù)副本模型延伸而來,由主索引的主分片保存遠(yuǎn)程副本相關(guān)元數(shù)據(jù),在實(shí)現(xiàn)上借鑒了微軟的PacificA算法。該設(shè)計(jì)思想符合ES數(shù)據(jù)副本模型,能夠極大程度地復(fù)用ES副本邏輯,降低開發(fā)難度,減少對(duì)開源ES內(nèi)核的侵入。
以下是該算法的部分核心術(shù)語和ES數(shù)據(jù)副本模型的對(duì)應(yīng)關(guān)系:
具體方案設(shè)計(jì)
DCDR是跨集群數(shù)據(jù)復(fù)制能力,實(shí)現(xiàn)該功能的第一步就是需要明確哪些索引模板或者索引需要進(jìn)行數(shù)據(jù)的跨集群復(fù)制,也就是需要建立起DCDR鏈路。其次,DCDR的從索引作為一個(gè)遠(yuǎn)程副本,需要恢復(fù)到和主索引的數(shù)據(jù)一致才能正常提供服務(wù),即歷史數(shù)據(jù)恢復(fù)。從索引的數(shù)據(jù)恢復(fù)到和主索引一致,當(dāng)主索引新增數(shù)據(jù)時(shí),數(shù)據(jù)該如何寫入從索引,即實(shí)時(shí)數(shù)據(jù)同步。經(jīng)過以上環(huán)節(jié),從索引就能夠正常提供服務(wù),那么如何保證數(shù)據(jù)的可靠性呢?這就涉及到了主從索引數(shù)據(jù)質(zhì)量校驗(yàn)。
基于以上思考,整個(gè)DCDR的方案設(shè)計(jì)上分為四個(gè)主流程:
1、DCDR鏈路構(gòu)建
ES集群是基于集群狀態(tài)驅(qū)動(dòng)的,因此DCDR鏈路構(gòu)建的本質(zhì)就是改變集群狀態(tài),并在對(duì)應(yīng)機(jī)器上應(yīng)用新的集群狀態(tài)。滴滴內(nèi)部的ES使用方式是索引模板形式(一組擁有相同前綴的索引集合),因此在鏈路設(shè)計(jì)上需要支持模板鏈路和索引鏈路。DCDR鏈路集群元信息通過ES cluster state自定義metaData實(shí)現(xiàn),鏈路擁有統(tǒng)一的命名規(guī)則,并且區(qū)分模板和索引,主要信息展示如下:
模板鏈路:
{
"templates": {
"templateA_to_ClusterA": {
"name": "IndexA_to_ClusterA", // dcdr模板鏈路名
"template": "templateA", // 索引模板名
"replica_cluster": "ClusterA" // 從集群名稱
}
}
}
索引鏈路:
{
"Index_202206/Index_202206(ClusterA)": {
"primary_index": "Index_202206", // 主索引名稱
"replica_index": "Index_202206", // 從索引名稱
"replica_cluster": "ClusterA", // 從集群名稱
"replication_state": true // 鏈路狀態(tài)
}
}
ES集群對(duì)外提供了DCDR鏈路創(chuàng)建API,通過API將鏈路元信息更新到集群狀態(tài)中,DCDR相關(guān)模塊通過訂閱集群狀態(tài)變更事件,從而進(jìn)入數(shù)據(jù)同步流程。如下圖:? ? ? ? ?
有個(gè)設(shè)計(jì)細(xì)節(jié)需要注意:
Q:主從索引名是一致的,那么主從索引的唯一標(biāo)識(shí)UUID(集群建索引后自動(dòng)生成的隨機(jī)字符串)要怎么處理呢?
綜合考慮開發(fā)難度和源碼侵入問題,主從索引的索引名和UUID都保持一致
在從索引創(chuàng)建時(shí)透?jìng)髦魉饕腢UID到從集群,從索引在創(chuàng)建索引時(shí)不再自動(dòng)生成UUID,解決從索引創(chuàng)建UUID不一致問題
由于ES墓地會(huì)暫時(shí)保存被刪除的索引,因此在從索引創(chuàng)建時(shí)掃描ES墓地并刪除UUID相同的索引,解決從索引刪除后無法重建問題
2、歷史數(shù)據(jù)恢復(fù)
歷史數(shù)據(jù)恢復(fù)方案在設(shè)計(jì)上借鑒了ES副本恢復(fù)策略。DCDR從索引的副本恢復(fù)同樣是分片級(jí)別的,也需要進(jìn)行segement和translog的復(fù)制環(huán)節(jié)。歷史數(shù)據(jù)恢復(fù)發(fā)生的條件:
新建DCDR鏈路,從索引需要根據(jù)主索引進(jìn)行歷史數(shù)據(jù)恢復(fù)
從索引分片數(shù)據(jù)寫入失敗,主索引定時(shí)任務(wù)重建DCDR鏈路? ? ? ?
從索引作為遠(yuǎn)程副本在歷史數(shù)據(jù)恢復(fù)方面和ES的副本恢復(fù)流程基本是一致的,主要區(qū)別(圖中綠色標(biāo)記)在于第1步的數(shù)據(jù)恢復(fù)觸發(fā)條件,以及第6步加入的副本組不同。同時(shí)要注意以下設(shè)計(jì)細(xì)節(jié):
Q:怎么觸發(fā)歷史數(shù)據(jù)的恢復(fù)?
ES的副本恢復(fù)是由集群狀態(tài)變更事件驅(qū)動(dòng)的,從索引的恢復(fù)是跨集群的,因此只能依靠主集群的RPC調(diào)用觸發(fā)從集群的DCDR歷史數(shù)據(jù)恢復(fù)。
Q:ES分片恢復(fù)是個(gè)很耗時(shí)的階段,如何提高從索引的分片恢復(fù)效率,使得從索引能夠快速提供服務(wù)?
從索引只需要恢復(fù)自身的主分片數(shù)據(jù),之后DCDR從索引歷史數(shù)據(jù)恢復(fù)結(jié)束,從索引就能正常接收主索引的寫請(qǐng)求了。從索引自身的副本恢復(fù)依賴于從集群的ES副本機(jī)制即可。這樣能夠極大地降低DCDR鏈路歷史數(shù)據(jù)恢復(fù)時(shí)間。
Q:從索引什么時(shí)候可以正常接收主索引的寫請(qǐng)求呢?
ES副本會(huì)在主分片phase1結(jié)束,副本啟動(dòng)Engine后加入主分片副本組,開始接收主分片的寫請(qǐng)求。從索引的恢復(fù)也是類似的,從索引的主分片作為主索引對(duì)應(yīng)主分片的遠(yuǎn)程副本,也會(huì)在主索引主分片phase1結(jié)束后,自身Engine啟動(dòng)后,由主索引的對(duì)應(yīng)主分片加入遠(yuǎn)程副本組,開始接收寫請(qǐng)求。
遠(yuǎn)程副本組的實(shí)現(xiàn)是在ES的ReplicationGroup類中增加一個(gè)遠(yuǎn)程的prepared list。
Q:DCDR歷史數(shù)據(jù)恢復(fù)過程中,主索引的主分片能否遷移?
分片搬遷是集群均衡的一種手段,由于DCDR的恢復(fù)是跨集群的,無法通過集群狀態(tài)變更快速地感知到分片遷移并進(jìn)行處理。因此,主分片不能遷移。在DCDR數(shù)據(jù)恢復(fù)過程中,會(huì)通過加鎖的方式防止主分片遷移。
3、實(shí)時(shí)數(shù)據(jù)同步
實(shí)時(shí)數(shù)據(jù)同步指的是歷史數(shù)據(jù)同步完成后,增量數(shù)據(jù)如何同步到從索引。根據(jù)前文的ES寫入流程可知,ES寫入是先寫主分片,之后再將寫請(qǐng)求同步轉(zhuǎn)發(fā)到副本上?;诘蔚蝺?nèi)部業(yè)務(wù)場(chǎng)景考慮,需要異地多活的業(yè)務(wù)數(shù)據(jù)寫入量一般不大,遠(yuǎn)未達(dá)到ES的寫入瓶頸,并且一些核心業(yè)務(wù)對(duì)數(shù)據(jù)一致性有強(qiáng)依賴。因此,DCDR在實(shí)時(shí)數(shù)據(jù)同步上采用主分片寫入成功,將數(shù)據(jù)同步轉(zhuǎn)發(fā)給副本以及遠(yuǎn)程副本這一方案。該方案犧牲一定的數(shù)據(jù)寫入性能,從而保證了數(shù)據(jù)的強(qiáng)一致性。
實(shí)時(shí)數(shù)據(jù)同步策略采用的是將寫請(qǐng)求轉(zhuǎn)發(fā)到遠(yuǎn)程副本實(shí)現(xiàn)的,仍然有許多細(xì)節(jié)需要考慮:
Q:遠(yuǎn)程副本寫入失敗怎么辦?
ES副本寫入失敗的處理策略是將副本從同步副本組移除,并重新執(zhí)行Recovery。遠(yuǎn)程副本寫入失敗的處理策略和ES副本寫入失敗處理策略類似,是將遠(yuǎn)程副本從主索引主分片的遠(yuǎn)程副本組中移除,主索引將不再轉(zhuǎn)發(fā)寫請(qǐng)求到從索引,由從索引的定時(shí)檢查機(jī)制重新執(zhí)行數(shù)據(jù)恢復(fù)流程。
Q:從索引的seq_num(每條請(qǐng)求遞增的唯一ID,用來加快副本恢復(fù)流程的)如何保證主從一致?
從索引的分片采用了自定義的Engine,該Engine能夠直接接收主索引傳過來的seq_num,不再生成seq_num值。
Q:主從mapping如何保證一致?要更新mapping時(shí)怎么處理?
新建DCDR鏈路時(shí)會(huì)將主索引的mapping拷貝到從集群,并新建從索引,保證鏈路新建時(shí)主從索引的mapping是一致的。
DCDR的設(shè)計(jì)思想是遠(yuǎn)程副本策略,是將寫請(qǐng)求直接轉(zhuǎn)發(fā)給從索引。因此,后期如果出現(xiàn)需要更新mapping的字段,會(huì)由主從集群各自的master去執(zhí)行master任務(wù)去更新mapping即可(主從master mapping更新處理策略一致)。
4、主從索引數(shù)據(jù)質(zhì)量校驗(yàn)
數(shù)據(jù)質(zhì)量校驗(yàn)環(huán)節(jié)是從索引數(shù)據(jù)可靠性的保障。它會(huì)定時(shí)檢查集群狀態(tài)中的DCDR元信息是否和當(dāng)前鏈路運(yùn)行狀態(tài)一致,根據(jù)結(jié)果對(duì)鏈路進(jìn)行相應(yīng)的操作。當(dāng)主從索引數(shù)據(jù)差距過大或鏈路異常時(shí),主集群會(huì)主動(dòng)斷開鏈路,并通知從索引進(jìn)行差量數(shù)據(jù)恢復(fù)。ES集群中,MasterNode負(fù)責(zé)管控集群元數(shù)據(jù),因此在設(shè)計(jì)校驗(yàn)任務(wù)時(shí),主要用于鏈路元數(shù)據(jù)創(chuàng)建及檢查從索引是否存在;DataNode負(fù)責(zé)數(shù)據(jù)存儲(chǔ),因此用于判斷主從分片是否需要進(jìn)行數(shù)據(jù)恢復(fù)。? ?
5、其他
經(jīng)過以上4個(gè)環(huán)節(jié)就能將數(shù)據(jù)從一個(gè) Elasticsearch 集群原生復(fù)制到另一個(gè) Elasticsearch 集群,搭配上主從切換策略,就能在保證數(shù)據(jù)強(qiáng)一致性的前提下實(shí)現(xiàn)跨集群高可用。對(duì)于不停機(jī)跨集群索引遷移這一目標(biāo),我們通過DCDR將數(shù)據(jù)同步到目的端集群,等待存量數(shù)據(jù)恢復(fù)完成,再進(jìn)行一次主從切換。對(duì)于可靠的版本升級(jí)這一目標(biāo),我們通過DCDR復(fù)制待升級(jí)版本數(shù)據(jù)到備用集群,當(dāng)版本升級(jí)異常時(shí)能夠快速切換集群。
總結(jié)文章來源:http://www.zghlxwxcb.cn/news/detail-636448.html
目前滴滴ES共有6個(gè)DCDR從集群,建立的DCDR模板鏈路400+,DCDR索引鏈路2000+,涵蓋了POI、dos_order、soda等滴滴核心業(yè)務(wù)。目前ES仍然存在查詢毛刺、查詢相互影響、分片恢復(fù)、寫入性能等方面問題,后續(xù)我們會(huì)在這些方面重點(diǎn)發(fā)力,更好的助力業(yè)務(wù)發(fā)展。文章來源地址http://www.zghlxwxcb.cn/news/detail-636448.html
到了這里,關(guān)于探索ES高可用:滴滴自研跨數(shù)據(jù)中心復(fù)制技術(shù)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!