架構面試題—大併發量的訂單的解析
點選關注,快速進階高階架構師
作者:激情的狼王
問題描述:做一個電商平臺,如何設定一個在買家下訂單後的”第60秒“發簡訊通知賣家發貨,需要考慮的是像淘寶一樣的大併發量的訂單。
原問題連結
https://www.oschina.net/question/926166_2137672
最基礎設計
最直觀能想到的解決辦法就是使用延遲佇列的實現原理,其就是一個按時間排好序的佇列,每次put的時候排序,然後take的時候就計算時間是否過期,如果過期則返回佇列第一個元素進行消費,否則當前執行緒阻塞X秒後彈出第一個元素,這個就是DelayQueue 的思路。
這種實現是最基礎的,但是也是問題最多的
1.DelayQueue 的最大容量是有上限的,承受不住過多的訂單2.每次來新的訂單都要進行排序插入合適位置,訂單量級過大時效能會很低3.這種方案只適合單機,無法橫向進行分散式擴充套件
升級版
針對上述的問題,我們採用Redis叢集來替代DelayQueue 的設計
1.生成訂單後,立即往redis群集寫訂單資訊(資訊包含下單時間)。2.根據redis叢集的結點數量,開啟相應倍數(大於等於1)的執行緒數,n個執行緒掃描一個結點3.各執行緒每次掃描得到的都是下單時間等於60s的訂單,再對這些訂單傳送簡訊,並相應的從redis移除
這種方法解決了基礎版的三個問題,在升級版裡還有一些點可以進行細化優化
1.訂單量爆發時,可以將每個訂單直接扔進redis,將壓力分給叢集2.訂單流量中低時,可以利用redis的SortedSet(有序集合)來進行操作,增大redis的掃描執行緒的顆粒度,進而提升處理效率3.Redis併發時的資料一致性問題,可以通過redis事務靈活解決
到這裡基本就可以解決本文所說的高併發量的帶時間延遲的問題了,我們再深入想一想這種設計的問題,如果時間不固定跨度廣的情況下其實輪詢的方式是不那麼理想的會空轉cpu
時間輪(TimingWheel)
Kafka中存在大量的延遲操作,比如延遲生產、延遲拉取以及延遲刪除等。Kafka並沒有使用JDK自帶的Timer或者DelayQueue來實現延遲的功能,而是基於時間輪自定義了一個用於實現延遲功能的定時器(SystemTimer)。
JDK的Timer和DelayQueue和redis的SortedSet插入和刪除操作的平均時間複雜度為O(nlog(n)),並不能滿足Kafka的高效能要求,而基於時間輪可以將插入和刪除操作的時間複雜度都降為O(1)。
時間輪的應用並非Kafka獨有,其應用場景還有很多,在Netty、Akka、Quartz、Zookeeper等元件中都存在時間輪的蹤影。
參考下圖,Kafka中的時間輪(TimingWheel)是一個儲存定時任務的環形佇列,每個元素可以存放一個定時任務列表(TimerTaskList)。TimerTaskList是一個雙向連結串列,元素是(TimerTaskEntry),其中封裝了真正的定時任務TimerTask。
image.png
時間輪由多個時間格組成,每個時間格代表當前時間輪的基本時間跨度(tickMs)。時間輪的時間格個數是固定的,可用wheelSize來表示,那麼整個時間輪的總體時間跨度(interval)可以通過公式 tickMs × wheelSize計算得出。時間輪還有一個錶盤指標(currentTime),currentTime當前指向的時間格也屬於到期部分,表示剛好到期,需要處理此時間格所對應的TimerTaskList的所有任務。
時間輪就像時鐘一樣,可以通過秒錶指向誰就執行誰,當時間跨度大時,可以增加時間輪的級別,如圖
image.png
第一層的時間輪tickMs=1ms, wheelSize=20, interval=20ms。
第二層的時間輪的tickMs為第一層時間輪的interval,即為20ms。每一層時間輪的wheelSize是固定的,都是20,那麼第二層的時間輪的總體時間跨度interval為400ms。
以此類推,這個400ms也是第三層的tickMs的大小,第三層的時間輪的總體時間跨度為8000ms。時間輪的優點
1.把任務輪詢的多個執行緒改裝為了秒針的單一輪詢2.從毫秒級或者秒級任務獲取執行改裝為批量的範圍獲取3.擴充套件性極好,顆粒度可以根據業務場景自適應4.插入和刪除操作的時間複雜度都降為O(1)
相關文章
- 高併發架構訊息佇列面試題解析架構佇列面試題
- 架構師眼中的高併發架構架構
- 架構師眼裡的高併發架構架構
- 高併發架構的搭建(二)架構
- 訂單系統中併發問題和鎖機制的探討
- 高併發架構架構
- 每秒上千訂單場景下的分散式鎖高併發優化實踐!【石杉的架構筆記】分散式優化架構筆記
- Java併發面試系列文章總結【石杉的架構筆記】Java面試架構筆記
- BAT研發面試36題總結:Spring+Redis+Docker+Dubbo+高併發架構BAT面試SpringRedisDocker架構
- 支付寶架構師眼裡的高併發架構架構
- Java併發面試題Java面試題
- 新零售SaaS架構:訂單履約系統的應用架構應用架構
- [分散式][高併發]高併發架構分散式架構
- 大型網站架構演變過程、大併發伺服器架構網站架構伺服器
- 【搞定 Java 併發面試】面試最常問的 Java 併發基礎常見面試題總結!Java面試題
- 大白話聊聊Java併發面試問題之談談你對AQS的理解?【石杉的架構筆記】Java面試AQS架構筆記
- ETL架構師面試題架構面試題
- Java 併發面試題解Java面試題
- RabbitMQ/高併發面試題MQ面試題
- 「架構技術專題」9種高效能高可用高併發的技術架構(5)架構
- Oracle RAC 併發與架構Oracle架構
- 解決庫存扣減及訂單建立時防止併發死鎖的問題
- 高併發架構的TCP知識介紹架構TCP
- 高併發架構的CDN知識介紹架構
- 377頁的Android 架構師面試題精編解析大全,請收下!Android架構面試題
- 大白話聊聊Java併發面試問題之volatile到底是什麼?【石杉的架構筆記】Java面試架構筆記
- 大白話聊聊Java併發面試問題之Java 8如何優化CAS效能?【石杉的架構筆記】Java面試優化架構筆記
- 一個考併發的面試題,怎麼答??面試題
- Java併發面試題精選Java面試題
- 【大資料】深入原始碼解析Map Reduce的架構大資料原始碼架構
- 高併發下的伺服器架構演變伺服器架構
- 大白話聊聊Java併發面試問題之公平鎖與非公平鎖是啥?【石杉的架構筆記】Java面試架構筆記
- 阿里支付寶架構師:談談我眼中的高併發架構【好文】阿里架構
- JAVA架構-使用redis叢集輕鬆應對大併發Java架構Redis
- 架構之:併發和並行架構並行
- Twitter 高併發高可用架構架構
- 構架Java併發模型框架 (轉)Java模型框架
- 千萬級併發架構設計架構