在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何對靜態數據做緩存

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 作者:馬哥Linux運維 ? 2022-07-04 11:34 ? 次閱讀

1. Overview

1.1 并發讀寫

秒殺要解決的主要問題是:并發讀與并發寫。

并發讀的優化理念是盡量減少用戶到服務端來讀數據,或者讓他們讀更少的數據;并發寫的處理原則一樣,要求我們在數據庫層面獨立出一個庫,做特殊的處理。

其次,還需要針對秒殺系統做一些保護,針對意料之外的情況設計兜底方案,以防止最壞的情況發生。

1.2 API設計原則

值得注意的地方是:如果想打造并維護一個超大流量并發讀寫、高性能、高可用的系統,在整個用戶請求路徑上從瀏覽器到服務端我們要遵循幾個原則,就是保證**用戶請求的數據盡量少、請求數盡量少、路徑盡量短、依賴盡量少,不要有單點**

1.3 秒殺架構原則

1.3.1 高可用

整個系統架構需要滿足高可用性,流量符合預期的時候肯定要穩定,就是超出預期也同樣不能掉鏈子,保證秒殺產品順利賣出。

1.3.2 一致性

數據必須一致,即成交總量必須和設定的數量一致。

1.3.3 高可用

系統的性能要足夠強,支撐足夠大的流量,不僅是服務端要做極致的性能優化,而且在整個請求鏈路上都要做協同的優化,每個地方都要快一點,整個系統就完美了。

本文將從這三個原則上來分別進行詳細說明。

2. 架構原則

秒殺系統本質上是一個滿足大并發、高性能和高可用的分布式系統。

2.1 數據盡量少

用戶請求的數據能少就少,請求的數據包括上傳給系統的數據和系統返回給用戶的數據。

因為這些數據在網絡上傳輸需要時間,其次不管是請求數據還是返回數據都需要服務器處理,而服務器在寫網絡的時候通常都要做壓縮和字符編碼,這些都非常消耗CPU,所以減少傳輸的數據量可以顯著減少CPU的使用。

同樣,數據盡量少還要求系統依賴的數據能少就少,包括系統完成某些業務邏輯需要讀取和保存的數據,這些數據一般是和后臺服務以及數據庫打交道的。調用其他服務會涉及數據的序列化和反序列化,這也是CPU的一大殺手,同樣也會增加延時。而且數據庫本身也很容易成為瓶頸,因此越少和數據庫打交道越好。

2.2 請求數盡量少

用戶請求的頁面返回后,瀏覽器渲染這個頁面還要包含其他的額外請求,比如說,這個頁面依賴的 CSS/JavaScript、圖片,以及 Ajax 請求等等都定義為“額外請求”,這些額外請求應該盡量少。因為瀏覽器每發出一個請求都多少會有一些消耗,例如建立連接要做三次握手,有的時候有頁面依賴或者連接數限制,一些請求(例如 JavaScript)還需要串行加載等。另外,如果不同請求的域名不一樣的話,還涉及這些域名的 DNS 解析,可能會耗時更久。所以你要記住的是,減少請求數可以顯著減少以上這些因素導致的資源消耗。

