成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

日均5億查詢量,京東到家訂單中心的ES架構演進

開發 架構 開發工具
京東到家訂單中心系統業務中,無論是外部商家的訂單生產,或是內部上下游系統的依賴,訂單查詢的調用量都非常大,造成了訂單數據讀多寫少的情況。

京東到家訂單中心系統業務中,無論是外部商家的訂單生產,或是內部上下游系統的依賴,訂單查詢的調用量都非常大,造成了訂單數據讀多寫少的情況。

[[255762]]

我們把訂單數據存儲在 MySQL 中,但顯然只通過 DB 來支撐大量的查詢是不可取的。

同時對于一些復雜的查詢,MySQL 支持得不夠友好,所以訂單中心系統使用了 Elasticsearch 來承載訂單查詢的主要壓力。

Elasticsearch 作為一款功能強大的分布式搜索引擎,支持近實時的存儲、搜索數據,在京東到家訂單系統中發揮著巨大作用,目前訂單中心 ES 集群存儲數據量達到 10 億個文檔,日均查詢量達到 5 億。

隨著京東到家近幾年業務的快速發展,訂單中心 ES 架設方案也不斷演進,發展至今 ES 集群架設是一套實時互備方案,很好地保障了 ES 集群讀寫的穩定性,下面就給大家介紹一下這個歷程以及發展過程中遇到的一些坑。

ES 集群架設演進歷程

初始階段

訂單中心 ES 初始階段如一張白紙,架設方案基本沒有,很多配置都是保持集群默認配置。整個集群部署在集團的彈性云上,ES 集群的節點以及機器部署都比較混亂。

同時按照集群維度來看,一個 ES 集群會有單點問題,顯然對于訂單中心業務來說也是不被允許的。

集群隔離階段

和很多業務一樣,ES 集群采用的混布的方式。但由于訂單中心 ES 存儲的是線上訂單數據,偶爾會發生混布集群搶占系統大量資源,導致整個訂單中心 ES 服務異常。

顯然任何影響到訂單查詢穩定性的情況都是無法容忍的,所以針對這個情況,先是對訂單中心 ES 所在的彈性云,遷出那些系統資源搶占很高的集群節點,ES 集群狀況稍有好轉。

但隨著集群數據不斷增加,彈性云配置已經不太能滿足 ES 集群,且為了完全的物理隔離,最終干脆將訂單中心 ES 集群部署到高配置的物理機上,ES 集群性能又得到提升。

節點副本調優階段

ES 的性能跟硬件資源有很大關系,當 ES 集群單獨部署到物理機器上時,集群內部的節點并不是獨占整臺物理機資源,在集群運行的時候同一物理機上的節點仍會出現資源搶占的問題。

所以在這種情況下,為了讓 ES 單個節點能夠使用最大程度的機器資源,采用每個 ES 節點部署在單獨一臺物理機上的方式。

但緊接著,問題又來了,如果單個節點出現瓶頸了呢?我們應該怎么再優化呢?

ES 查詢的原理,當請求打到某號分片的時候,如果沒有指定分片類型(Preference 參數)查詢,請求會負載到對應分片號的各個節點上。

而集群默認副本配置是一主一副,針對此情況,我們想到了擴容副本的方式,由默認的一主一副變為一主二副,同時增加相應物理機。

訂單中心 ES 集群架設示意圖

如圖,整個架設方式通過 VIP 來負載均衡外部請求:

  • 第一層 Gateway 節點實質為 ES 中 Client Node,相當于一個智能負載均衡器,充當著分發請求的角色。
  • 第二層為 Data Node,負責存儲數據以及執行數據的相關操作。

整個集群有一套主分片,二套副分片(一主二副),從網關節點轉發過來的請求,會在打到數據節點之前通過輪詢的方式進行均衡。

集群增加一套副本并擴容機器的方式,增加了集群吞吐量,從而提升了整個集群查詢性能。

下圖為訂單中心 ES 集群各階段性能示意圖,直觀地展示了各階段優化后 ES 集群性能的顯著提升:

當然分片數量和分片副本數量并不是越多越好,在此階段,我們對選擇適當的分片數量做了進一步探索。

分片數可以理解為 MySQL 中的分庫分表,而當前訂單中心 ES 查詢主要分為兩類:

  • 單 ID 查詢
  • 分頁查詢

分片數越大,集群橫向擴容規模也更大,根據分片路由的單 ID 查詢吞吐量也能大大提升,但聚合的分頁查詢性能則將降低。

分片數越小,集群橫向擴容規模也更小,單 ID 的查詢性能也會下降,但分頁查詢的性能將會提升。

所以如何均衡分片數量和現有查詢業務,我們做了很多次調整壓測,最終選擇了集群性能較好的分片數。

主從集群調整階段

到此,訂單中心的 ES 集群已經初具規模,但由于訂單中心業務時效性要求高,對 ES 查詢穩定性要求也高,如果集群中有節點發生異常,查詢服務會受到影響,從而影響到整個訂單生產流程。

