天天看點

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

作者:架構師尼恩

▌說在前面:

在尼恩指導了幾百個小夥伴的面試,在這些過程中, 非常、非常高頻的一個面試題:

千萬級資料,如何做性能優化?

億級資料,如何做性能優化?

最近,有個小夥伴阿裡二面,又遇到了這個問題。

其實,尼恩一直想梳理一個教科書式的答案,

但是由于千萬級資料、億級資料的場景,千差萬别,唯恐不能覆寫全面而出現纰漏,是以一直拖着。

一直拖着....

最近,在梳理超高并發行業案例的過程中,發現了一個"近乎完美" 的行業案例《vivo 全球商城 億級訂單中心、優惠券中心架構設計與實踐》。

突然,豁然開朗。

咱們一直心心念念的 “千萬級資料,如何做性能優化?” 的教科書式的答案,其實就藏着在這個行業案例裡邊。

▌什麼才是“教科書式” 答案:

  • 要求1:資料量貼近實際

很多小夥伴,一說到3高架構,就習慣于 一頓猛吹,不切實際

面試官又不是傻子,一聽,就知道在吹水。

vivo 案例裡邊的資料量, 剛好不多不少, 正好是 “教科書式” 的資料量

  • 要求2:方案不夠完美,但是生産足以

很多小夥伴,一遇到3高架構的題目,就異常亢奮

狠不得竹筒倒豆子,把尼恩面試寶典裡邊的三高架構思路,尼恩書裡的三高架構思路,社群的聽到到三高架構思路,一個勁兒全部倒出來,

一聽,就知道在吹水。為什麼呢?

生産方案,其實不是完美的

完美的方案,都不怎麼生産;都活在書上、活在嘴裡

而行業案例《vivo 全球商城 億級訂單中心、優惠券中心架構設計與實踐》,剛好就是一個不怎麼完美的方案,但是,卻恰恰是一個 真正生産方案。

總之,尼恩從 面試次元,對這個方案,進行二次重構和梳理,現在把其做為參考答案,收入咱們的《尼恩Java面試寶典 PDF》供後面的小夥伴參考,大家一定好好看看這個教科書級别的答案。

注:本文以 PDF 持續更新,最新尼恩 架構筆記、面試題 的PDF檔案,請到《技術自由圈》公衆号領取

▌問題場景介紹:

首先,看看VIVO商城的使用者資料

截止2021,vivo在全球已覆寫4億多使用者,服務60多個國家和地區,

vivo 在菲律賓、馬來、印度等國家的市場佔有率名列前三,在國内出貨量始終保持領先地位,成功跻身2021年第三季度4000+以上高端手機市場佔有率的Top3。

抱歉,以上是他們2021的資料,

但是咱們手上的方案,大概是他們2018年的,那時候,他們的訂單隻有1000萬級别。

那個時候的vivo商城資料量看上去不多,但是剛好是完美的學習型資料。

VIVO商城問題場景

從2017年開始,随着使用者量級的快速增長,vivo 官方商城 v1.0 的單體架構逐漸暴露出弊端:

  • 子產品愈發臃腫
  • 開發效率低下
  • 性能出現瓶頸
  • 系統維護困難。

訂單子產品是電商系統的交易核心,不斷累積的資料即将達到單表存儲瓶頸,系統難以支撐新品釋出和大促活動期間的流量,服務化改造勢在必行。

那麼,他們如何做優化呢?

▌優化措施的宏觀介紹:

▌優化1:業務架構解耦

從2017年開始啟動的 v2.0 架構更新和全面的解耦,包括 業務子產品解耦、服務化改造

  • 業務子產品解耦,主要是基于業務子產品進行垂直的系統實體拆分,
  • 服務化改造,就是在業務子產品解耦基礎上,進一步的微服務化。拆分出來業務線各司其職,提供服務化的能力,共同支撐主站業務。

基于業務子產品進行垂直的系統實體拆分,分出來業務線各司其職,提供服務化的能力,共同支撐主站業務。

▌優化2:資料量大的優化

随着曆史訂單不斷累積,2017年MySQL中訂單表資料量已達千萬級。之後的訂單資料,遠遠大于億級

