1. 程式人生 > >京東618:一箇中心五個原則,談談物流系統的大促優化實踐

京東618:一箇中心五個原則,談談物流系統的大促優化實踐

京東

作者:者文明

編輯:木環、郭蕾

在京東的訂單流鏈路中,可以簡單的劃分為訂單前和訂單後兩部分,我們在京東主站上搜索商品、瀏覽商品詳情、把商品加入購物車、提交併支付訂單等環節屬於訂單前,訂單提交之後,訂單資訊流就進入訂單後的物流系統部分。每逢 618 大促期間,大家可能會更多的聚焦到網站 PV、秒殺系統、交易資料、廣告收入等等。其實對於京東來說,其很核心的優勢來源於精準的時效承諾、極速的送貨體驗和極致的售後服務,在大促期間,其物流系統的表現對客戶體驗至關重要。

京東物流系統簡介

京東物流系統屬於訂單生產系統,主要包括訂單履約、倉儲、配送、客戶服務和逆向處置中心等等。圖 1 示意了一個簡單的正向訂單生產流程,逆向生產流程主要由逆向處置中心發起,主要包括售後服務單(退換貨等)和安裝維修單。

流程

圖 1 訂單生產流程

京東物流系統有如下 3 大特性:

  • 90% 以上為 OLTP 系統,承載著訂單生產相關的所有核心交易流程
  • 領域模型和業務邏輯複雜
  • 強依賴關係型資料庫

以上特性也決定了物流系統的大促備戰和電商網站、訂單交易、秒殺、搜尋推薦、廣告等系統會大有不同,在很大程度上系統 70% 以上的效能(容量)取決於 DB 的效能(容量)。因此,DB 是我們每次大促備戰的重點。圍繞 DB 側的備戰工作,主要聚焦在慢 SQL、垂直和水平拆分、讀寫分離、生產庫和報表庫分離、連線池優化、引數調優等方面。

打不死的小強—慢 SQL

記得剛加入京東第一次負責 618 的時候,在 618 當天就遇到了兩次業務反饋系統卡頓的現象,緊急排查發現 DB 中大量連線堆積,再通過檢視當前執行緒發現是一個慢 SQL(耗時 10 多秒)導致了連線堆積,後來把慢 SQL 緊急優化上線後系統恢復正常。從那天以後,我深深感受到了慢 SQL 對我們系統的影響,同時也明白了一點,一個慢 SQL 對我們的系統總是致命的,我們不能放過任何一個慢 SQL。為了說明一個慢 SQL 對系統的影響,截取了兩張資料庫 CPU 使用率在一個慢 SQL 優化前後的對比圖(如圖 2),從圖中也可以看出,前後對比是非常明顯的。

SQL 優化

圖 2 一個慢 SQL 優化前後 CPU 負載對比

在資料庫優化方面,慢 SQL 優化是最重要且效果最好的一項工作,如果要用一個比喻去形容慢 SQL,打不死的小強是再貼切不過的了,慢 SQL 在我們的系統中是滅了一茬又一茬,似乎永遠消滅不完。通常情況下,慢 SQL 的出現可能是因為過濾條件中沒有索引、SQL 語句寫的過於複雜、表中資料量過大,做了全表掃描等等,因此我們在進行慢 SQL 優化時,優先會通過新增索引解決,索引解決不了的才會去優化語法,拆解 SQL 語句,將大事務化小,通過適當冗餘來減少關聯,優化資料模型,通過歷史資料結轉減少資料量等等。總之優化慢 SQL 的方法很多,各系統要根據各自的特性和場景選擇最優且成本最低的方案。

近幾年來,京東的業務一直處於持續膨脹之中,系統中總會不斷湧入很多新的業務需求,這樣也就不可避免的引入了新的慢 SQL,所以每次大促,慢 SQL 優化是一大備戰重點。

資料庫垂直和水平拆分