很明顯這種異常情況是致命的,所以為了應對這種情況,我們初步設想是增加一個備用集群,當主集群發生異常時,可以實時的將查詢流量降級到備用集群。

那備用集群應該怎么來搭?主備之間數據如何同步?備用集群應該存儲什么樣的數據?

考慮到 ES 集群暫時沒有很好的主備方案,同時為了更好地控制 ES 數據寫入,我們采用業務雙寫的方式來搭設主備集群。

每次業務操作需要寫入 ES 數據時,同步寫入主集群數據,然后異步寫入備集群數據。

同時由于大部分 ES 查詢的流量都來源于近幾天的訂單,且訂單中心數據庫數據已有一套歸檔機制,將指定天數之前已經關閉的訂單轉移到歷史訂單庫。

所以歸檔機制中增加刪除備集群文檔的邏輯,讓新搭建的備集群存儲的訂單數據與訂單中心線上數據庫中的數據量保持一致。

同時使用 ZK 在查詢服務中做了流量控制開關,保證查詢流量能夠實時降級到備集群。在此,訂單中心主從集群完成,ES 查詢服務穩定性大大提升。

現今:實時互備雙集群階段

期間由于主集群 ES 版本是較低的 1.7,而現今 ES 穩定版本都已經迭代到 6.x,新版本的 ES 不僅性能方面優化很大,更提供了一些新的好用的功能。

所以我們對主集群進行了一次版本升級,直接從原來的 1.7 升級到 6.x 版本。

集群升級的過程繁瑣而漫長,不但需要保證線上業務無任何影響,平滑無感知升級。

同時由于 ES 集群暫不支持從 1.7 到 6.x 跨越多個版本的數據遷移,所以需要通過重建索引的方式來升級主集群,具體升級過程就不在此贅述了。

主集群升級的時候必不可免地會發生不可用的情況,但對于訂單中心 ES 查詢服務,這種情況是不允許的。

所以在升級的階段中,備集群暫時頂上充當主集群,來支撐所有的線上 ES 查詢,保證升級過程不影響正常線上服務。

同時針對于線上業務,我們對兩個集群做了重新的規劃定義,承擔的線上查詢流量也做了重新的劃分。

備集群存儲的是線上近幾天的熱點數據,數據規模遠小于主集群,大約是主集群文檔數的十分之一。集群數據量小,在相同的集群部署規模下,備集群的性能要優于主集群。

然而在線上真實場景中,線上大部分查詢流量也來源于熱點數據,所以用備集群來承載這些熱點數據的查詢,而備集群也慢慢演變成一個熱數據集群。

之前的主集群存儲的是全量數據,用該集群來支撐剩余較小部分的查詢流量,這部分查詢主要是需要搜索全量訂單的特殊場景查詢以及訂單中心系統內部查詢等,而主集群也慢慢演變成一個冷數據集群。

同時備集群增加一鍵降級到主集群的功能,兩個集群地位同等重要,但都可以各自降級到另一個集群。

雙寫策略也優化為:假設有 AB 集群,正常同步方式寫主(A 集群),異步方式寫備(B 集群)。A 集群發生異常時,同步寫 B 集群(主),異步寫 A 集群(備)。

ES 訂單數據的同步方案

MySQL 數據同步到 ES 中,大致總結可以分為兩種方案。

方案 1

監聽 MySQL 的 Binlog,分析 Binlog 將數據同步到 ES 集群中:

優點:業務與 ES 數據耦合度低,業務邏輯中不需要關心 ES 數據的寫入。

缺點:Binlog 模式只能使用 ROW 模式,且引入了新的同步服務,增加了開發量以及維護成本,也增大了 ES 同步的風險。

方案 2

直接通過 ES API 將數據寫入到 ES 集群中:

  • 優點:簡潔明了,能夠靈活的控制數據的寫入。
  • 缺點:與業務耦合嚴重,強依賴于業務系統的寫入方式。

考慮到訂單系統 ES 服務的業務特殊性,對于訂單數據的實時性較高,顯然監聽 Binlog 的方式相當于異步同步,有可能會產生較大的延時性。且方案 1 實質上跟方案 2 類似,但又引入了新的系統,維護成本也增高。

所以訂單中心 ES 采用了直接通過 ES API 寫入訂單數據的方式,該方式簡潔靈活,能夠很好的滿足訂單中心數據同步到 ES 的需求。

由于 ES 訂單數據的同步采用的是在業務中寫入的方式,當新建或更新文檔發生異常時,如果重試勢必會影響業務正常操作的響應時間。

所以每次業務操作只更新一次 ES,如果發生錯誤或者異常,在數據庫中插入一條補救任務,有 Worker 任務會實時地掃這些數據,以數據庫訂單數據為基準來再次更新 ES 數據。

通過此種補償機制,來保證 ES 數據與數據庫訂單數據的最終一致性。

遇到的一些坑

實時性要求高的查詢走 DB