對資料量大的問題,進行了以下優化:

  • 資料歸檔
  • 分表

▌優化3:吞吐量大的優化

商城業務處于高速發展期,下單量屢創新高,業務複雜度也在提升,

應用程式對MySQL的通路量越來越高,但是, 單機MySQL的處理能力是有限的,

當壓力過大時,所有請求的通路速度都會下降,甚至有可能使資料庫當機。

并發量高的解決方案有:

  • 使用緩存
  • 讀寫分離
  • 分庫

▌優化4:高速搜尋引擎的資料一緻性優化

為了便于訂單的聚合搜尋,高速搜尋,把訂單資料備援存儲在Elasticsearch中,

那麼,如何在MySQL的訂單資料和ES中訂單資料的增量一緻性呢?

他們從以下的兩種方案中:

1)MQ方案

2)Binlog方案

他們沒有選擇 業務代碼侵入小、不影響服務本身的性能 的Binlog方案

而是選擇 更加低延遲的 MQ方案。

▌優化5:合理的選擇資料庫遷移措施

何将資料從原來的單執行個體資料庫,遷移到新的資料庫叢集,也是一大技術挑戰。

要考慮的問題有二:

  • 要確定資料的正确性,
  • 還要保證遷移過程中,隻要有問題,能快速地復原。

他們考慮了兩種方案:

  • 停機遷移
  • 不停機遷移

他們比較務實,不追求高大上。

考慮到不停機方案的改造成本較高,而夜間停機方案的業務損失并不大,最終選用的是停機遷移方案。

這才是 教科書式的選擇。

▌優化6:合理的進行分布式事務方案的選型

從單體架構,到微服務架構,資料的一緻性呢?

單體架構的 資料庫ACID 事務,當然保證不了,需要用到分布式事務。

分布式事務的方案,那就太多了。 具體可以參考下面的部落格文章:

《分布式事務 (秒懂)》PDF

業界的主流方案中,用于解決強一緻性的有兩階段送出(2PC)、三階段送出(3PC),

用于解決最終一緻性的有TCC、本地消息、事務消息和最大努力通知等。

他們從高并發的場景出發,選擇了本地消息表方案:

在本地事務中将要執行的異步操作記錄在消息表中,如果執行失敗,可以通過定時任務來補償。

▌優化7: 其他的一些細節優化

  • 比如 es 召回優化
  • 比如消息的有序性優化
  • 比如sharding-jdbc 分頁查詢優化等等

接下來,來看看這個生産項目,具體是怎麼做的。

▌優化1:業務架構解耦

業務架構解耦,就是基于業務子產品,進行垂直的系統實體拆分,

拆分出來業務線各司其職,提供服務化的能力,共同支撐主站業務。

是以,之前的訂單子產品,被從商城拆分出來,獨立為訂單系統,為商城相關系統提供訂單、支付、物流、售後等标準化服務。

子產品解耦配合的,就是資料庫解耦,是以,訂單子產品使用獨立的資料庫,

高并發場景下,子產品解耦之後,就是服務解耦(微服務化)。

服務化解耦之後,對應的就是團隊解耦。拆分出來業務線,各司其職。

總結起來,其實就是四大解耦:

  • 子產品解耦
  • 資料庫解耦
  • 服務解耦
  • 團隊解耦(業務線解耦)

四大解耦之後,訂單系統架構如下圖所示:

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌那麼四大解耦之後,結果是什麼呢:

  • 拆分出來業務線各司其職,疊代效率大幅提升
  • 能更好的應對超高并發、超大規模資料存儲難題。各個業務線可以結合領域特性,實施個性化的解決方案,更加有效、更有針對性的生産難題。

▌優化2:資料量大的優化

随着曆史訂單不斷累積,2017年MySQL中訂單表資料量已達千萬級。2017年之後的訂單資料,遠遠大于億級

大家知道,InnoDB存儲引擎的存儲結構是B+樹,單表的查找時間複雜度是O(log n),

B+樹的問題是: 樹的高度越大, IO次數越多

而磁盤IO操作,是性能非常低的。

是以當資料總量n變大時,檢索速度必然會變慢,