跟傳統的企業應用系統一樣,京東的倉儲系統也經歷過 C/S 和 B/S 時代,V3.0 之前用的是 SQLServer 和.Net 平臺,而且整個倉儲管理是一個系統,包括基礎資料、庫存、入庫、出庫、在庫等,隨著京東業務規模的迅速增長,每次大促的單量峰值也由早期的萬級增長到了現在的億級,這中間倉儲系統進行了垂直拆分,將基礎資料、庫存、入庫、出庫、在庫等拆分為獨立系統獨立部署(如圖 3) 。垂直拆分之後倉儲系統一分為多,系統的容量也就成倍上升。

資料庫

圖 3 倉儲系統資料庫垂直拆分

除了倉儲系統,其他很多系統(包括配送系統)都經歷了垂直拆分的過程,垂直拆分不但可以很好的解耦系統,還能成倍提升系統容量。

京東的配送系統流量比倉儲系統還要大,垂直拆分之後的系統容量不足以支撐大促期間的單量衝擊,於是在垂直拆分的基礎上又做了水平拆分,水平拆分除了常用的分庫分表之外,還有部分複雜業務表的模型水平拆分,比如運單表,拆分成基礎資料、擴充套件資料和狀態管理三個表,有的表也會按讀寫比例進行拆分,比如將讀多寫少的列放一張表,讀少寫多的列放另一張表。圖 4 是配送系統進行水平拆分的一個示意圖。水平拆分之後,目前系統可以輕鬆應對大促期間的億級單量,流量還遠遠未到系統的容量上限。

資料庫

圖 4 配送系統資料庫水平拆分

分離技術

分離技術也是我們每次大促備戰中的常用方法,主要包括讀 / 寫分離,生產 / 監控分離和線上 / 離線分離。

我們大部分系統讀寫比例大約 10:1,對於關係型資料庫來說,主要消耗來源於查詢,尤其是複雜查詢,所以為了提升資料庫端的總體容量,必須儘可能的將查詢 SQL 分離到從庫上,主庫只提供寫服務和一些必要的讀服務,圖 5 中 B 為備份庫,R 為從庫,所有從庫均可提供讀服務,一個主庫下可能會掛多個從庫,多個從庫根據業務場景需求可以做成負載均衡,也可以按業務優先順序進行隔離並支援靈活切換。這樣主庫就只負責生產,避免了那些比較消耗效能的複雜查詢影響到生產,同時系統的總體容量也會得到大大提升。

生產 / 監控分離指的是生產報表和監控報表必須分離開來,所謂生產報表就是業務生產過程中強依賴的報表,比如倉儲系統中的積壓類報表(揀貨、複核、打包等各環節積壓數量),配送系統中的分揀差異報表、配送差異報表等等。

這兩類報表業務優先順序不一樣,生產報表是要優先保障的,所以在系統中需要將這兩類報表進行隔離,避免監控類報表影響到生產類報表。監控報表是一個獨立系統,資料來源有兩種路徑,一種是從生產庫通過 binlog 複製過來(我們用的是自研的 Decomb 匯流排),另一種是從生產庫通過訊息方式先進入 kafka,再從 kafka 消費到監控系統。因為監控報表業務場景的多樣性和複雜性,監控系統的資料庫會採用多種技術,比如 MySQL、ElasticSearch、HBase、Cassandra 等等。

線上 / 離線分離指的是線上報表和離線報表分離,線上報表是實時或準實時報表,檢視的是 24 小時之內的業務資料,離線報表多為分析類報表,檢視的是 24 小時之前的業務資料。因為二者的業務優先順序和技術方案都不盡相同,所以必須要進行分離,避免相互影響。

分離技術

圖 5 分離技術

DB+ 技術

