電商平臺的促銷活動往往意味著技術系統的大升級。今年的618周年大促,京東實現了商品中心、用戶中心和交易中心等平臺化升級。在日前的京東技術開放日618技術分享專場,多位京東技術專家聯袂解析了京東的技術研發體系如何在高強度的負載壓力下,保證業務系統的平穩運行,并介紹大型互聯網平臺技術升級、備戰思路、應急預案設計、問題應對等各方面的實戰經驗。
專家們介紹,京東的技術架構是由規模驅動的,近三年來基本上是每半年重構一次。目前京東正在打造一個多中心業務平臺,從流量和數據雙分散的角度將交易放在多個數據中心。京東采用OpenStack、Docker和自研的JFS、JMQ、JDOS等技術優化基礎資源配置能力,走向自動化運維,并多重改造MySQL支持多中心的穩定運行。在上層,京東還將機器學習和大數據分析技術應用于授信風控、推薦搜索等環節。
基礎云服務:從JFS到11000多個在線容器
京東云平臺首席架構師、系統技術部負責人劉海鋒介紹了支持各個業務單元的基礎云服務的演進(PPT下載)。這些基礎云服務可以簡單分解成三類,包括數據存儲、中間件系統和彈性計算云,與CSDN之前報道的京東私有云三大技術方向解析是一致的。
京東云平臺首席架構師、系統技術部負責人劉海鋒
劉海鋒表示,本次618系統設計有兩個指導原則:
面向故障設計,做了很多的工作,所有的系統全部都做了機房容錯的考慮。
隨著規模的增長,單機的性能會降低。要保證運維的有效性,自動化/半自動的運維越來越重要。
要完成這兩個原則,數據存儲系統中針對非結構化數據存儲的JFS,要提供BLOBs/files/blocks統一存儲、元數據管理的可擴展和可擦除編碼降低成本,JIMDB(以內存為中心的高速NoSQL)要做到精確故障檢測與自動切換,在線分裂、遷移與橫向擴容,自研存儲引擎支持RAM+SSD,以及靈活復制支持異步、同步、局部。但目前京東還沒有做元數據存儲的跨機房復制,未來半年,JFS的重心就是強一致跨數據中心復制,然后按范圍分裂。JIMDB要做零維護全自動化接入與管理,接入、部署、圍繞流量的切換,全部自動化完成。消息隊列則強調斷電不丟消息、跨數據中心部署等,未來要強化快速問題定位和一些新功能增強。
京東基礎云服務核心系統
劉海峰重點介紹了京東彈性計算云,要解決的是規模不斷擴大、機器越來越多的問題。2013年,京東彈性計算云從KVM起步,2014年10月,京東開始思考用Docker重構,2015年2月正式立項,由管理層推動,作為戰略項目來做。這今年618發揮了不小的作用。
劉海峰認為,VM的安全性和隔離性更強,更適合公有云,Docker更加輕量化,靈活性高,軟件的部署、管理和發布便捷,符合京東彈性計算云的構建思路:軟件定義數據中心+自動化、智能化的集群調度。雖然Docker的安全性和隔離性不是太好,但這并不是私有云的主要矛盾。
整個彈性計算云是兩層的架構,底層做硬件資源的管理,上層做業務的整合,中間用Docker做資源的抽象,做全自動化運維的管理。資源管理系統采用了OpenStack,不僅僅能夠生產Docker,也能夠生產傳統的VM和物理機,覆蓋到今后上線的新機房,覆蓋監控整個生命周期。京東的很多工作放在細粒度監控上,通過7*24小時的監控,一方面能夠發現很多的問題并預警,更主要的是通過監控數據來驅動整個調度、擴容或者縮容、快速的故障遷移等行為。但這個系統不管業務流程,只分配資源,提供API。
京東彈性計算云架構
網絡方面,京東并未引入SDN,而是劃分VLAN,宿主機網絡模式是Open vSwitch,支持每個Docker有一個IP——劉海峰稱之為“胖容器”,有IP,有常用工具鏈,有agent監控。他認為這更符合開發和運維的習慣,因為太超前就類似Google的K8S,接受、學習和使用成本更高。
真正解決業務的痛點,除了資源細粒度化,還需要上層應用的整合。包括原來運維的工具鏈,部署發布,擴容都要整合,目標是不用申請服務器,業務直接上線。下半年會按照流量做擴容。
京東的彈性微服務設計,一是公司要有很多服務,二是不能把很多的業務邏輯都打包在一起,這就適合做橫向的拓展和收縮,應對經常性的流量波動。目前主要是兩類產品,一是針對外部的CDN漏過來的應用,二是后端的應用服務,由服務框架開發,根據收集的數據做在線的調整。例如針對秒殺,針對惡意流量的風險控制跑在彈性云上面,幾個按紐就可以快速的部署,用完了就快速回收。
目前,京東在生產環境上的Docker實例最多超過11000個,大約60%用于在線應用,40%用于緩存,接入1000+應用。預計今年年底加上MySQL部署管理(目前是幾千個機器)和開發測試之后,規模再翻兩番,屆時京東大部分應用程序都會通過容器技術來發布和管理。
后端運營:數據庫保衛戰是核心
京東資深架構師者文明介紹了針對后端運營系統備戰的經驗(PPT下載)。后端運營系統涉及履約、倉儲、配送、客服和售后等核心業務,具有如下三個特點:
核心交易100多個系統,90%以上為OLTP類系統;
業務邏輯復雜,系統承擔著核心業務的信息流和資金流;
70%以上的性能取決于DB。
所以,只要數據庫沒問題,系統就是好的,每次備戰的原則就是保衛數據庫。
京東資深架構師者文明
京東通過3個方法進行這項工作:
在數據庫之上盡可能使用緩存;
同步邏輯盡量簡單化,更多復雜邏輯放到業務端去做;
大面積的讀寫分離。
具體包括8項措施:
消滅慢SQL
DB物理解耦
熱點緩存
同步異步化
分離技術
用漏斗保護DB
跨機房容災
應急預案
慢SQL搜索和消除是每一次備戰的一個重點問題,應用、系統慢的問題,源頭往往就是慢SQL連接堆積,可能只需要簡單修改就使得整個系統暢通,京東通過自動化工具,每天自動搜索出負載波動很大的SQL來進行修改,一個慢SQL的消除甚至可能帶來50%多的性能提升。
DB端物理解耦。為解決性能和擴展性的問題,從I+O(6個關鍵系統共享1套RAC小型機)到x86+MySQL(95%的系統已經是MySQL,但青龍的部分系統還是Oracle),并引入Sharding。六大系統全部打散,每個庫每個系統的數據層是物理隔離的,同時容量也能提升4~5倍。現在,寫并發最高的系統(接近一萬TPS)無壓力,性能和容量提升效果都明顯,同時也避免了某一系統出現故障就把資源耗盡影響其他系統的情況。
后端運營系統幾乎每一個系統都用了緩存。一些青龍基礎系統,比如分揀和配送,存儲了基礎信息、站點信息、配送員信息,其特點為數據量不大而并發特別高。京東去年雙11開始做Sharding,現在系統完全在MySQL上,一個主庫,對應四從一備,每個從庫承擔25%的并發,做四層緩存,包括服務端本地/服務端Redis/客戶端本地/客戶端Redis(Redis緩存由彈性云提供),這樣即便混存集群崩潰,全部流量打到數據庫上,一樣還是可以提供服務。然后根據服務并發量評估,如果不夠會加機器和服務的分組。整個訂單流操作環節都會同步給運單系統,保證訂單數據的一致性。
四級緩存架構
自動預分揀服務的同步異步化。一定范圍內的站點配送,根據基礎信息匹配的結果,可以持久化復用。持久化最后落庫是瓶頸,京東通過異步的方式來做,性能提升明顯。其次是異步降級,每一個步驟中間都可以做到靈活的降級,并可以靈活切換,做預案就很方便。此外相對靜態的數據放在Memory中,可以提高6倍的性能。可以這樣做是因為還有兩個從庫,宕機時候可以切過來,犧牲性能保住生產系統不死,繼續生產。
同步異步化
分離技術,除了DB端常用的讀寫分離,京東還做了生產和監控分離,在線報表和離線報表分離,減少生產庫的負擔。首先生產庫只留下生產必要的讀;其次量級巨大、搜索復雜的監控報表,拎出來單獨部署,用多種同步技術同步生產庫數據;對實時性要求不高的離線報表,則走BI的思路解決。者文明表示,有些監控比如今天送配送了多少包裹是屬于生產的范疇的,對性能要求很高,需要引入NoSQL等多種技術結合起來解決,能用KV引擎就用KV引擎,不能用KV就用關系庫。
漏斗模型是多次備戰總結出來的經驗,即為了避免并發流量直接打到后端的數據庫系統導致系統雪崩。在后端DB強依賴的系統上做一個隔離層,先把不可控的高并發流量接到這個隔離層,然后根據后端系統的生產能力逐步下發消費,下發給后端系統的流量是可以控制的,下游系統能夠支撐多少流量,就下發多少個訂單。原理和漏斗形狀類似,上面的口大,并發能力比較強,接下外圍的上游系統下發的信息,提供一定的容量,再根據下面系統的能力慢慢釋放,同時一滴不漏。通過隊列、異步化和分布式存儲保證容積,通過一個流控閥做配制中心,根據需求一鍵調大調小。異步也是秒級的,所以用戶對漏斗的存在基本沒有感覺。
漏斗模型原理
跨機房的容災和彈性云相結合實現,應用做到雙機房對等的部署,數據庫方面,主庫單機房提供寫,讀庫和備庫都是雙機房,應用跨機房延遲兩三毫秒,域名方式訪問DB,切換無需修改和重啟應用。現在能做到應用分階段部署,主庫在災難時可以切到異地地方的備庫,做到異地半雙活。未來的方向是運營多活(即多中心),配送和倉儲分成各大區(目前是七個大區),每個區只是負責該區的數據。運營多活現在開始探索。
應急預案,通過一個配置管理中心做降級開關的動作,配合服務分組多機房的切換,包括控制每個系統的降級開關、限流開關,在618或者雙11期間需要降級時,打開監控的頁面找到對應的開關點一下就行,不用重啟,能夠短時間內自動生效。在此之前,30臺機器的規模,重啟要花費15~20分鐘,會導致積單。
者文明還表示,目前讀的瓶頸已經解決,數據庫的寫流量,在允許的情況下引入了異步寫方案,但也已經可以預見到瓶頸,未來最主要的是到MySQL上面把寫的容量擴出來(拆庫、拆表)。京東的系統,業務相對復雜,拆庫、拆表的時候,可能不太好全面的兼顧,現在原則是通過一種簡單、明確的路由策略,能夠兼顧80%、90%左右就可以做,其他有其他的技術來搞定。
交易系統:分流、限流與物理擴容齊頭并進
京東商城交易平臺總監王曉鐘介紹了交易系統的整體規劃、優化思路、架構梳理和具體系統的優化案例,如何應對流量和數據增長量的壓力(PPT下載)。優化的基礎是去年雙11和日常運行數據、軟硬件性能指標以及數據存儲容量,優化的依據是架構梳理和線上壓力測試結果(包括讀業務和寫業務兩類場景)。
京東商城交易平臺總監王曉鐘
兩個優化原則如下:
流量角度:分流,如同一個頁面上的購物車和庫存狀態實際上是單獨的服務器;限流/隔離,殺掉不正常的流量,同時做服務隔離和數據隔離;跨機房災備;降級。
數據角度:擴容,加機器,改架構;內存不夠用,增加一些分片;冷熱分離,如訂單數據放在緩存,已完成狀態的訂單,單獨放在性能規格稍低的存儲;讀寫分離。
架構梳理包括物理鏈路和邏輯鏈路:
物理鏈路梳理包括三個層面:首先是公網入口流量和二級ISP;第二是機房內部,放在哪個機柜,網絡流量怎么走,包括機房和公網之間連接的物理網絡,有沒有做到雙備;第三是機房之間的專線,京東五個大機房之間,有一些服務的切分,跨機房調動的情況要梳理出來(交易和金融的接口不在這個系統)。
邏輯鏈路的梳理:交易系統暴露給前面的每一個鏈接,不能提供服務會不會影響京東用戶的下單,如果影響到下單是零級的鏈接(如庫存),不影響可降級的,歸到一級或者二級;這些鏈接后面依賴哪些系統,數據存儲的關系是什么,能不能分流、降級,數據是不是一致性。
王曉鐘通過購物車系統、庫存系統和秒殺系統舉例說明如何進行梳理架構、壓測和優化的工作。
購物車系統的架構梳理包括跨機房災備、同機房災備、降級和分流。實際的壓測顯示,想象的系統瓶頸都不存在,實際的瓶頸分別在于入口處Nginx網卡瓶頸(gzip已開)、柜頂交換機瓶頸、專線瓶頸,此外,流量大了以后CPU負載100%,有一條多線處理就造成堵塞。解決的核心思路,就是硬件升級和流量隔離。
庫存系統包括庫存狀態和庫存扣減。庫存狀態只是讀流量,庫存扣減是寫流量,一致性要求高,且無法降級,做了大量的限流保護。庫存還通過增加Redis復制節點擴容,扣減邏輯單獨一組Redis。目前一共是八套。庫存流量壓測發現的問題和解決:
Redis增量復制問題。網絡抖動發生就會變成全量復制,版本修復加了幾個關鍵的key并做硬盤持久化解決。
Redis的鏈接數問題。應用到一定程度,連接數就是瓶頸,簡單的解決辦法是加機器,多個部門協作完成。
庫存狀態更新回源主緩存節點,影響庫存預占性能。同時讀寫性能會下降,更會影響庫存扣減的性能,這里可以提前算好數據放到Nginx節點的Redis緩存。
庫存預占性能瓶頸。大流量時候即使異步寫入SQL,整個集群性能也下降,解決方案是往MySQL插任務。
京東庫存系統簡化示意圖
秒殺系統和主交易系統在邏輯上,包括邏輯層的鏈路完全一樣,區別是它的流量不可控,每到準點開始秒殺的時候,除了很多正常的用戶,還有一堆機器人、秒殺軟件,并發流量可能達到平時的100倍。機器人通過基礎限流規則(IP和用戶名匹配),用戶行為(輸驗證碼)等限制。王曉鐘認為,只要不把后面的邏輯做實際的邏輯,系統訪問的數據特別快。秒殺商品只需要一百多個商品信息,單獨做存儲,秒殺系統任何高流量都不會影響商品系統和促銷系統本身。
流量壓測發現的瓶頸和解決方案:
交易服務的接單有瓶頸,每秒數萬單扛不住,做水平擴展,加機器就可以解決。
Nginx服務節點帶寬成為瓶頸,規則和邏輯幾乎把網卡打滿,仍是加機器解決。
秒殺系統讀取活動規則Redis瓶頸,寫了簡單的業務規則判斷,Redis前置到服務本地解決。
交易平臺的未來,王曉鐘介紹,主要是兩個工作:一是下半年要主推多中心交易,就是多個機房承擔線上流量的壓力,還有單機房內部升級優化,每個機房往上升一步。王曉鐘表示,彈性云做得再好,單機房的擴容也是有瓶頸的,目前京東機房的機架位已經到頭。交易方面,現在用戶的讀流量已經是多中心了,面向用戶的寫流量是下半年整個團隊技術攻關的重點。
小結
京東今年618的交易量略高于去年雙11(1600萬 vs. 1400萬),為日常運營交易量的10倍左右。經過4年的618、雙11的實踐,京東團隊跨部門配合、技術架構的探索、數據的處理已經是輕車熟路,本次備戰和預案工作顯得從容不迫,不再像去年雙11一樣強調全員通宵達旦。整個促銷活動過程中也沒有遇到什么大問題。
如劉海峰所說,京東618備戰,根本是解決規模的問題,雖然不是每一個企業都會有京東那樣的體量,但以發展的眼光來看,技術人員仍然可以獲得一些可以借鑒的經驗。
規模問題的終極答案是多中心交易。京東認為,在業務邏輯允許的情況下,要從傳統的單機房橫向擴展走向多中心交易的架構。京東已經完成讀流量的多中心,并在規劃廊坊的數據中心,未來還會考慮南方。但跨機房的分布式事務,性能仍是大難題。
壓力測試很重要。王曉鐘強調,一定要按照線上壓測的結果來確認系統是否有瓶頸點,需要怎么解決,不要用所謂的架構師的經驗去評估,那基本上是不靠譜的。當然,壓測需要架構支持多個隔離的集群提供服務,包括數據也是隔離開來的。京東線上壓測機器的數據庫和緩存就是用過的數據庫和緩存,只是壓力測試流量到其他的集群里面去。同時使用的還有模擬流量。
采用多種技術結合,并根據實情靈活選擇是否運用新技術。如Docker,NoSQL,ES,KV引擎,關系庫,都發揮了各自的作用。青龍并沒有完全按去O,NoSQL的應用大都在監控,而Docker的大面積推廣,注重胖容器和瘦容器的結合,也并未刻意做SDN。
軟件架構調整之外,硬件升級/擴容同樣很重要,尤其是應用和數據不支持水平擴展的時候。京東入口處Nginx網卡瓶頸,柜頂交換機瓶頸,都需要通過硬件升級的方式來解決。這要在業務量和運營成本之間平衡,畢竟軟件系統的重構也意味著成本。硬件要根據預估和壓測提前采購準備好。
最后,團隊管理和團隊人才穩定性是實現技術持續升級的后盾。京東每次都是馬松副總裁牽頭,以例會的形式,解決跨部門合作的問題,相互做保護和通知,共同進行預案的演練。