不論如何加索引或者優化都無法解決,隻能想辦法減小單表資料量。

對資料量大的問題,進行了以下優化:

  • 資料歸檔
  • 分表

▌1)資料歸檔

根據二八定律,系統絕大部分的性能開銷花在20%的業務。資料也不例外,

從資料的使用頻率來看,經常被業務通路的資料稱為熱點資料;反之,稱之為冷資料。

訂單資料具備時間屬性,存在熱尾效應,

在了解的資料的冷、熱特性後,便可以指導我們做一些有針對性的性能優化。

這裡面有業務層面的優化,也有技術層面的優化。

▌業務層面的優化:

電商網站,一般隻能查詢3個月内的訂單,如果你想看看3個月前的訂單,需要通路曆史訂單頁面。

▌技術層面的優化:

大部分情況下檢索的都是最近的訂單,而訂單表裡卻存儲了大量使用頻率較低的老資料。

那麼就可以将新老資料分開存儲,将曆史訂單移入另一張表中,

然後,對代碼中的查詢子產品做一些相應改動,便能有效解決資料量大的問題。

▌2)資料分表

分表又包含垂直分表和水準分表:

  • 水準分表:在同一個資料庫内,把一個表的資料按一定規則拆到多個表中;
  • 垂直分表:将一個表按照字段分成多表,每個表存儲其中一部分字段。

這裡主要是減少 IO 的次數,降低B+樹的高度,是以,主要考慮的是水準分表

按照業内的參考标準,單表的資料在500-1000W,B+樹的高度在2-3層,一般2-3次IO操作,就可以讀取到資料記錄。

但是,分表和措施,通常和分庫一起分析和落地。

是以,這裡稍後結合 第三大優化吞吐量大的優化,一起分析。

▌優化3:吞吐量大的優化

截止2021,vivo在全球已覆寫4億多使用者,服務60多個國家和地區

從2017年開始,商城業務處于高速發展期,下單量屢創新高,吞吐量猛漲

  • 應用程式吞吐量猛漲
  • MySQL的吞吐量猛漲

但是, 單體MySQL的處理能力是有限的,當壓力過大時,首先是 所有請求的RT時間拉長,通路速度下降,最後是拖垮整個資料庫,甚至有可能使資料庫當機。

吞吐量大的優化的解決方案有:

  • 使用緩存
  • 讀寫分離
  • 分庫

▌1)使用緩存

尼恩梳理了《當當的億級電商支付系統性能優化方案》之後,總結了高并發架構的三闆斧: 緩存、池化、異步

第一闆斧,首當其沖

首先考慮的是分布式緩存 Redis,使用Redis作為MySQL的前置緩存,可以擋住大部分的查詢請求,并降低響應時延。

其次,對于熱點資料,可以使用二級緩存,甚至三級緩存

具體可以參考尼恩的 《第26章視訊: 百萬qps 三級緩存架構落地與實操》

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

但是,緩存對存在局部熱點、周期性熱點資料友好

比如: 商品系統、 優惠券系統、活動系統,這裡存在局部熱點、周期性熱點資料的系統,使用一級緩存、二級緩存、甚至三級緩存。

但是,訂單系統不屬于這個場景。

訂單熊有一個特點,每個使用者的訂單資料都不一樣,

是以,在訂單系統中,緩存的緩存命中率不高。不存在太熱的資料,是以一級緩存、三級緩存就不用了。

但是,redis 二級緩存,能緩存最近的訂單,

最近的訂單也是使用者最近最可能使用的資料,矮個子裡邊拔将軍,

是以,redis分布式還是能夠為DB分擔一下壓力。這個還是要用的。

▌2)讀寫分離

主庫負責執行資料更新請求,然後将資料變更實時同步到所有從庫,用多個從庫來分擔查詢請求。

問題是:

  • 但訂單資料的更新操作較多,下單高峰時主庫的壓力依然沒有得到解決。
  • 且存在主從同步延遲,正常情況下延遲非常小,不超過1ms,但也會導緻在某一個時刻的主從資料不一緻。

那就需要對所有受影響的業務場景進行相容處理,可能會做一些妥協,