經歷過多次大促備戰之後,給我們最大的感觸就是業務規模的增長速度總是快於我們系統的迭代速度,業務規模總是在驅動著系統的迭代升級。面對億級單量,單純的引入前面提到的技術已經無法讓系統容量發生質的變化,系統容量容易受制於資料庫,所以,除了通過分庫分表來實現資料庫寫的分散式,還需要引入一些 NoSQL 技術,所謂的 DB+,也就是 DB+NoSQL+ 分散式,主要包括如下幾個方面的改進:

  1. 引入 KV 引擎,將一些資料從關係型資料庫(MySQL)遷移到 KV 引擎中來儲存和處理,這樣不僅可以大大降低關係型資料庫(MySQL)的負擔,還能提升資料的讀寫效能。京東的物流系統中,引入的 KV 引擎主要包括 Redis、HBase、ElasticSearch 和 Cassandra,Redis 用於快取相對靜態的熱點資料,HBase 是儲存,主要儲存海量的業務資料和歷史資料,ElasticSearch 主要儲存查詢條件相對複雜的資料,Cassandra 主要儲存一些日誌、流水類資料。
  2. 引入資料庫分庫分表中介軟體,實現資料庫寫的分散式,做到資料庫讀寫的水平可擴充套件,真正實現從 Scale up 到 Scale out 的轉變。
  3. 追求 BASE 模型,容忍分割槽失敗,弱化事務,大事務化小事務,甚至是無事務,舍強一致性取最終一致性。

圖 6 能簡單說明 DB+ 的基本思路,系統的儲存分兩部分,一部分是傳統的關係型資料庫(MySQL),用來儲存結構化,強事務資料,資料庫做了 Sharding,讀寫均為分散式,支援彈性擴充套件。另一個是 KV 引擎,KV 引擎主要包括 Redis、HBase、ElasticSearch 和 Cassandra,Redis 主要用來做熱點快取,HBase 用來儲存資料量級大而且 rowkey 又比較固定的資料,ElasticSearch 用來儲存查詢條件比較複雜的報表、查詢類資料,Cassandra 主要用來儲存日誌、流水類資料,這類資料量級大,讀寫效能要求也比較高,但是大多都是按 key 查詢。

DB技術

圖 6 DB+ 技術

思考總結

在經歷過多次大促備戰之後,最大的感觸是每次大促的業務規模總是在驅動著系統的技術不斷的升級。不同的業務量級所需要使用的技術也大不一樣,前面介紹的都是每次大促備戰的一些技術實踐。簡而言之,對於 OLTP 類系統來說,面對大促的優化可以總結為 一箇中心和五個基本原則

一箇中心就是要以資料庫為中心,優化資料庫效能為先,從資料庫端出發來提升系統容量。五個基本原則就是大系統小做原則、大事務化小原則、分離原則、分散式原則和資料庫弱依賴原則。下面分別介紹下:

  • 大系統小做講的就是合理的垂直拆分,將一個業務系統按照合理的領域模型拆分成多個可以獨立部署的子系統,一方面解耦,一方面提升系統的容量和可擴充套件能力。
  • 大事務化小指的是在業務允許的前提下儘可能將大事務拆成小事務,大事務會嚴重影響資料庫的效能而且容易造成死鎖;
  • 分離原則就是要根據業務的不通場景和要求和資料的冷熱程度等進行資料的分離,避免不同優先順序的業務相互影響;
  • 分散式原則主要說的是要將資料庫的寫進行分散式,並且真正做到寫庫可動態擴充套件;
  • 資料庫弱依賴原則簡單說就是要儘可能減少對關係型資料庫的依賴,能用 NoSQL 解決的就不用關係型資料庫,能非同步寫庫的就不同步寫,能最終一致性的就不追求強一致性等等。

現階段正處於電商高速發展的黃金時期,業務規模還將持續保持快速增長,京東的物流系統也還將持續迭代和演進。

作者介紹

者文明,京東商城運營研發部首席架構師,中科院碩士,清華大學學士,15 年電子商務 / 企業應用領域研發、架構經驗,涉及電子商務、網際網路、大資料、人工智慧等領域,專注電商物流系統架構、實時大資料、智慧物流等解決方案。2012 年初加入京東,主要負責京東物流系統架構。

原文來自微信公眾號:聊聊架構