例如,減少請求數最常用的一個實踐就是合并 CSS 和 JavaScript 文件,把多個 JavaScript 文件合并成一個文件,在 URL 中用逗號隔開([https://g.xxx.com/tm/xx-b/4.0.94/mods/??module-preview/index.xtpl.js,module-jhs/index.xtpl.js,module-focus/index.xtpl.js](https://g.xxx.com/tm/xx-b/4.0.94/mods/??module-preview/index.xtpl.js,module-jhs/index.xtpl.js,module-focus/index.xtpl.js))。這種方式在服務端仍然是單個文件各自存放,只是服務端會有一個組件解析這個 URL,然后動態把這些文件合并起來一起返回。

2.3 路徑要盡量短

路徑指的是用戶發出請求到返回數據這個過程中需要經過的中間節點的數量。

通常,這些節點可以表示為一個系統或者一個新的 Socket 連接(比如代理服務器只是創建一個新的 Socket 連接來轉發請求)。每經過一個節點,一般都會產生一個新的 Socket 連接。

然而,每增加一個連接都會增加新的不確定性。從概率統計上來說,假如一次請求經過 5 個節點,每個節點的可用性是 99.9% 的話,那么整個請求的可用性是:99.9% 的 5 次方,約等于 99.5%。

所以縮短請求路徑不僅可以增加可用性,同樣可以有效提升性能(減少中間節點可以減少數據的序列化與反序列化),并減少延時(可以減少網絡傳輸耗時)。

要縮短訪問路徑可以將多個相互有強依賴的應用合并部署在一起,將遠程過程調用變成JVM內部的方法調用。

2.4 依賴要盡量少

所謂依賴,指的是要完成一次用戶請求必須依賴的系統或者服務。

舉個例子,比如說你要展示秒殺頁面,而這個頁面必須強依賴商品信息、用戶信息,還有其他如優惠券、成交列表等這些對秒殺不是非要不可的信息(弱依賴),這些弱依賴在緊急情況下就可以去掉。

要減少依賴,我們可以給系統進行分級,比如 0 級系統、1 級系統、2 級系統、3 級系統,0 級系統如果是最重要的系統,那么 0 級系統強依賴的系統也同樣是最重要的系統,以此類推。

注意,0 級系統要盡量減少對 1 級系統的強依賴,防止重要的系統被不重要的系統拖垮。例如支付系統是 0 級系統,而優惠券是 1 級系統的話,在極端情況下可以把優惠券給降級,防止支付系統被優惠券這個 1 級系統給拖垮。

2.5 不要有單點

不能有單點,因為單點意味著沒有備份,風險不可控,設計分布式系統的一個最重要的原則就是消除單點。

如何避免單點?—-> 避免將服務的狀態和機器綁定,即把服務無狀態化,這樣服務就可以在機器中隨意移動了。

如何那把服務的狀態和機器解耦呢?這里也有很多實現方式。例如把和機器相關的配置動態化,這些參數可以通過配置中心來動態推送,在服務啟動時動態拉取下來,我們在這些配置中心設置一些規則來方便地改變這些映射關系。

應用無狀態化是有效避免單點的一種方式,但是像存儲服務本身很難無狀態化,因為數據要存儲在磁盤上,本身就要和機器綁定,那么這種場景一般要通過冗余多個備份的方式來解決單點問題。

3. 不同場景下的不同架構案例

如果你想快速搭建一個簡單的秒殺系統,只需要把你的商品購買頁面增加一個“定時上架”功能,僅在秒殺開始時才讓用戶看到購買按鈕,當商品的庫存賣完了也就結束了。這就是當時第一個版本的秒殺系統實現方式。

但隨著請求量的加大(比如從 1w/s 到了 10w/s 的量級),這個簡單的架構很快就遇到了瓶頸,因此需要做架構改造來提升系統性能。這些架構改造包括:

把秒殺系統獨立出來單獨打造一個系統,這樣可以有針對性地做優化,例如這個獨立出來的系統就減少了店鋪裝修的功能,減少了頁面的復雜度;

在系統部署上也獨立做一個機器集群,這樣秒殺的大流量就不會影響到正常的商品購買集群的機器負載;

將熱點數據(如庫存數據)單獨放到一個緩存系統中,以提高“讀性能”;

增加秒殺答題,防止有秒殺器搶單。

此時秒殺已經成為了一個獨立的新系統,另外核心的一些數據放到了緩存當中,其他的關聯系統也都以獨立集群的方式進行部署。

438e0a4a-f947-11ec-ba43-dac502259ad0.png

fig1.jpg

但是這個架構仍然無法支持超過100w/s的請求量,因此為了進一步提高秒殺系統的性能,又對架構做了進一步的升級,比如:

對頁面進行徹底的動靜分離,使得用戶秒殺時不需要刷新整個頁面,而只需要點擊搶寶按鈕,借此把頁面刷新的數據降到最少;

在服務端對秒殺商品進行本地緩存,不需要再調用依賴系統的后臺服務獲取數據,甚至不需要去公共的緩存集群中查詢數據,這樣不僅可以減少系統調用,而且能夠避免壓垮公共緩存集群。

增加系統限流保護,防止最壞的情況發生

此時整個系統架構變成了這個樣子,已經對頁面進行了進一步的靜態化,秒殺過程當中就不需要刷新整個頁面了,只需要向服務端請求很少的動態數據。而且最關鍵的詳情和交易系統都增加了本地緩存,來提前緩存秒殺商品的信息,熱點數據庫也做了獨立部署。

43d0079c-f947-11ec-ba43-dac502259ad0.png

fig2.jpg

從前面的幾次升級來看,其實越到后面需要定制的地方越多,也就是越“不通用”。例如,把秒殺商品緩存在每臺機器的內存中,這種方式顯然不適合太多的商品同時進行秒殺的情況,因為單機的內存始終有限。所以要取得極致的性能,就要在其他地方(比如,通用性、易用性、成本等方面)有所犧牲。

4. 動靜分離的方案

秒殺系統需要讓請求效率足夠高 - 提高單次請求的效率,減少沒必要的請求。

4.1 何為動靜數據

將用戶請求的數據(如HTML)劃分為動態數據和靜態數據。而動態靜態數據的劃分,在于看頁面中輸出的數據是否和URL,瀏覽者,時間,地域相關,以及是否含有Cookie等私密數據。

對很多媒體類的網站來說,無論誰來看文章,展示的數據都是一樣的,那么哪怕這是個動態頁面,它仍然是個典型的靜態數據。

訪問淘寶的首頁,每個人看到的頁面可能都是不一樣的,其中包含了很多根據訪問者個人信息進行的推薦,這些個性化的數據就稱為動態數據。

這里再強調一下,我們所說的靜態數據,不能僅僅理解為傳統意義上完全存在磁盤上的 HTML 頁面,它也可能是經過 Java 系統產生的頁面,但是它輸出的頁面本身不包含上面所說的那些因素。也就是所謂“動態”還是“靜態”,并不是說數據本身是否動靜,而是數據中是否含有和訪問者相關的個性化數據。

這樣做動靜分離的時候,我們就可以對分離出來的靜態數據做緩存,有了緩存以后,靜態數據的訪問效率肯定就提高了。

4.2 如何對靜態數據做緩存?

4.2.1 距離用戶最近

將靜態數據緩存到離用戶最近的地方。靜態數據就是那些相對不會變化的數據,因此可以做緩存。常見的,我們可以緩存在:

用戶瀏覽器

CDN上

服務端的Cache中

4.2.2 靜態化改造要直接緩存HTTP連接

系統的靜態化改造是直接緩存HTTP連接而不僅僅是數據了。如下圖所示,Web代理服務器根據請求URL直接去除對應的HTTP響應頭和響應體然后直接返回,這個響應過程連HTTP協議都不用重新組裝,甚至連HTTP請求頭也不需要解析。

43ff4214-f947-11ec-ba43-dac502259ad0.png

fig3.jpg

4.2.3 緩存語言

不同語言寫的cache軟件處理緩存數據的效率也各不相同。以Java為例,Java不擅長處理大量連接請求,每個連接消耗的內存會比較多,Servlet容器解析HTTP協議比較慢。所以可以不在Java層做緩存,而是直接在Web服務器層上做,這樣就可以屏蔽Java的一些弱點;而相比起來,Web服務器(Nginx, Apache, Varnish)會更加擅長處理大并發的靜態文件請求。

4.3 靜態數據處理方案

以商品詳情頁為例:

4.3.1 URL唯一化

要緩存整個HTTP連接,以URL作為緩存的key

4.3.2 分離瀏覽者相關的因素

分離用戶的相關信息,是否登錄以及登錄身份等等。

4.3.3 分離時間因素

服務端輸出的是哪也通過動態請求獲取

4.3.4 異步化地域因素

詳情頁面上與地域相關的因素做成異步獲取的方式

4.3.5 去掉Cookie

服務端輸出的頁面包含的 Cookie 可以通過代碼軟件來刪除,如 Web 服務器 Varnish 可以通過 unset req.http.cookie 命令去掉 Cookie。注意,這里說的去掉 Cookie 并不是用戶端收到的頁面就不含 Cookie 了,而是說,在緩存的靜態數據中不含有 Cookie。

4.4 動態數據處理方案

4.4.1 ESI (Edge Side Includes)

在Web代理服務器上做動態內容請求,并將請求插入到靜態頁面中,當用戶拿到頁面時已經是一個完整的頁面了。對服務端性能有影響,但是用戶體驗會比較好

4.4.2 CSI (Client Side Include)

單獨發出異步Javascript請求,向服務端獲取動態內容。這種方式服務端性能更好,但是用戶端可能會有延時,體驗會差一些

4.5 動靜分離架構方案

4.5.1 實體機單機部署

這種方案是將虛擬機改為實體機,以增大 Cache 的容量,并且采用了一致性 Hash 分組的方式來提升命中率。這里將 Cache 分成若干組,是希望能達到命中率和訪問熱點的平衡。Hash 分組越少,緩存的命中率肯定就會越高,但短板是也會使單個商品集中在一個分組中,容易導致 Cache 被擊穿,所以我們應該適當增加多個相同的分組,來平衡訪問熱點和命中率的問題。

Nginx+Cache+Java結構實體機單機部署

441e0d8e-f947-11ec-ba43-dac502259ad0.png

fig4.jpg

這種部署方式有以下幾個優點:

沒有網絡瓶頸,而且能使用大內存;

既能提升命中率,又能減少 Gzip 壓縮;

減少 Cache 失效壓力,因為采用定時失效方式,例如只緩存 3 秒鐘,過期即自動失效。

這個方案中,雖然把通常只需要虛擬機或者容器運行的 Java 應用換成實體機,優勢很明顯,它會增加單機的內存容量,但是一定程度上也造成了 CPU 的浪費,因為單個的 Java 進程很難用完整個實體機的 CPU。

另外就是,一個實體機上部署了 Java 應用又作為 Cache 來使用,這造成了運維上的高復雜度,所以這是一個折中的方案。如果你的公司里,沒有更多的系統有類似需求,那么這樣做也比較合適,如果你們有多個業務系統都有靜態化改造的需求,那還是建議把 Cache 層單獨抽出來公用比較合理,如下面的方案 2 所示。

4.5.2 統一Cache層

所謂統一 Cache 層,就是將單機的 Cache 統一分離出來,形成一個單獨的 Cache 集群。統一 Cache 層是個更理想的可推廣方案,該方案的結構圖如下:

442d77ce-f947-11ec-ba43-dac502259ad0.png

fig5.jpg

統一Cache層,可以減少運維成本,也方便接入其他靜態化系統,還有以下優點:

單獨一個 Cache 層,可以減少多個應用接入時使用 Cache 的成本。這樣接入的應用只要維護自己的 Java 系統就好,不需要單獨維護 Cache,而只關心如何使用即可。

統一 Cache 的方案更易于維護,如后面加強監控、配置的自動化,只需要一套解決方案就行,統一起來維護升級也比較方便。

可以共享內存,最大化利用內存,不同系統之間的內存可以動態切換,從而能夠有效應對各種攻擊。

這種方案也會帶來一些問題。比如:

Cache 層內部交換網絡成為瓶頸;

緩存服務器的網卡也會是瓶頸;

機器少風險較大,掛掉一臺就會影響很大一部分緩存數據。

要解決上面這些問題,可以再對 Cache 做 Hash 分組,即一組 Cache 緩存的內容相同,這樣能夠避免熱點數據過度集中導致新的瓶頸產生。

4.5.3 使用CDN

在將整個系統做動靜分離后,我們自然會想到更進一步的方案,就是將 Cache 進一步前移到 CDN 上,因為 CDN 離用戶最近,效果會更好。

有幾個問題需要解決:

失效問題

前面我們也有提到過緩存時效的問題,不知道你有沒有理解,我再來解釋一下。談到靜態數據時,我說過一個關鍵詞叫“相對不變”,它的言外之意是“可能會變化”。比如一篇文章,現在不變,但如果你發現個錯別字,是不是就會變化了?如果你的緩存時效很長,那用戶端在很長一段時間內看到的都是錯的。所以,這個方案中也是,我們需要保證 CDN 可以在秒級時間內,讓分布在全國各地的 Cache 同時失效,這對 CDN 的失效系統要求很高。

命中率問題

Cache 最重要的一個衡量指標就是“高命中率”,不然 Cache 的存在就失去了意義。同樣,如果將數據全部放到全國的 CDN 上,必然導致 Cache 分散,而 Cache 分散又會導致訪問請求命中同一個 Cache 的可能性降低,那么命中率就成為一個問題。

發布更新問題

如果一個業務系統每周都有日常業務需要發布,那么發布系統必須足夠簡潔高效,而且你還要考慮有問題時快速回滾和排查問題的簡便性。

從前面的分析來看,將商品詳情系統放到全國的所有 CDN 節點上是不太現實的,因為存在失效問題、命中率問題以及系統的發布更新問題。那么是否可以選擇若干個節點來嘗試實施呢?答案是“可以”,但是這樣的節點需要滿足幾個條件:

靠近訪問量比較集中的地區

離主站相對較遠

節點到主站間的網絡比較好,比較穩定

節點容量大,不會占用其他CDN太多的資源

基于上面幾個因素,選擇 CDN 的二級 Cache 比較合適,因為二級 Cache 數量偏少,容量也更大,讓用戶的請求先回源的 CDN 的二級 Cache 中,如果沒命中再回源站獲取數據,部署方式如下圖所示:

4443c664-f947-11ec-ba43-dac502259ad0.png

fig6.jpg

使用 CDN 的二級 Cache 作為緩存,可以達到和當前服務端靜態化 Cache 類似的命中率,因為節點數不多,Cache 不是很分散,訪問量也比較集中,這樣也就解決了命中率問題,同時能夠給用戶最好的訪問體驗,是當前比較理想的一種 CDN 化方案。

5. 如何處理熱點數據

有一部分數據是會被大量用戶訪問的熱賣商品,這部分商品是需要特殊關注的,因為其會對系統產生一系列的影響。

首先,熱點請求會大量占用服務器處理資源,雖然這個熱點可能占總量的很小的一部分,然而卻可能搶占90%以上的服務器資源,如果這個熱點請求還是沒有價值的無效請求,那么對系統資源來說完全是浪費。

5.1 什么是熱點

5.1.1 熱點操作

例如大量的刷新頁面,大量添加購物車,零點大量的下單等。這些操作可以抽象為“讀請求”和“寫請求”,這兩種請求的處理方式大相徑庭,讀請求的優化空間比較大,而寫請求的瓶頸一般都在存儲層,優化的思路就是根據CAP理論做平衡。

5.1.2 熱點數據

熱點數據就是用戶的熱點請求對應的數據,又可以分為靜態熱點數據和動態熱點數據。

靜態熱點數據,就是能夠提前預測的熱點數據。動態熱點數據,就是不能被提前預測到的,系統在運行過程中臨時產生的熱點。

5.2 發現熱點數據

5.2.1 發現靜態熱點數據

如前面講的,靜態熱點數據可以通過商業手段,例如強制讓賣家通過報名參加的方式提前把熱點商品篩選出來,實現方式是通過一個運營系統,把參加活動的商品數據進行打標,然后通過一個后臺系統對這些熱點商品進行預處理,如提前進行緩存。但是這種通過報名提前篩選的方式也會帶來新的問題,即增加賣家的使用成本,而且實時性較差,也不太靈活。

不過,除了提前報名篩選這種方式,你還可以通過技術手段提前預測,例如對買家每天訪問的商品進行大數據計算,然后統計出 TOP N 的商品,我們可以認為這些 TOP N 的商品就是熱點商品。

5.2.2 發現動態熱點數據

具體實現

構建異步系統,用來收集交易鏈路上各個環節中的中間件產品的熱點Key,例如Nginx、緩存、RPC服務框架

建立一個熱點上報和可以按照需求訂閱的熱點服務的下發規范。因為交易鏈路上各個系統(包括詳情,購物車,交易,優惠,庫存等等)會有訪問上的時間差,需要將上游已經發現的熱點透傳給下游系統,提前做好保護。例如,對于大促高峰期,詳情系統是最早知道的。

將上游系統收集的熱點數據發送到熱點服務臺,讓下游系統提前知道信息,做熱電保護

44509268-f947-11ec-ba43-dac502259ad0.png

fig7.jpg

我們通過部署在每臺機器上的 Agent 把日志匯總到聚合和分析集群中,然后把符合一定規則的熱點數據,通過訂閱分發系統再推送到相應的系統中。你可以是把熱點數據填充到 Cache 中,或者直接推送到應用服務器的內存中,還可以對這些數據進行攔截,總之下游系統可以訂閱這些數據,然后根據自己的需求決定如何處理這些數據。

Tips:

熱點服務的后臺抓取熱點數據日志的方式最好采用異步的方式;可以保證通過性,不會影響業務系統和中間件產品的主流程。

熱點服務和中間件自身需要有熱電保護模塊,每個中間件和應用和需要保護自己

熱點發現需要接近實時,因為只有接近實時才有意義,能及時對下游系統提供保護

5.3 如何處理熱點數據

5.3.1 優化

緩存熱點數據,如果熱點數據做了動靜分離,那么可以長期緩存靜態數據。

5.3.2 限制

保護機制,比如對商品的ASIN做一致性hash,然后根據hash做分桶,每個分桶處置一個處理隊列,通過這種方式將熱點商品限制在一個請求隊列當中,防止因為某些熱點商品占用太多的服務器資源,而使得其他請求始終得不到服務器的處理資源。

5.3.3 隔離

將熱點數據隔離出來,針對熱點數據可以再做優化

業務隔離 - 商業邏輯上運行上的隔離

系統隔離 - 運行時的隔離

數據隔離 - 單獨數據庫 Cache集群

6. 流量削峰

秒殺請求在時間上是高度集中于某一特定的時間點的,這樣一來會有一個特別高的流量峰值,它對資源的消耗是瞬時的。

但是對于秒殺這個場景來說,最終能夠搶到的商品的人數是固定的,并發讀越高,無效請求也就越多了。

從業務角度上來說,秒殺希望更多的人能夠參與進來,更多的人來刷新頁面,但是真正開始下單的時候,秒殺請求就不是越多越好了,可以設計一些規則,讓并發的請求更多的延緩,甚至我們可以過濾掉一些無效請求。

6.1 削峰的原因

我們知道服務器的處理資源是恒定的,你用或者不用它的處理能力都是一樣的,所以出現峰值的話,很容易導致忙到處理不過來,閑的時候卻又沒有什么要處理。但是由于要保證服務質量,我們的很多處理資源只能按照忙的時候來預估,而這會導致資源的一個浪費。

削峰主要是為了能夠讓服務端處理變得更加平穩,也為了能夠節省服務器的資源成本。從秒殺這個場景來說,就是更多延緩用戶請求的發出,以便減少或者過濾掉一些無效請求,遵從請求數要盡量少的原則。

6.2 無損削峰方式

6.2.1 排隊

用消息隊列緩沖瞬時流量,將同步的直接調用轉換成異步的間接推送,中間通過一個隊列在一端承接瞬時的流量洪峰,在另外一端平滑地將信息推送出去。

44656792-f947-11ec-ba43-dac502259ad0.png

fig8.jpg

但是如果流量峰值持續一段時間,超過了消息隊列的處理上限,還是會被壓垮的。

其他常見的排隊方式有:

利用線程池加鎖等待

先進先出、先進后出等常用的內存排隊算法的實現

將請求序列化到文件當中,然后再順序讀文件

6.2.2 答題

第一個目的是防止部分買家使用秒殺器在參加秒殺時作弊。2011 年秒殺非常火的時候,秒殺器也比較猖獗,因而沒有達到全民參與和營銷的目的,所以系統增加了答題來限制秒殺器。增加答題后,下單的時間基本控制在 2s 后,秒殺器的下單比例也大大下降。

第二個目的其實就是延緩請求,起到對請求流量進行削峰的作用,從而讓系統能夠更好地支持瞬時的流量高峰。這個重要的功能就是把峰值的下單請求拉長,從以前的 1s 之內延長到 2s~10s。這樣一來,請求峰值基于時間分片了。這個時間的分片對服務端處理并發非常重要,會大大減輕壓力。而且,由于請求具有先后順序,靠后的請求到來時自然也就沒有庫存了,因此根本到不了最后的下單步驟,所以真正的并發寫就非常有限了。這種設計思路目前用得非常普遍,如當年支付寶的“咻一咻”、微信的“搖一搖”都是類似的方式。

6.2.3 分層過濾

采用漏斗式的設計

4483f040-f947-11ec-ba43-dac502259ad0.png

fig9.jpg

假如請求分別經過 CDN、前臺讀系統(如商品詳情系統)、后臺系統(如交易系統)和數據庫這幾層,那么:

大部分數據和流量在用戶瀏覽器或者 CDN 上獲取,這一層可以攔截大部分數據的讀取

經過第二層(即前臺系統)時數據(包括強一致性的數據)盡量得走 Cache,過濾一些無效的請求

再到第三層后臺系統,主要做數據的二次檢驗,對系統做好保護和限流,這樣數據量和請求就進一步減少

最后在數據層完成數據的強一致性校驗

分層過濾的核心思想是:在不同的層次盡可能地過濾掉無效請求,讓漏斗最末端的才是有效的請求。而達到這種效果,我們就必須對數據做分層的校驗。

分層校驗的基本原則有:

將動態請求的讀數據緩存在Web端,過濾掉無效的數據讀

對讀數據不做強一致性校驗,減少因為一致性校驗產生的瓶頸問題

對寫數據進行基于時間的合理分片,過濾掉過期的失效請求

對寫請求做限流保護,將超出系統承載能力的請求過濾掉

對寫數據進行強一致性校驗,只保留最后有效的數據

分層校驗的目的是:在讀系統中,盡量減少由于一致性校驗帶來的系統瓶頸,但是盡量將不影響性能的檢查條件提前,如用戶是否具有秒殺資格、商品狀態是否正常、用戶答題是否正確、秒殺是否已經結束、是否非法請求、營銷等價物是否充足等;在寫數據系統中,主要對寫的數據(如“庫存”)做一致性檢查,最后在數據庫層保證數據的最終準確性(如“庫存”不能減為負數)。

7. 影響性能的因素

7.1 性能的定義

服務設備的不同對于性能的定義也是不一樣的,例如CPU主要看主頻,磁盤主要看IOPS(Input/ output Operations Per Second, 即每秒進行讀寫操作的次數)。

關于秒殺,我們主要討論系統服務端的性能,一般使用QPS來衡量,還有一個影響和QPS息息相關,即響應時間(Response Time, RT),可以理解為服務器處理響應的耗時。

正常情況下響應時間越短,一秒鐘處理的請求數就會越多,這在單線程處理的情況下看起來是線性關系,即我們只要把每個請求的響應時間降到最低,那么性能就會最高。而在多線程當中,總QPS = (1000ms/ 響應時間)x 線程數,從這個角度上來看,性能和兩個因素相關,一個是一次響應的服務端的耗時,一個是處理請求的線程數。

7.1.1 響應時間

對于大部分的Web系統而言,響應時間一般是由CPU執行時間和線程等待時間組成的,即服務器在處理一個請求時,一部分是CPU本身在做運算,還有一部分是各種等待。

理解了服務器處理請求的邏輯,估計你會說為什么我們不去減少這種等待時間。很遺憾,根據我們實際的測試發現,減少線程等待時間對提升性能的影響沒有我們想象得那么大,它并不是線性的提升關系,這點在很多代理服務器(Proxy)上可以做驗證。

如果代理服務器本身沒有CPU消耗,我們在每次給代理服務器代理的請求加個延時,即增加響應時間,但是這對代理服務器本身的吞吐量并沒有多大的影響,因為代理服務器本身的資源并沒有被消耗,可以通過增加代理服務器的處理線程數,來彌補響應時間對代理服務器的 QPS 的影響。

其實,真正對性能有影響的是 CPU 的執行時間。這也很好理解,因為 CPU 的執行真正消耗了服務器的資源。經過實際的測試,如果減少 CPU 一半的執行時間,就可以增加一倍的 QPS。

7.1.2 線程數

并不是線程數越多越好,總QPS就會越大,因為線程本身也消耗資源,會受到其他因素的制約。例如,線程越多系統的線程切換成本就會越高,而且每個線程都會耗費一定的內存。

默認的配置一般為:

線程數 = 2 x CPU核數 + 1

還有一個根據最佳實踐得出來的公式為:

線程數 = [(線程等待時間 + 線程CPU時間) / 線程CPU時間] x CPU數量

因此要提升性能,我們就要減少CPU的執行時間,另外就是要設置一個合理的并發線程數量,通過這兩方面來顯著提升服務器的性能。

7.2 如何發現瓶頸

服務器會出現瓶頸的地方很多,例如CPU, 內存, 磁盤以及網絡等可能都會導致瓶頸。另外不同的系統對于瓶頸的關注度不一樣,例如對緩存系統來說,制約的是內存,而對存儲型的系統來說I/O 更容易出現瓶頸。

而對于秒殺,瓶頸更容易發生在CPU上。

那么,如何發現 CPU 的瓶頸呢?其實有很多 CPU 診斷工具可以發現 CPU 的消耗,最常用的就是 JProfiler 和 Yourkit 這兩個工具,它們可以列出整個請求中每個函數的 CPU 執行時間,可以發現哪個函數消耗的 CPU 時間最多,以便你有針對性地做優化。

當然還有一些辦法也可以近似地統計 CPU 的耗時,例如通過 jstack 定時地打印調用棧,如果某些函數調用頻繁或者耗時較多,那么那些函數就會多次出現在系統調用棧里,這樣相當于采樣的方式也能夠發現耗時較多的函數。

雖說秒殺系統的瓶頸大部分在 CPU,但這并不表示其他方面就一定不出現瓶頸。例如,如果海量請求涌過來,你的頁面又比較大,那么網絡就有可能出現瓶頸。

怎樣簡單地判斷 CPU 是不是瓶頸呢?一個辦法就是看當 QPS 達到極限時,你的服務器的 CPU 使用率是不是超過了 95%,如果沒有超過,那么表示 CPU 還有提升的空間,要么是有鎖限制,要么是有過多的本地 I/O 等待發生。

7.3 如何優化系統

針對Java來說的:

7.3.1 減少編碼

Java的編碼運行比較慢,在很多場景下,只要涉及字符串的操作都會比較消耗CPU資源,不管是磁盤IO還是網絡IO,因為都需要將字符轉換成字節,這個轉換必須編碼。

每個字符的編碼都需要查表,而這種查表的操作非常耗資源,所以減少字符到字節或者相反的轉換、減少字符編碼會非常有成效。減少編碼就可以大大提升性能。

那么如何才能減少編碼呢?例如,網頁輸出是可以直接進行流輸出的,即用 resp.getOutputStream() 函數寫數據,把一些靜態的數據提前轉化成字節,等到真正往外寫的時候再直接用 OutputStream() 函數寫,就可以減少靜態數據的編碼轉換。

7.3.2 減少序列化

序列化也是Java性能的一大天敵,減少Java當中的序列化操作也能大大提升性能。又因為序列化往往是和編碼同時發生的,所以減少序列化也就減少了編碼。

序列化大部分是在 RPC 中發生的,因此避免或者減少 RPC 就可以減少序列化,當然當前的序列化協議也已經做了很多優化來提升性能。有一種新的方案,就是可以將多個關聯性比較強的應用進行“合并部署”,而減少不同應用之間的 RPC 也可以減少序列化的消耗。

所謂“合并部署”,就是把兩個原本在不同機器上的不同應用合并部署到一臺機器上,當然不僅僅是部署在一臺機器上,還要在同一個 Tomcat 容器中,且不能走本機的 Socket,這樣才能避免序列化的產生。

7.3.3 Java 秒殺場景的針對性優化

Java 和通用的 Web 服務器(如 Nginx 或 Apache 服務器)相比,在處理大并發的 HTTP 請求時要弱一點,所以一般我們都會對大流量的 Web 系統做靜態化改造,讓大部分請求和數據直接在 Nginx 服務器或者 Web 代理服務器(如 Varnish、Squid 等)上直接返回(這樣可以減少數據的序列化與反序列化),而 Java 層只需處理少量數據的動態請求。針對這些請求,我們可以使用以下手段進行優化:

直接使用 Servlet 處理請求。避免使用傳統的 MVC 框架,這樣可以繞過一大堆復雜且用處不大的處理邏輯,節省 1ms 時間(具體取決于你對 MVC 框架的依賴程度)。

直接輸出流數據。使用 resp.getOutputStream() 而不是 resp.getWriter() 函數,可以省掉一些不變字符數據的編碼,從而提升性能;數據輸出時推薦使用 JSON 而不是模板引擎(一般都是解釋執行)來輸出頁面。

7.3.4 并發讀優化

也許有讀者會覺得這個問題很容易解決,無非就是放到 Tair 緩存里面。集中式緩存為了保證命中率一般都會采用一致性 Hash,所以同一個 key 會落到同一臺機器上。雖然單臺緩存機器也能支撐 30w/s 的請求,但還是遠不足以應對像“大秒”這種級別的熱點商品。那么,該如何徹底解決單點的瓶頸呢?

答案是采用應用層的 LocalCache,即在秒殺系統的單機上緩存商品相關的數據。

那么,又如何緩存(Cache)數據呢?你需要劃分成動態數據和靜態數據分別進行處理:

像商品中的“標題”和“描述”這些本身不變的數據,會在秒殺開始之前全量推送到秒殺機器上,并一直緩存到秒殺結束;

像庫存這類動態數據,會采用“被動失效”的方式緩存一定時間(一般是數秒),失效后再去緩存拉取最新的數據。

還有關于一致性的問題,因為庫存是在不斷更新的,這就要用到前面介紹的讀數據的分層校驗原則了,讀的場景可以允許一定的臟數據,因為這里的誤判只會導致少量原本無庫存的下單請求被誤認為有庫存,可以等到真正寫數據時再保證最終的一致性,通過在數據的高可用性和一致性之間的平衡,來解決高并發的數據讀取問題。

8. 減庫存設計的核心邏輯

不超賣是秒殺系統的前提。減庫存到底應該是在下單階段還是付款階段呢?

8.1 減庫存的方式

8.1.1 下單減庫存

即當買家下單之后,在商品的總庫存中減去買家購買的數量。這種方式控制最精確,下單時直接通過數據庫的事務機制控制商品庫存,這樣一定不會出現超賣的現象。但是有些人下完單以后并不會付款。

8.1.2 付款減庫存

即買家下單后,并不立即減庫存,而是等到有用戶付款后才真正減庫存,否則庫存一直保留給其他買家。但因為付款時才減庫存,如果并發比較高,有可能出現買家下單后付不了款的情況,因為可能商品已經被其他人買走了。

8.1.3 預扣庫存

這種方式相對復雜一些,買家下單后,庫存為其保留一定的時間(如 10 分鐘),超過這個時間,庫存將會自動釋放,釋放后其他買家就可以繼續購買。在買家付款前,系統會校驗該訂單的庫存是否還有保留:如果沒有保留,則再次嘗試預扣;如果庫存不足(也就是預扣失敗)則不允許繼續付款;如果預扣成功,則完成付款并實際地減去庫存。

8.2 可能存在的問題

假如我們采用“下單減庫存”的方式,即用戶下單后就減去庫存,正常情況下,買家下單后付款的概率會很高,所以不會有太大問題。但是有一種場景例外,就是當賣家參加某個活動時,此時活動的有效時間是商品的黃金售賣時間,如果有競爭對手通過惡意下單的方式將該賣家的商品全部下單,讓這款商品的庫存減為零,那么這款商品就不能正常售賣了。要知道,這些惡意下單的人是不會真正付款的,這正是“下單減庫存”方式的不足之處。

既然“下單減庫存”可能導致惡意下單,從而影響賣家的商品銷售,那么有沒有辦法解決呢?你可能會想,采用“付款減庫存”的方式是不是就可以了?的確可以。但是,“付款減庫存”又會導致另外一個問題:庫存超賣。

假如有 100 件商品,就可能出現 300 人下單成功的情況,因為下單時不會減庫存,所以也就可能出現下單成功數遠遠超過真正庫存數的情況,這尤其會發生在做活動的熱門商品上。這樣一來,就會導致很多買家下單成功但是付不了款,買家的購物體驗自然比較差。

那么,既然“下單減庫存”和“付款減庫存”都有缺點,我們能否把兩者相結合,將兩次操作進行前后關聯起來,下單時先預扣,在規定時間內不付款再釋放庫存,即采用“預扣庫存”這種方式呢?

這種方案確實可以在一定程度上緩解上面的問題。但是否就徹底解決了呢?其實沒有!針對惡意下單這種情況,雖然把有效的付款時間設置為 10 分鐘,但是惡意買家完全可以在 10 分鐘后再次下單,或者采用一次下單很多件的方式把庫存減完。針對這種情況,解決辦法還是要結合安全和反作弊的措施來制止。

例如,給經常下單不付款的買家進行識別打標(可以在被打標的買家下單時不減庫存)、給某些類目設置最大購買件數(例如,參加活動的商品一人最多只能買 3 件),以及對重復下單不付款的操作進行次數限制等。

針對“庫存超賣”這種情況,在 10 分鐘時間內下單的數量仍然有可能超過庫存數量,遇到這種情況我們只能區別對待:對普通的商品下單數量超過庫存數量的情況,可以通過補貨來解決;但是有些賣家完全不允許庫存為負數的情況,那只能在買家付款時提示庫存不足。

8.3 大型秒殺中如何減庫存

對于一般業務系統而言,一般是預扣庫存的方案,超出有效付款時間訂單就會自動釋放。而對于秒殺場景,一般采用下單減庫存。

“下單減庫存”在數據一致性上,主要就是保證大并發請求時庫存數據不能為負數,也就是要保證數據庫中的庫存字段值不能為負數,一般我們有多種解決方案:一種是在應用程序中通過事務來判斷,即保證減后庫存不能為負數,否則就回滾;另一種辦法是直接設置數據庫的字段數據為無符號整數,這樣減后庫存字段值小于零時會直接執行 SQL 語句來報錯;再有一種就是使用 CASE WHEN 判斷語句,例如這樣的 SQL 語句:

UPDATEitemSETinventory=CASEWHENinventory>=xxxTHENinventory-xxxELSEinventoryEND

秒殺商品和普通商品的減庫存還是有些差異的,例如商品數量比較少,交易時間段也比較短,因此這里有一個大膽的假設,即能否把秒殺商品減庫存直接放到緩存系統中實現,也就是直接在緩存中減庫存或者在一個帶有持久化功能的緩存系統(如 Redis)中完成呢?

如果你的秒殺商品的減庫存邏輯非常單一,比如沒有復雜的 SKU 庫存和總庫存這種聯動關系的話,我覺得完全可以。但是如果有比較復雜的減庫存邏輯,或者需要使用事務,你還是必須在數據庫中完成減庫存。

由于 MySQL 存儲數據的特點,同一數據在數據庫里肯定是一行存儲(MySQL),因此會有大量線程來競爭 InnoDB 行鎖,而并發度越高時等待線程會越多,TPS(Transaction Per Second,即每秒處理的消息數)會下降,響應時間(RT)會上升,數據庫的吞吐量就會嚴重受影響。

這就可能引發一個問題,就是單個熱點商品會影響整個數據庫的性能, 導致 0.01% 的商品影響 99.99% 的商品的售賣,這是我們不愿意看到的情況。一個解決思路是遵循前面介紹的原則進行隔離,把熱點商品放到單獨的熱點庫中。但是這無疑會帶來維護上的麻煩,比如要做熱點數據的動態遷移以及單獨的數據庫等。

而分離熱點商品到單獨的數據庫還是沒有解決并發鎖的問題,我們應該怎么辦呢?要解決并發鎖的問題,有兩種辦法:

應用層排隊

按照商品維度設置隊列順序執行,這樣能減少同一臺機器對數據庫同一行記錄進行操作的并發度,同時也能控制單個商品占用數據庫連接的數量,防止熱點商品占用太多的數據庫連接。

數據庫排隊

應用層只能做到單機的排隊,但是應用機器數本身很多,這種排隊方式控制并發的能力仍然有限,所以如果能在數據庫層做全局排隊是最理想的。阿里的數據庫團隊開發了針對這種 MySQL 的 InnoDB 層上的補丁程序(patch),可以在數據庫層上對單行記錄做到并發排隊。

9. 如何設計兜底方案?

9.1 高可用建設應該從哪里著手?

44a43940-f947-11ec-ba43-dac502259ad0.png

fig10.jpg

架構階段 - 考慮系統的可擴展性和容錯性,要避免出現單點問題。例如多機房單元化部署,即使某個城市的某個機房出現整體故障,仍然不會影響整體網站的運轉。

編碼階段 - 保證代碼的健壯性,例如涉及到遠程調用的問題的時候,要設置合理的超時退出機制,防止被其他系統拖垮,也要對調用的返回結果集有預期,防止返回的結果超出程序處理的范圍。即對錯誤異常進行捕獲,對無法預料的錯誤要有默認處理結果。

測試階段 - 測試主要是保證測試用例的覆蓋度,保證最壞情況發生的時候,我們也有相應的處理流程。

發布階段 - 要有緊急的回滾機制

運行階段 - 運行態是常態,重要的是對系統的監控要準確及時,發現問題能夠準確報警并且報警數據要準確詳細,以便于排查問題。

故障發生 - 及時止損,例如由于程序問題導致商品價格錯誤,就要及時下架商品或者關閉購買鏈接,防止造成重大資產損失。

為什么系統的高可用建設要放到整個生命周期中全面考慮?因為我們在每個環節中都可能犯錯,而有些環節犯的錯,你在后面是無法彌補的。例如在架構階段,你沒有消除單點問題,那么系統上線后,遇到突發流量把單點給掛了,你就只能干瞪眼,有時候想加機器都加不進去。所以高可用建設是一個系統工程,必須在每個環節都做好。

那么針對秒殺系統,我們重點介紹在遇到大流量時,應該從哪些方面來保障系統的穩定運行,所以更多的是看如何針對運行階段進行處理,這就引出了接下來的內容:降級、限流和拒絕服務。

9.2 降級

所謂“降級”,就是當系統的容量達到一定程度時,限制或者關閉系統的某些非核心功能,從而把有限的資源保留給更核心的業務。它是一個有目的、有計劃的執行過程,所以對降級我們一般需要有一套預案來配合執行。如果我們把它系統化,就可以通過預案系統和開關系統來實現降級。

降級方案可以這樣設計:當秒殺流量達到 5w/s 時,把成交記錄的獲取從展示 20 條降級到只展示 5 條。“從 20 改到 5”這個操作由一個開關來實現,也就是設置一個能夠從開關系統動態獲取的系統參數。

這里,我給出開關系統的示意圖。它分為兩部分,一部分是開關控制臺,它保存了開關的具體配置信息,以及具體執行開關所對應的機器列表;另一部分是執行下發開關數據的 Agent,主要任務就是保證開關被正確執行,即使系統重啟后也會生效。

44d0cc94-f947-11ec-ba43-dac502259ad0.png

fig11.jpg

9.3 限流

如果說降級是犧牲了一部分次要的功能和用戶的體驗效果,那么限流就是更極端的一種保護措施了。限流就是當系統容量達到瓶頸時,我們需要通過限制一部分流量來保護系統,并做到既可以人工執行開關,也支持自動化保護的措施。

這里,我同樣給出了限流系統的示意圖。總體來說,限流既可以是在客戶端限流,也可以是在服務端限流。此外,限流的實現方式既要支持 URL 以及方法級別的限流,也要支持基于 QPS 和線程的限流。

客戶端限流

好處可以限制請求的發出,通過減少發出無用請求從而減少對系統的消耗。缺點就是當客戶端比較分散時,沒法設置合理的限流閾值:如果閾值設的太小,會導致服務端沒有達到瓶頸時客戶端已經被限制;而如果設的太大,則起不到限制的作用。

服務端限流

好處是可以根據服務端的性能設置合理的閾值,而缺點就是被限制的請求都是無效的請求,處理這些無效的請求本身也會消耗服務器資源。

fig12.jpg

在限流的實現手段上來講,基于 QPS 和線程數的限流應用最多,最大 QPS 很容易通過壓測提前獲取,例如我們的系統最高支持 1w QPS 時,可以設置 8000 來進行限流保護。線程數限流在客戶端比較有效,例如在遠程調用時我們設置連接池的線程數,超出這個并發線程請求,就將線程進行排隊或者直接超時丟棄。

限流無疑會影響用戶的正常請求,所以必然會導致一部分用戶請求失敗,因此在系統處理這種異常時一定要設置超時時間,防止因被限流的請求不能 fast fail(快速失敗)而拖垮系統。

9.4 拒絕服務

當系統負載達到一定閾值時,例如 CPU 使用率達到 90% 或者系統 load 值達到 2*CPU 核數時,系統直接拒絕所有請求,這種方式是最暴力但也最有效的系統保護方式。例如秒殺系統,我們在如下幾個環節設計過載保護:

在最前端的 Nginx 上設置過載保護,當機器負載達到某個值時直接拒絕 HTTP 請求并返回 503 錯誤碼,在 Java 層同樣也可以設計過載保護。

拒絕服務可以說是一種不得已的兜底方案,用以防止最壞情況發生,防止因把服務器壓跨而長時間徹底無法提供服務。像這種系統過載保護雖然在過載時無法提供服務,但是系統仍然可以運作,當負載下降時又很容易恢復,所以每個系統和每個環節都應該設置這個兜底方案,對系統做最壞情況下的保護。

原文標題:9. 如何設計兜底方案?

文章出處:【微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭靜

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7103

    瀏覽量

    89287
  • 數據緩存
    +關注

    關注

    0

    文章

    23

    瀏覽量

    7094
  • HTTP協議
    +關注

    關注

    0

    文章

    66

    瀏覽量

    9751

原文標題:9. 如何設計兜底方案?

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    緩存對大數據處理的影響分析

    緩存對大數據處理的影響顯著且重要,主要體現在以下幾個方面: 一、提高數據訪問速度 在大數據環境中,數據存儲通常采用分布式存儲系統,
    的頭像 發表于 12-18 09:45 ?197次閱讀

    HTTP緩存頭的使用 本地緩存與遠程緩存的區別

    HTTP緩存頭是一組HTTP響應頭,它們控制瀏覽器和中間代理服務器如何緩存網頁內容。合理使用HTTP緩存頭可以顯著提高網站的加載速度和性能,減少服務器的負載。 1. HTTP緩存頭概述
    的頭像 發表于 12-18 09:41 ?140次閱讀

    Web緩存的類型及功能分析

    隨著互聯網的迅速發展,用戶對網絡內容的訪問需求日益增長。為了提高用戶體驗和降低服務器負擔,Web緩存技術應運而生。Web緩存通過存儲重復請求的數據,減少了對原始服務器的訪問次數,從而加快了數據
    的頭像 發表于 12-18 09:35 ?257次閱讀

    緩存技術在軟件開發中的應用

    在現代軟件開發中,隨著數據量的爆炸性增長和用戶對響應速度的高要求,緩存技術成為了提升系統性能的重要手段。緩存技術通過將數據存儲在離用戶更近的位置,減少
    的頭像 發表于 12-18 09:32 ?280次閱讀

    什么是緩存(Cache)及其作用

    緩存(Cache)是一種高速存儲器,用于臨時存儲數據,以便快速訪問。在計算機系統中,緩存的作用是減少處理器訪問主存儲器(如隨機存取存儲器RAM)所需的時間。 緩存(Cache)概述
    的頭像 發表于 12-18 09:28 ?1134次閱讀

    緩存之美——如何選擇合適的本地緩存

    Guava cache是Google開發的Guava工具包中一套完善的JVM本地緩存框架,底層實現的數據結構類似于ConcurrentHashMap,但是進行了更多的能力拓展,包括緩存過期時間設置、
    的頭像 發表于 11-17 14:24 ?376次閱讀
    <b class='flag-5'>緩存</b>之美——如何選擇合適的本地<b class='flag-5'>緩存</b>?

    什么是CPU緩存?它有哪些作用?

    CPU緩存(Cache Memory)是計算機系統中一個至關重要的組成部分,它位于CPU與內存之間,作為兩者之間的臨時存儲器。CPU緩存的主要作用是減少CPU訪問內存所需的時間,從而提高系統的整體性能。以下將詳細闡述CPU緩存
    的頭像 發表于 08-22 14:54 ?3493次閱讀

    請問ESP32的CAN有沒硬件上的數據緩存呢?

    如題,請問ESP32 的CAN有沒硬件上的數據緩存呢?
    發表于 06-25 07:59

    緩存有大key?你得知道的一些手段

    ?? ? ? ? 背景: 最近系統內緩存CPU使用率一直報警,超過設置的70%報警閥值,針對此場景,需要對應解決緩存是否有大key使用問題,掃描緩存集群的大key,針對每個key優化
    的頭像 發表于 06-19 09:38 ?797次閱讀
    <b class='flag-5'>緩存</b>有大key?你得知道的一些手段

    使用.cmm閃存初始SW借助Trace32 SW腳本,數據無法從高速緩存內存讀取特定扇區的數據,為什么?

    。 對于某個扇區,我們無法從高速緩存地址讀取數據。 但通過非緩存地址,我們可以從同一地址讀取數據,而且在復位(任何復位)后,我們可以同時從兩個地址(
    發表于 06-03 08:20

    LOTO示波器軟件PC緩存(波形錄制與回放)功能

    數據波形,我們在獲取足夠的緩存后,可以先暫停示波器的采集:,就可以看到PC緩存也停止了,滑動條也出現了,我們可以靜態的選中任何一幀我們感興趣的波形。每個
    發表于 05-16 11:23

    如何設置靜態IP代理

    靜態IP
    jf_60146132
    發布于 :2024年04月29日 07:46:31

    STM32f103 USB雙緩存的時候,發送4K數據里面前64字節是0,為什么?

    STM32f103 USB 雙緩存的時候, 采取ENP3的TXaddr1和TXaddr0的雙緩存ping-pong發送機制,每次上位機接收完4K數據, 4K
    發表于 04-28 07:07

    交換機分布緩存_述說數據中心交換機的重要性能指標——緩存

    交換機是數據中心不可缺少的網絡設備,在數據中心里發揮著重要作用。在平時使用和采購時,大多數都關注交換機的背板帶寬、端口密度、單端口速度、協議特性等方面的性能指標,很少有人去關注緩存指標,這是一個常常
    的頭像 發表于 03-15 17:39 ?883次閱讀

    如何選擇合適的本地緩存

    小編最近在使用系統的時候,發現盡管應用已經使用了 redis 緩存提高查詢效率,但是仍然有進一步優化的空間,于是想到了比分布式緩存性能更好的本地緩存,因此對領域內常用的本地緩存進行了一
    的頭像 發表于 01-18 11:19 ?874次閱讀
    如何選擇合適的本地<b class='flag-5'>緩存</b>?
    主站蜘蛛池模板: 2022天天操| 国产一区二区高清| 亚洲影院手机版777点击进入影院 亚洲综合精品成人啪啪 | 欧美日韩一级视频| 亚洲一区二区免费看| 国产亚洲欧美成人久久片| 综合视频网| 国内自拍网红在综合图区| 人人草人人爽| 午夜免费免费啪视频观看| 黄色免费网站视频| 午夜免费影视| 99久久999久久久综合精品涩| 久草视频在线免费看| 日韩精品视频免费观看| 婷婷激情亚洲| 亚洲欧洲一区| 最近高清在线国语| 欧美 亚洲 一区| 亚洲免费国产| 中文字幕123区| 免费在线视频观看| 人人澡人人澡碰人人看软件| 国产午夜精品福利久久| 免费我看视频在线观看| 中文字幕一区精品欧美| 色玖玖| 日韩一级免费视频| 久久国产精品99精品国产987| 在线www 天堂网在线| 资源视频在线观看| 牛牛碰在线| 久操视频在线免费观看| 亚洲国产欧美在线成人aaaa | 啪啪网站色大全免费| 久久精品国产四虎| 午夜影视体验区| 91极品女神私人尤物在线播放| 色偷偷免费| 亚洲1234区乱码| 人人澡人人添|