比如下單成功後先跳轉到一個下單成功頁,使用者手動點選檢視訂單後才能看到這筆訂單。

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌3)分庫

分庫又包含垂直分庫和水準分庫:

  • 水準分庫:把同一個表的資料按一定規則拆到不同的資料庫中,每個庫可以放在不同的伺服器上;
  • 垂直分庫:按照業務将表進行分類,分布到不同的資料庫上面,每個庫可以放在不同的伺服器上,它的核心理念是專庫專用。

分庫能夠解決整體 高吞吐的問題

分表能夠解決單表 高吞吐的問題

綜合考慮了改造成本、效果和對現有業務的影響,決定直接使用最後一招:分庫分表。

▌4)分庫分表技術選型

分庫分表的技術選型主要從這幾個方向考慮:

  • 用戶端sdk開源方案
  • 中間件proxy開源方案
  • 公司中間件團隊提供的自研架構
  • 自己動手造輪子

參考之前項目經驗,并與公司中間件團隊溝通後,采用了開源的 Sharding-JDBC 方案。

Sharding-JDBC 方案 已更名為Sharding-Sphere。其官方的位址是:

  • Github:https://github.com/sharding-sphere/
  • 文檔:官方文檔比較粗糙,但是網上資料、源碼解析、demo比較豐富
  • 社群:活躍
  • 特點:jar包方式提供,屬于client端分片,支援xa事務
阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌1)分庫分表政策

結合業務特性,選取使用者辨別作為分片鍵,

通過計算使用者辨別的哈希值再取模,來得到使用者訂單資料的庫表編号。

假設共有n個庫,每個庫有m張表,

則庫表編号的計算方式為:

  • 庫序号:Hash(userId) / m % n
  • 表序号:Hash(userId) % m

路由過程如下圖所示:

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

id的路由,邏輯比較複雜, 尼恩的第19章《10w qps 推送中台》有詳細具體的介紹,這個可以參考。

行業有非常多的解決案例, 推特 snowflake雪花id, 百度 雪花id,shardingjdbc 雪花id 源碼,這些案例各有優勢,這些 尼恩的第19章《10w qps 推送中台》有源碼級、原理級的介紹。

▌2)分庫分表的局限性和應對方案

分庫分表解決了資料量和并發問題,但它會極大限制資料庫的查詢能力,

有一些之前很簡單的關聯查詢,在分庫分表之後可能就沒法實作了,

那就需要單獨對這些Sharding-JDBC不支援的SQL進行改寫。

除此之外,還遇到了這些挑戰:

◆①全局唯一ID設計

分庫分表後,資料庫自增主鍵不再全局唯一,不能作為訂單号來使用,

但很多内部系統間的互動接口隻有訂單号,沒有使用者辨別這個分片鍵,如何用訂單号來找到對應的庫表呢?

原來,我們在生成訂單号時,就将庫表編号隐含在其中了。

這樣就能在沒有使用者辨別的場景下,從訂單号中擷取庫表編号。

id的設計,邏輯複雜,既要考慮 高并發高性能,還要考慮時鐘回撥等問題。

行業有非常多的解決案例, 推特 snowflake雪花id, 百度 雪花id,shardingjdbc 雪花id 源碼,這些案例各有優勢,這些 尼恩的第19章《10w qps 推送中台》有源碼級、原理級的介紹。

◆②曆史訂單号沒有隐含庫表資訊

用一張表單獨存儲曆史訂單号和使用者辨別的映射關系,随着時間推移,這些訂單逐漸不在系統間互動,就慢慢不再被用到。

◆③管理背景需要根據各種篩選條件,分頁查詢所有滿足條件的訂單

将訂單資料備援存儲在搜尋引擎Elasticsearch中,僅用于背景查詢。

▌優化4:高速搜尋引擎的資料一緻性優化

為了便于訂單的聚合搜尋,高速搜尋,把訂單資料備援存儲在Elasticsearch中,

那麼,如何在MySQL的訂單資料和ES中訂單資料的增量一緻性呢?

上面的說法,文绉绉的。

直白來說,如何在MySQL的訂單資料變更後,同步到ES中呢?

