背景:
在JD.COM家庭訂單中心系統(tǒng)的業(yè)務(wù)中,無論是外部商家的訂單生產(chǎn)還是內(nèi)部上下游系統(tǒng)的依賴,訂單查詢的調(diào)用量都非常大,導(dǎo)致訂單數(shù)據(jù)讀多寫少的情況。從JD.COM到家里的訂單數(shù)據(jù)存儲在Mysql中,但顯然只通過數(shù)據(jù)庫支持大量查詢是不可取的。同時Mysql不夠友好,無法支持一些復(fù)雜的查詢,所以訂單中心系統(tǒng)使用彈性搜索來承擔訂單查詢的主要壓力。
彈性搜索作為一個強大的分布式搜索引擎,支持近實時的數(shù)據(jù)存儲和搜索,在JD.COM的家庭訂單系統(tǒng)中發(fā)揮著巨大的作用。目前,訂單中心的ES集群存儲了10億份文檔,平均每天的查詢量為5億。近年來,隨著JD.COM業(yè)務(wù)的快速發(fā)展,訂單中心的專家系統(tǒng)架設(shè)方案也在不斷發(fā)展。到目前為止,專家系統(tǒng)集群的建立是一種實時的互備份方案,保證了專家系統(tǒng)集群讀寫的穩(wěn)定性。下面簡單介紹一下這個過程和遇到的一些坑。
專家系統(tǒng)集群實施的演變:
1.初始階段:
訂單中心ES初期好到一張白紙,基本沒有實施方案。許多配置保持集群的默認配置。整個集群部署在群的彈性云上,es集群的節(jié)點和機器部署混亂。同時,按照集群維度,一個ES集群會出現(xiàn)單點問題,這對于訂單中心業(yè)務(wù)來說顯然是不允許的。
2.集群隔離階段:
與許多服務(wù)一樣,es集群采用混合分發(fā)的方式。但由于訂單中心es存儲在線訂單數(shù)據(jù),偶爾會有大量系統(tǒng)資源被混合集群搶占,導(dǎo)致整個訂單中心ES服務(wù)異常。
顯然,對訂單查詢穩(wěn)定性的任何影響都是不可容忍的。所以針對這種情況,首先對于訂單中心es所在的彈性云,將系統(tǒng)資源搶占度高的集群節(jié)點移出,ES集群情況略有改善。但是隨著集群數(shù)據(jù)的不斷增加,彈性云配置已經(jīng)不能滿足ES集群的要求。為了實現(xiàn)完全的物理隔離,最終將訂單中心的ES集群部署到高配置的物理機上,提高了ES集群的性能。
3.節(jié)點復(fù)制優(yōu)化階段:
ES的性能與硬件資源密切相關(guān)。當ES集群單獨部署到物理機上時,集群內(nèi)部的節(jié)點不會獨占整個物理機的資源,同一臺物理機上的節(jié)點在集群運行時仍然會存在資源搶占的問題。因此,在這種情況下,為了允許單個es節(jié)點使用最大的機器資源,每個ES節(jié)點被部署在單個物理機器上。
但是后來,問題又來了。單個節(jié)點出現(xiàn)瓶頸怎么辦?應(yīng)該怎么重新優(yōu)化?ES查詢的原理,當請求命中某個片段時,如果沒有為查詢指定片段類型(首選參數(shù)),請求將加載到片段號對應(yīng)的每個節(jié)點上。群集的默認副本配置是一個主服務(wù)器和一對服務(wù)器。鑒于此,我們想到了擴展副本的方法,從默認的一主一對,擴展到一主兩對,同時添加相應(yīng)的物理機。
上圖是訂單中心ES集群實現(xiàn)示意圖。整個實現(xiàn)方法使用VIP對外部請求進行負載均衡,第一層網(wǎng)關(guān)節(jié)點本質(zhì)上是es中的客戶端節(jié)點,相當于一個智能負載均衡器,起到分發(fā)請求的作用。第二層是數(shù)據(jù)節(jié)點,負責(zé)存儲數(shù)據(jù)和執(zhí)行數(shù)據(jù)相關(guān)操作。整個集群有一組主片和兩組次片(一個主片和兩個次片),從網(wǎng)關(guān)節(jié)點轉(zhuǎn)發(fā)的請求在到達數(shù)據(jù)節(jié)點之前將通過輪詢進行平衡。集群增加了一組副本,擴展了機器容量,增加了集群的吞吐量,從而提高了整個集群的查詢性能。下圖是訂單中心各階段ES集群性能示意圖,直觀展示了各階段優(yōu)化后ES集群性能的顯著提升。
當然,切片的數(shù)量和切片的份數(shù)都不是盡可能的好?,F(xiàn)階段,我們對選擇合適的切片數(shù)量進行了進一步的探索。片數(shù)可以理解為Mysql中的子數(shù)據(jù)庫和子表,而目前訂單中心的es查詢主要分為單ID查詢和分頁查詢兩類。碎片數(shù)量越大,簇水平擴展的規(guī)模越大,基于碎片路由的單ID查詢的吞吐量可以大大提高,但聚合分頁查詢的性能會降低。碎片數(shù)量越少,簇水平擴展的規(guī)模越小,單ID的查詢性能也會下降,但對于分頁查詢,性能會有所提高。因此,如何平衡碎片數(shù)量與現(xiàn)有的查詢服務(wù),我們做了很多調(diào)整和壓力測試,最終選擇了聚類性能更好的碎片數(shù)量。
4.主從集群調(diào)整階段:
至此,訂單中心的ES集群已經(jīng)初具規(guī)模。但是由于訂單中心業(yè)務(wù)的時效性要求較高,對ES查詢的穩(wěn)定性要求也較高。如果集群中有異常的節(jié)點,查詢服務(wù)會受到影響,從而影響整個訂單生產(chǎn)流程。顯然,這種異常情況是致命的,所以為了應(yīng)對這種情況,我們最初假設(shè)會增加一個備用集群,當主集群出現(xiàn)異常時,可以實時將查詢流量降級到備用集群。
備用集群應(yīng)該如何構(gòu)建?主備數(shù)據(jù)如何同步?備用集群應(yīng)該存儲什么樣的數(shù)據(jù)?考慮到ES集群暫時沒有好的主備方案,為了更好的控制ES數(shù)據(jù)的寫入,我們采用業(yè)務(wù)雙寫的方式構(gòu)建主備集群。每次業(yè)務(wù)操作需要寫ES數(shù)據(jù)時,同步寫主集群數(shù)據(jù),然后異步寫備用集群數(shù)據(jù)。同時,由于ES查詢流量大部分來自最近幾天的訂單,而且訂單中心數(shù)據(jù)庫中的數(shù)據(jù)有一套歸檔機制,所以在指定天數(shù)之前已經(jīng)關(guān)閉的訂單會被轉(zhuǎn)移到歷史訂單庫中。因此,在歸檔機制中增加了刪除備份集群文檔的邏輯,使得新建備份集群中存儲的訂單數(shù)據(jù)與訂單中心在線數(shù)據(jù)庫中的數(shù)據(jù)量一致。同時,ZK被用作查詢服務(wù)中的流量控制開關(guān),以確保查詢流可以實時降級到備份集群。這里完成了訂單中心的主從集群,ES查詢服務(wù)的穩(wěn)定性大大提高。
5.今天:實時相互備份雙集群階段:
在此期間,由于主集群的ES版本低于1.7,但是現(xiàn)在穩(wěn)定版的ES已經(jīng)迭代到6.x,新版本的ES不僅大大優(yōu)化了性能,還提供了一些新的、易用的功能,所以我們對主集群進行了一次升級,直接從原來的1.7升級到6.x,集群升級的過程繁瑣而漫長,不僅需要保證在線業(yè)務(wù)沒有影響,還需要在沒有感知的情況下順利升級。同時,由于ES集群暫時不支持跨多個版本從1.7到6.x的數(shù)據(jù)遷移,所以需要通過重建索引來升級主集群,具體的升級過程在此不再贅述。
升級時不可避免會出現(xiàn)主集群不可用的情況,但訂單中心的ES查詢服務(wù)不允許出現(xiàn)這種情況。因此,在升級階段,備用群集暫時充當主群集,以支持所有在線ES查詢,并確保升級過程不會影響正常的在線服務(wù)。同時,針對在線業(yè)務(wù),重新定義了兩個聚類,并對在線查詢流量進行了重新劃分。
備用集群存儲最近幾天的熱數(shù)據(jù),數(shù)據(jù)規(guī)模比主集群小很多,大約是主集群文檔的十分之一。集群數(shù)據(jù)量小。在相同的集群部署規(guī)模下,備用集群的性能優(yōu)于主集群。但是在真實的在線場景中,大部分的在線查詢流量也來自于熱數(shù)據(jù),所以用備用簇來承載這些熱數(shù)據(jù)的查詢,備用簇慢慢演變成熱數(shù)據(jù)簇。前一個主集群存儲全部數(shù)據(jù),用于支持剩余的一小部分查詢流量。這部分查詢主要是需要搜索訂單全額的特殊場景查詢和訂單中心系統(tǒng)內(nèi)部查詢等。,主集群慢慢演變成冷數(shù)據(jù)集群。
同時,備用集群增加了一鍵降級到主集群的功能。這兩個集群同等重要,但每個集群都可以降級為另一個集群。雙寫策略也優(yōu)化如下:假設(shè)有A B簇,正常同步模式下寫主(A簇),異步模式下寫備用(B簇)。集群a出現(xiàn)異常時,同步寫入集群b(主),異步寫入集群a(備用)。
專家系統(tǒng)訂單數(shù)據(jù)同步方案:
Mysql數(shù)據(jù)同步到ES,大致可以概括為兩種方案:
方案一:聽mysql的binlog,分析binlog,同步數(shù)據(jù)到ES集群
優(yōu)點:業(yè)務(wù)與es數(shù)據(jù)耦合度低,ES數(shù)據(jù)的寫入不需要業(yè)務(wù)邏輯上的關(guān)注
缺點:binglog模式只能使用ROW模式,并且引入了新的同步服務(wù),增加了開發(fā)量和維護成本,同時也增加了es同步的風(fēng)險
方案二:通過ES API直接將數(shù)據(jù)寫入ES集群
優(yōu)點:簡潔明了,數(shù)據(jù)寫入控制靈活
缺點:與業(yè)務(wù)耦合嚴重,強烈依賴業(yè)務(wù)系統(tǒng)的編寫模式
考慮到訂單系統(tǒng)中ES服務(wù)的業(yè)務(wù)特殊性,訂單數(shù)據(jù)的實時性較高。顯然,監(jiān)控binlog的方式相當于異步同步,可能會導(dǎo)致更大的延遲。方案1與方案2基本相似,但引入了新系統(tǒng),維護成本也增加了。因此,訂單中心ES采用直接通過ES API寫入訂單數(shù)據(jù)的方式,簡單靈活,能夠很好的滿足訂單中心數(shù)據(jù)同步到ES的需求。
由于ES訂單數(shù)據(jù)同步是在業(yè)務(wù)中寫入的,如果在創(chuàng)建或更新單據(jù)時出現(xiàn)異常,重試會影響正常業(yè)務(wù)操作的響應(yīng)時間。所以每個業(yè)務(wù)操作只更新es一次。如果出現(xiàn)錯誤或異常,向數(shù)據(jù)庫中插入一個補救任務(wù),一個工作任務(wù)將實時掃描數(shù)據(jù),并根據(jù)數(shù)據(jù)庫訂單數(shù)據(jù)再次更新ES數(shù)據(jù)。通過這種補償機制,可以保證ES數(shù)據(jù)和數(shù)據(jù)庫訂單數(shù)據(jù)的最終一致性。
遇到一些坑:
1.對實時性要求高的查詢轉(zhuǎn)到數(shù)據(jù)庫
如果你知道ES的寫入機制,你可能知道新添加的文檔會被收集到索引緩沖區(qū),然后寫入文件系統(tǒng)緩存,在那里它們可以像其他文件一樣被索引。但是默認情況下,從索引緩沖區(qū)到文件系統(tǒng)緩存的文檔(即刷新操作)是每秒自動按片刷新的,所以這就是為什么我們說es是接近實時搜索而不是實時的原因:文檔的變化對于搜索來說不是立即可見的,而是會在一秒鐘內(nèi)變得可見。目前訂單系統(tǒng)ES采用默認刷新配置,所以對于那些實時訂單數(shù)據(jù)較高的業(yè)務(wù),直接使用數(shù)據(jù)庫查詢來保證數(shù)據(jù)的準確性。
2.避免深度分頁查詢
ES集群的分頁查詢支持from和size參數(shù)。查詢時,每個片段必須構(gòu)造一個長度為from+size的優(yōu)先級隊列,然后將其發(fā)送回網(wǎng)關(guān)節(jié)點,網(wǎng)關(guān)節(jié)點再對這些優(yōu)先級隊列進行排序,找到大小正確的文檔。假設(shè)在一個有6個主片的索引中,from為10000,size為10,每個片必須產(chǎn)生10010個結(jié)果,在網(wǎng)關(guān)節(jié)點中合并60060個結(jié)果,最終找到10個滿足要求的文檔??梢钥闯觯攆rom足夠大時,即使OOM不發(fā)生,也會影響CPU和帶寬,從而影響整個集群的性能。所以要避免深度分頁查詢,盡量不要使用。
3.字段數(shù)據(jù)和文檔值
字段數(shù)據(jù):在線查詢偶爾超時。通過調(diào)試查詢語句,發(fā)現(xiàn)與排序有關(guān)。在es 1.x版本中,排序使用fielddata結(jié)構(gòu),占用jvm堆內(nèi)存,jvm內(nèi)存有限,所以會為fielddata cache設(shè)置一個閾值。如果空不足,則使用LRU算法刪除字段數(shù)據(jù),同時加載新的字段數(shù)據(jù)緩存,這將消耗系統(tǒng)資源并花費大量時間。因此,這個查詢的響應(yīng)時間飆升,甚至影響了整個集群的性能。為了解決這個問題,采用了doc值。
DOCVALUES: DOCVALUES是一種列數(shù)據(jù)存儲結(jié)構(gòu),類似于fieldata,但是存儲位置在Lucene文件中,也就是不占用JVM堆。隨著ES版本的迭代,doc值比fielddata更穩(wěn)定,doc值是從2開始的默認設(shè)置。x.
總結(jié):
架構(gòu)的快速迭代源于業(yè)務(wù)的快速發(fā)展,也正是因為近年來家庭業(yè)務(wù)的快速發(fā)展,訂單中心的架構(gòu)不斷優(yōu)化升級。但是架構(gòu)方案不是最好的,只有最適合的。相信幾年后,訂單中心的架構(gòu)會是另一張臉,但訂單中心系統(tǒng)永遠追求更大的吞吐量,更好的性能,更強的穩(wěn)定性。
1.《京東我的訂單查詢 京東到家訂單訂單查詢服務(wù)演進》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點,與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《京東我的訂單查詢 京東到家訂單訂單查詢服務(wù)演進》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉(zhuǎn)載時請保留本站內(nèi)容來源地址,http://f99ss.com/shehui/974088.html