對于 ES 的寫入機制有了解的同學可能會知道,新增的文檔會被收集到 Indexing Buffer,然后寫入到文件系統緩存中,到了文件系統緩存中就可以像其他的文件一樣被索引到。

然而默認情況文檔從 Indexing Buffer 到文件系統緩存(即 Refresh 操作)是每秒分片自動刷新。

所以這就是我們說 ES 是近實時搜索而非實時的原因:文檔的變化并不是立即對搜索可見,但會在一秒之內變為可見。

當前訂單系統 ES 采用的是默認 Refresh 配置,故對于那些訂單數據實時性比較高的業務,直接走數據庫查詢,保證數據的準確性。

避免深分頁查詢

ES 集群的分頁查詢支持 from 和 size 參數,查詢的時候,每個分片必須構造一個長度為 from+size 的優先隊列,然后回傳到網關節點,網關節點再對這些優先隊列進行排序找到正確的 size 個文檔。

假設在一個有 6 個主分片的索引中,from 為 10000,size 為 10,每個分片必須產生 10010 個結果,在網關節點中匯聚合并 60060 個結果,最終找到符合要求的 10 個文檔。

由此可見,當 from 足夠大的時候,就算不發生 OOM,也會影響到 CPU 和帶寬等,從而影響到整個集群的性能。所以應該避免深分頁查詢,盡量不去使用。

FieldData 與 Doc Values

FieldData

線上查詢出現偶爾超時的情況,通過調試查詢語句,定位到是跟排序有關系。

排序在 es1.x 版本使用的是 FieldData 結構,FieldData 占用的是 JVM Heap 內存,JVM 內存是有限,對于 FieldData Cache 會設定一個閾值。

如果空間不足時,使用最久未使用(LRU)算法移除 FieldData,同時加載新的 FieldData Cache,加載的過程需要消耗系統資源,且耗時很大。

所以導致這個查詢的響應時間暴漲,甚至影響整個集群的性能。針對這種問題,解決方式是采用 Doc Values。

Doc Values

Doc Values 是一種列式的數據存儲結構,跟 FieldData 很類似,但其存儲位置是在 Lucene 文件中,即不會占用 JVM Heap。

隨著 ES 版本的迭代,Doc Values 比 FieldData 更加穩定,Doc Values 在 2.x 起為默認設置。

總結

架構的快速迭代源于業務的快速發展,正是由于近幾年到家業務的高速發展,訂單中心的架構也不斷優化升級。

而架構方案沒有最好的,只有最合適的,相信再過幾年,訂單中心的架構又將是另一個面貌,但吞吐量更大,性能更好,穩定性更強,將是訂單中心系統永遠的追求。 

 

責任編輯:武曉燕 來源: 京東技術
相關推薦

2019-01-02 14:55:54

MySQLES數據庫

2019-08-30 12:30:25

京東到家訂單查詢數據存儲

2018-12-20 06:04:02

京東到家訂單中心Elasticsear

2019-11-01 15:50:06

MySQLES搜索引擎

2018-11-06 14:05:27

京東訂單派發架構

2019-01-14 09:06:40

LBS定位系統架構

2017-12-12 08:40:00

2018-04-20 09:36:23

NettyWebSocket京東

2020-05-12 11:25:50

MySQLES數據庫

2022-02-12 20:51:23

京東程序員代碼

2020-09-02 07:32:19

數據架構訂單中心架構

2019-05-22 09:31:01

MySQL架構高可用

2021-03-18 14:34:34

達達集團京東云電商

2015-12-09 15:16:03

架構師京東架構

2020-06-19 09:38:14

交易量MySQL架構

2020-09-16 09:08:49

訂單微服務架構

2023-02-09 07:38:39

配置中心架構組件

2023-12-11 21:52:52

數據中心架構數字時代

2024-06-18 08:07:50

存儲架構設計

2022-02-14 08:13:33

刪庫MySQL備份
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品一区二区久久久久久久网站 | 9porny九色视频自拍 | 一区二区三区视频播放 | 欧美日韩精品 | 亚洲国产欧美精品 | 91久久精品一区二区二区 | 欧美 日韩 亚洲91麻豆精品 | 久久久久久久久久久久久九 | 伊人免费观看视频 | 日韩不卡一区二区 | www.黄色在线观看 | 91一区二区| 亚洲一区二区精品 | 在线免费观看日本 | 九九热国产精品视频 | 精品精品视频 | 艹逼网| 国产一区二区影院 | 精品国产精品 | 亚州激情| 黄久久久 | 嫩草视频在线 | 色综合久久久久 | 九九热这里 | a级免费观看视频 | 天天操天天干天天爽 | 午夜影院操 | 国产一区2区 | 久久综合久久自在自线精品自 | 香蕉久久网 | 天堂网中文字幕在线观看 | 久久久.com | av影音资源 | 国产7777| 久久久久午夜 | 久久免费视频在线 | 亚洲一二三区不卡 | 久久中文一区二区 | 51ⅴ精品国产91久久久久久 | www国产成人免费观看视频,深夜成人网 | 国产精品久久九九 |