上面說到為了便于管理背景的查詢,我們将訂單資料備援存儲在Elasticsearch中,

那麼,如何在MySQL的訂單資料變更後,同步到ES中呢?

這裡要考慮的是資料同步的時效性和一緻性、對業務代碼侵入小、不影響服務本身的性能等。

▌1)MQ方案

ES更新服務作為消費者,接收訂單變更MQ消息後對ES進行更新

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌2)Binlog方案

ES更新服務借助canal等開源項目,把自己僞裝成MySQL的從節點,接收Binlog并解析得到實時的資料變更資訊,然後根據這個變更資訊去更新ES。

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

其中BinLog方案比較通用,但實作起來也較為複雜,我們最終選用的是MQ方案。

因為ES資料隻在管理背景使用,對資料可靠性和同步實時性的要求不是特别高。

考慮到當機和消息丢失等極端情況,在背景增加了按某些條件手動同步ES資料的功能來進行補償。

▌優化5:合理的選擇資料庫遷移措施

如何将資料從原來的單執行個體資料庫,遷移到新的資料庫叢集,也是一大技術挑戰。

不但要確定資料的正确性,還要保證每執行一個步驟後,一旦出現問題,能快速地復原到上一個步驟。

我們考慮了停機遷移和不停機遷移的兩種方案:

▌1)不停機遷移方案:

  • 把舊庫的資料複制到新庫中,上線一個同步程式,使用 Binlog等方案實時同步舊庫資料到新庫;
  • 上線雙寫訂單新舊庫服務,隻讀寫舊庫;
  • 開啟雙寫,同時停止同步程式,開啟對比補償程式,確定新庫資料和舊庫一緻;
  • 逐漸将讀請求切到新庫上;
  • 讀寫都切換到新庫上,對比補償程式確定舊庫資料和新庫一緻;
  • 下線舊庫,下線訂單雙寫功能,下線同步程式和對比補償程式。
阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌2)停機遷移方案:

  • 上線新訂單系統,執行遷移程式将兩個月之前的訂單同步到新庫,并對資料進行稽核;
  • 将商城V1應用停機,確定舊庫資料不再變化;
  • 執行遷移程式,将第一步未遷移的訂單同步到新庫并進行稽核;
  • 上線商城V2應用,開始測試驗證,如果失敗則回退到商城V1應用(新訂單系統有雙寫舊庫的開關)。
阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

考慮到不停機方案的改造成本較高,而夜間停機方案的業務損失并不大,最終選用的是停機遷移方案。

▌優化6:合理的進行分布式事務方案的選型

電商的交易流程中,分布式事務是一個經典問題,比如:

  • 使用者支付成功後,需要通知發貨系統給使用者發貨;
  • 使用者确認收貨後,需要通知積分系統給使用者發放購物獎勵的積分。

我們是如何保證微服務架構下資料的一緻性呢?

不同業務場景對資料一緻性的要求不同,業界的主流方案中,用于解決強一緻性的有兩階段送出(2PC)、三階段送出(3PC),解決最終一緻性的有TCC、本地消息、事務消息和最大努力通知等。

我們正在使用的本地消息表方案:

在本地事務中将要執行的異步操作記錄在消息表中,如果執行失敗,可以通過定時任務來補償。

下圖以訂單完成後通知積分系統贈送積分為例。

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

▌優化7: 其他的一些細節、具備優化

▌1)網絡隔離

隻有極少數第三方接口可通過外網通路,且都會驗證簽名,

内部系統互動使用内網域名和RPC接口,不需要要進行簽名,提升性能,也提升安全性。

▌2)并發鎖

分布式場景,可能會出現同一個訂單的并發更新

任何訂單更新操作之前,會通過資料庫行級鎖加以限制,防止出現并發更新。

▌3)幂等性

分布式場景,可能會出現同一個訂單的重複更新

所有接口均具備幂等性,不用擔心對方網絡逾時重試所造成的影響。

▌4)熔斷

分布式場景,需要防止故障的擴散,發生由一點牽動全身的系統性雪崩

防止某個系統故障的影響擴大到整個分布式系統中。

使用Hystrix元件,對外部系統的實時調用添加熔斷保護,防止某個系統故障的影響擴大到整個分布式系統中。

▌5)全方位監控和告警

通過配置日志平台的錯誤日志報警、調用鍊的服務分析告警,

再加上公司各中間件和基礎元件的監控告警功能,讓我們能夠能夠第一時間發現系統異常。

▌6)消息的有序性問題

采用MQ消費的方式同步資料庫的訂單相關資料到ES中,遇到的寫入資料不是訂單最新資料問題。

阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了

上圖左邊是原方案:

在消費訂單資料同步的MQ時,如果線程A在先執行,查出資料,

這時候訂單資料被更新了,線程B開始執行同步操作,查出訂單資料後先于線程A一步寫入ES中,

線程A執行寫入時就會将線程B寫入的資料覆寫,導緻ES中的訂單資料不是最新的。

上圖右邊是解決方案:

解決方案是在查詢訂單資料時加行鎖,整個業務執行在事務中,執行完成後再執行下一個線程。

▌7)sharding-jdbc 分組後排序分頁查詢出所有資料問題

示例:

select a  from  temp group by a,b order by a  desc limit 1,10           

執行時Sharding-jdbc裡group by 和 order by 字段和順序不一緻時将10置為Integer.MAX_VALUE, 導緻分頁查詢失效。

io.shardingsphere.core.routing.router.sharding.ParsingSQLRouter#processLimit

private void processLimit(final List<Object> parameters, final SelectStatement selectStatement, final boolean isSingleRouting) {
     boolean isNeedFetchAll = (!selectStatement.getGroupByItems().isEmpty() || !selectStatement.getAggregationSelectItems().isEmpty()) && !selectStatement.isSameGroupByAndOrderByItems();
    selectStatement.getLimit().processParameters(parameters, isNeedFetchAll, databaseType, isSingleRouting);
}

io.shardingsphere.core.parsing.parser.context.limit.Limit#processParameters

/**
* Fill parameters for rewrite limit.
*
* @param parameters parameters
* @param isFetchAll is fetch all data or not
* @param databaseType database type
* @param isSingleRouting is single routing or not
*/
public void processParameters(final List<Object> parameters, final boolean isFetchAll, final DatabaseType databaseType, final boolean isSingleRouting) {
    fill(parameters);
    rewrite(parameters, isFetchAll, databaseType, isSingleRouting);
}


private void rewrite(final List<Object> parameters, final boolean isFetchAll, final DatabaseType databaseType, final boolean isSingleRouting) {
    int rewriteOffset = 0;
    int rewriteRowCount;
    if (isFetchAll) {
        rewriteRowCount = Integer.MAX_VALUE;
    } else if (isNeedRewriteRowCount(databaseType) && !isSingleRouting) {
         rewriteRowCount = null == rowCount ? -1 : getOffsetValue() + rowCount.getValue();
    } else {
       rewriteRowCount = rowCount.getValue();
    }
    if (null != offset && offset.getIndex() > -1 && !isSingleRouting) {
       parameters.set(offset.getIndex(), rewriteOffset);
     }
     if (null != rowCount && rowCount.getIndex() > -1) {
        parameters.set(rowCount.getIndex(), rewriteRowCount);
      }
}           

正确的寫法應該是

select a  from  temp group by a desc ,b limit 1,10;           

兩個sql,可以對比一下

select a  from  temp group by a desc ,b limit 1,10 ; #優化的sql, 去掉了 oderby

select a  from  temp group by a,b order by a  desc limit 1,10   #原始的sql           

這裡 使用的版本是sharing-jdbc的3.1.1。

▌8)ES分頁查詢的召回問題

ES分頁查詢的召回問題: ES分頁查詢如果排序字段存在重複的值。

解決方案:最好加一個唯一的字段作為第二排序條件,避免分頁查詢時漏掉資料、查出重複資料,

比如用的是訂單建立時間作為唯一排序條件,同一時間如果存在很多資料,就會導緻查詢的訂單存在遺漏或重複,

這裡,需要增加一個唯一值作為第二排序條件、或者直接使用唯一值作為排序條件。

▌優化和更新的成果:

最後,總結一下,優化和更新的成果

  • 一次性上線成功,穩定運作了一年多;
  • 核心服務性能提升十倍以上;
  • 系統解耦,疊代效率大幅提升;
  • 能夠支撐商城至少五年的高速發展。

▌來自VIVO官方的建議:

VIVO官網商城開發團隊在系統設計時,并沒有一味追求前沿技術和思想,

面對問題根據業務實際狀況來選取最合适的辦法。

VIVO官網商城開發團隊認為,一個好的系統,不是在一開始就被大牛設計出來的,

一個好的系統,一定是随着業務的發展和演進逐漸被疊代出來的,持續預判業務發展方向,提前制定架構演進方案,

▌是以,以上才是“教科書式” 答案:

結合 VIVO的優化方案,大家回到前面的面試題:

  • 千萬級資料,如何做性能優化?
  • 億級資料,如何做性能優化?

很多小夥伴,一遇到3高架構的題目,就異常亢奮,狠不得竹筒倒豆子,一頓狂吹,一通猛吹,一通瞎吹

通過以上的VIVO的實際優化案例,大家應該有一個切實的感受:

  • 生産方案,其實不不是完美的
  • 完美的方案,都不怎麼生産;都活在書上、活在嘴裡

以上問題的和答案,不算完美,但是,正因為這樣,才算是一個面試場景,教科書式的答案

該答疑,已經收入 《尼恩Java面試寶典》PDF 。

後續,尼恩為結合生産實際項目、一線生産項目,

給大家分析、總結更多的,更加 符合實際的、真正的工業級的 教科書式的答案。

▌參考:

尼恩原創文章初始釋出:https://blog.csdn.net/crazymakercircle/article/details/128848309

▌技術自由的實作路徑 PDF領取:

▌實作你的架構自由:

  • 《吃透8圖1模闆,人人可以做架構》PDF
  • 《10Wqps評論中台,如何架構?B站是這麼做的!!!》PDF
  • 《阿裡二面:千萬級、億級資料,如何性能優化? 教科書級 答案來了》PDF
  • 《峰值21WQps、億級DAU,小遊戲《羊了個羊》是怎麼架構的?》PDF
  • 《100億級訂單怎麼排程,來一個大廠的極品方案》PDF
  • 《2個大廠 100億級 超大流量 紅包 架構方案》PDF

… 更多架構文章,正在添加中

▌實作你的 響應式 自由:

  • 《響應式聖經:10W字,實作Spring響應式程式設計自由》PDF
  • 這是老版本 《Flux、Mono、Reactor 實戰(史上最全)》PDF

▌實作你的 spring cloud 自由:

  • 《Spring cloud Alibaba 學習聖經》 PDF
  • 《分庫分表 Sharding-JDBC 底層原理、核心實戰(史上最全)》PDF
  • 《一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之間混亂關系(史上最全)》PDF

▌實作你的 linux 自由:

  • 《Linux指令大全:2W多字,一次實作Linux自由》PDF

▌實作你的 網絡 自由:

  • 《TCP協定詳解 (史上最全)》PDF
  • 《網絡三張表:ARP表, MAC表, 路由表,實作你的網絡自由!!》PDF

▌實作你的 分布式鎖 自由:

  • 《Redis分布式鎖(圖解 - 秒懂 - 史上最全)》PDF
  • 《Zookeeper 分布式鎖 - 圖解 - 秒懂》PDF

▌實作你的 王者元件 自由:

  • 《隊列之王: Disruptor 原理、架構、源碼 一文穿透》PDF
  • 《緩存之王:Caffeine 源碼、架構、原理(史上最全,10W字 超級長文)》PDF
  • 《緩存之王:Caffeine 的使用(史上最全)》PDF
  • 《Java Agent 探針、位元組碼增強 ByteBuddy(史上最全)》PDF

▌實作你的 面試題 自由:

4000頁《尼恩Java面試寶典》PDF 40個專題

....

注:以上尼恩 架構筆記、面試題 的PDF檔案,請到《技術自由圈》公衆号領取

還需要啥自由,可以告訴尼恩。 尼恩幫你實作.......

繼續閱讀