1. 程式人生 > >9.快取設計與優化

9.快取設計與優化

1. 快取收益和成本

1.1 收益

  • 加速讀寫
  • 降低後端負載(降低mysql負載)

1.2 成本

  • 資料不一致:快取層和資料層有時間視窗不一致,和更新策略有關
  • 程式碼維護成本:多了一層快取邏輯
  • 運維成本:例如redis cluster

1.3 使用場景

  • 降低後端負載:對於高消耗的SQL:join結果集、分組統計結果;對這些結果進行快取。
  • 加速請求響應
  • 大量寫合併為批量寫:如計數器先redis累加再批量寫入DB

2. 快取的更新策略

  • LRU/LFU/FIFO演算法剔除:例如maxmemory-policy

FIFO(first in first out)

先進先出策略,最先進入快取的資料在快取空間不夠的情況下(超出最大元素限制)會被優先被清除掉,以騰出新的空間接受新的資料。策略演算法主要比較快取元素的建立時間。在資料實效性要求場景下可選擇該類策略,優先保障最新資料可用。

LFU(less frequently used)

最少使用策略,無論是否過期,根據元素的被使用次數判斷,清除使用次數較少的元素釋放空間。策略演算法主要比較元素的hitCount(命中次數)。在保證高頻資料有效性場景下,可選擇這類策略。

LRU(least recently used)

最近最少使用策略,無論是否過期,根據元素最後一次被使用的時間戳,清除最遠使用時間戳的元素釋放空間。策略演算法主要比較元素最近一次被get使用時間。在熱點資料場景下較適用,優先保證熱點資料的有效性。

  • 超時剔除:例如expire
  • 主動更新:開發控制生命週期(最終一致性,時間間隔比較短)

image

  • 低一致性:最大記憶體和淘汰策略
  • 高一致性:超時剔除和主動更新結合,最大記憶體和淘汰策略兜底。

3. 快取粒度控制

image

快取粒度控制三個角度

  • 通用性:全量屬性更好(新增刪除屬性不需要改東西)
  • 佔用空間:部分屬性更好
  • 程式碼維護:表面上全量屬性更好(新增刪除屬性不需要改東西)

4. 快取穿透優化

定義

大量請求不命中,快取已經沒有存在的意義了:

image

產生原因

  • 業務程式碼自身問題
  • 惡意攻擊、爬蟲等

如何發現

  • 業務響應時間
  • 業務本身問題
  • 相關指標:總呼叫數、快取層命中數、儲存層命中數

解決方案

  • 方案一:快取空物件

image

存在的問題

需要更多的鍵:惡意攻擊、爬蟲會有很多亂七八糟的鍵,當量很大時,會有風險,所以會對這種空物件設定快取時間控制風險

快取層和儲存層資料“短期”不一致:快取了空物件,但是當業務恢復了,真實資料又存在於DB中了,那麼在這個空物件過期時間內,取到的仍然是空物件,造成短期內資料不一致的問題。解決:可以訂閱訊息,當恢復正常後接受到訊息,然後重新整理快取。

image

  • 方案二:布隆過濾器攔截

image

什麼是Bloom Filter?

布隆過濾器(Bloom Filter)是1970年由布隆提出的, “a space-efficient probabilistic data structure”。它實際上是一個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。

如果想判斷一個元素是不是在一個集合裡,一般想到的是將集合中所有元素儲存起來,然後通過比較確定。連結串列、樹、散列表(又叫雜湊表,Hash table)等等資料結構都是這種思路。但是隨著集合中元素的增加,我們需要的儲存空間越來越大。同時檢索速度也越來越慢,上述三種結構的檢索時間複雜度分別為O(n),O(log n),O(n/k)。

++布隆過濾器的原理是,當一個元素被加入集合時,通過K個雜湊函式將這個元素對映成一個位數組中的K個點,把它們置為1++。

優點:相比於其它的資料結構,++布隆過濾器在空間和時間方面都有巨大的優勢++。布隆過濾器儲存空間和插入/查詢時間都是常數(O(k))。另外, 雜湊函式相互之間沒有關係,方便由硬體並行實現。布隆過濾器不需要儲存元素本身,在某些對保密要求非常嚴格的場合有優勢。布隆過濾器可以表示全集,其它任何資料結構都不能;k和m相同,使用同一組雜湊函式的兩個布隆過濾器的交併差運算可以使用位操作進行。

缺點:但是布隆過濾器的缺點和優點一樣明顯。++誤算率是其中之一++。隨著存入的元素數量增加,誤算率隨之增加。但是如果元素數量太少,則使用散列表足矣。另外,++一般情況下不能從布隆過濾器中刪除元素++。我們很容易想到把位陣列變成整數陣列,每插入一個元素相應的計數器加1,這樣刪除元素時將計數器減掉就可以了。然而要保證安全地刪除元素並非如此簡單。首先我們必須保證刪除的元素的確在布隆過濾器裡面。這一點單憑這個過濾器是無法保證的。另外計數器迴繞也會造成問題。在降低誤算率方面,有不少工作,使得出現了很多布隆過濾器的變種。

image

檢索時,我們只要看看這些點是不是都是1就(大約)知道集合中有沒有它了:++如果這些點有任何一個0,則被檢元素一定不在;如果都是1,則被檢元素很可能在++。這就是布隆過濾器的基本思想。

Bloom Filter應用場景?

image

image

用Redis的Bitmap作為位陣列構建起來的可擴充套件的布隆過濾器。

解決方案對比

image

5. 無底洞問題優化

問題描述

  • 2010年,facebook有了3000個Memcache節點
  • 發現問題:”加”機器效能沒能提升,反而下降

問題原因

當存在的節點異常多的時候,IO的代價已經超過資料傳輸,上文提到的facebook的節點已經超過3000個,在這種情況下再增加節點已經沒法再提高效率了。

image

問題解決—優化IO

  • 命令本身的效率:例如sql優化,命令優化

  • 網路次數:減少通訊次數

  • 降低接入成本:長連/連線池,NIO等。

  • IO訪問合併:O(n)到O(1)過程:批量介面(mget),就是第八節文章中介紹的對於mget的四個方案。

6. 快取雪崩優化

什麼是快取雪崩?

從下圖可以很清晰出什麼是快取雪崩:由於快取層承載著大量請求,有效的保護了儲存層,但是如果快取層由於某些原因整體不能提供服務,於是所有的請求都會達到儲存層,儲存層的呼叫量會暴增,造成儲存層也會掛掉的情況。 快取雪崩的英文原意是 stampeding herd(奔逃的野牛),指的是快取層宕掉後,流量會像奔逃的野牛一樣,打向後端儲存。

image

如何防止快取雪崩?

  • 保證快取層服務高可用性。

和飛機都有多個引擎一樣,如果快取層設計成高可用的,即使個別節點、個別機器、甚至是機房宕掉,依然可以提供服務,例如前面介紹過的 Redis Sentinel 和 Redis Cluster 都實現了高可用。

  • 依賴隔離元件為後端限流並降級

無論是快取層還是儲存層都會有出錯的概率,可以將它們視同為資源。作為併發量較大的系統,假如有一個資源不可用,可能會造成執行緒全部 hang 在這個資源上,造成整個系統不可用。降級在高併發系統中是非常正常的:比如推薦服務中,如果個性化推薦服務不可用,可以降級補充熱點資料,不至於造成前端頁面是開天窗。

++在實際專案中,我們需要對重要的資源 ( 例如 Redis、 MySQL、 Hbase、外部介面 ) 都進行隔離++,讓每種資源都單獨執行在自己的執行緒池中,即使個別資源出現了問題,對其他服務沒有影響。但是執行緒池如何管理,比如如何關閉資源池,開啟資源池,資源池閥值管理,這些做起來還是相當複雜的,這裡推薦一個 Java 依賴隔離工具 Hystrix。超出範圍了。不再贅述。

7. 熱點key重建優化

問題

熱點key( 例如一個熱門的娛樂新聞)+較長的重建時間(可能是一個複雜計算,例如複雜的 SQL、多次 IO、多個依賴等)

就是說在高併發的情況下,某個key在快取中重建時間太長,以至於高併發下快取查不到,都去DB進行查詢。對於DB壓力很大,並且響應時間長。

image

三個目標:要減少快取重建次數、資料儘可能一致、減少潛在危險。

兩個解決:互斥鎖、永遠不過期

互斥鎖—setex,setnx

image

存在問題:有等待時間。

虛擬碼:

image

(1) 從 Redis 獲取資料,如果值不為空,則直接返回值,否則執行 (2.1) 和 (2.2)。

(2) 如果 set(nx 和 ex) 結果為 true,說明此時沒有其他執行緒重建快取,那麼當前執行緒執行快取構建邏輯。

(2.2) 如果 setnx(nx 和 ex) 結果為 false,說明此時已經有其他執行緒正在執行構建快取的工作,那麼當前執行緒將休息指定時間 ( 例如這裡是 50 毫秒,取決於構建快取的速度 ) 後,重新執行函式,直到獲取到資料。

永遠不過期

這裡我想了很久到底是什麼意思,,,我感覺這是一個場景:保證資料的定期更新。對於熱點key,無非是併發特別大一級重建快取時間比較長,如果直接設定過期時間,那麼時間到的時候,巨大的訪問量會壓迫到資料庫上,所以我們實際上,是不給他設定過期時間,但是不設定過期時間,怎麼做到定時更新呢?這裡的方案是給熱點key的val增加一個邏輯過期時間欄位,併發訪問的時候,判斷這個邏輯欄位的時間值是否大於當前時間,大於了說明要對快取進行更新了,那麼這個時候,依然讓所有執行緒訪問老的快取,因為快取並沒有設定過期,但是另開一個執行緒對快取進行重構。等重構成功,即執行了redis set操作之後,所有的執行緒就可以訪問到重構後的快取中的新的內容了。不知道我的理解是不是正確。

“永遠不過期”包含兩層意思:

從快取層面來看,確實沒有設定過期時間,所以不會出現熱點 key 過期後產生的問題,也就是“物理”不過期。

從功能層面來看,為每個 value 設定一個邏輯過期時間,當發現超過邏輯過期時間後,會使用單獨的執行緒去構建快取。

image

虛擬碼實現:

image

兩種方案對比

image

相關推薦

9.快取設計優化

1. 快取收益和成本 1.1 收益 加速讀寫 降低後端負載(降低mysql負載) 1.2 成本 資料不一致:快取層和資料層有時間視窗不一致,和更新策略有關 程式碼維護成本:多了一層快取邏輯 運維成本:例如redis cluster

Redis快取設計效能優化

Redis我們一般是用作快取,扛併發;或者用於某些特定的業務場景,比如前面說到redis各種資料型別的使用場景以及redis的哨兵和叢集模式。 這裡主要整理了下redis用作快取,存在的一些問題,以及改善方案。   簡單的流程就像這個樣子,一般請先到快取區獲取,如果快取沒有再到後端的資料庫去查詢。

算法設計優化之等價轉換

算法優化 等價轉換 Gergovia酒的交易 等價轉換與其說是一種算法的設計方法,更不說是一種算法思想。這種思想能有助於我們把復雜的問題簡單化,幫我們理清問題的思路,甚至能直接得出求解問題的方法。下面通過一道具體的題目來像讀者介紹這種思想。Gergovia酒的交易(Wine trading in

算法設計優化策略——滑動窗口

唯一的雪花“滑動窗口”和上篇博客中介紹的“等價轉換”一樣也為一種算法優化的思想。同樣,下面通過一個例子,來介紹這種思想。唯一的雪花(Unique snowflake,UVa 11572)輸入一個長度為n(n<=10^6)的序列A,找到一個盡量長的連續子序列AL~AR,使得該序列中沒有相同的元素。在讀完題

大數據量數據庫設計優化方案(SQL優化)

把他 like 後者 結果集 表鎖 ted detail 出了 解決方案 轉自:http://blog.sina.com.cn/s/blog_6c0541d50102wxen.html 一、數據庫結構的設計 如果不能設計一個合理的數據庫模型,不僅會增加客戶端

深入淺出分散式儲存的設計優化之道

隨著資訊化程度的不斷提高,全球資料日益膨脹。面對當前PB級的海量資料儲存需求,傳統的儲存系統在容量和效能的擴充套件上存在瓶頸。雲端儲存以其擴充套件性強、價效比高、容錯性好等優勢得到了業界的廣泛認同。由於其前瞻性,眾多企業都將其作為進軍雲端計算的第一步。分散式檔案系統和分散式塊儲存作為雲端儲存中重要的

高效能可擴充套件 MySQL資料庫架構設計優化

第1章 資料庫開發規範的制定 俗話說:“沒有規矩不成方圓”。這一章,我們就先來制定資料庫開發的各種規範,包括:資料庫命名規範、資料庫基本設計規範、資料庫索引設計規範、資料庫欄位設計規範、SQL開發規範以及資料庫操作規範。通過這些規範的制定可以指導並規範我們後續的開發工作,為我們以後的工作提供一個良好的基礎。.

jvm synchronized底層設計優化

通常來講synchronized被當做重量級鎖來使用,但其實它並不是一味地阻塞當前執行緒,而是通過鎖升級等方式進行了很多的優化。 一 重量級鎖(互斥同步或悲觀鎖) 最原始的,也是synchronized與生俱來的同步方式。 使用synchronized可以指定一

演算法設計優化程式設計 第十講 Subway

Subway Problem Description jiefangxuanyan and yiyi cat are universally acknowledged model couples(配偶). Once jiefangxuanyan has

【 專欄 】- 資料庫實戰開發設計優化

作者:楊秀璋 學歷:本科-北京理工大學            碩士-北京理工大學 現任教於貴財財經大學資訊學院 http://www.eastmountyxz.com 簡介:自幼受貴州大山的薰陶,養成了誠實質樸的性格。經過寒窗苦讀,考入BIT,為完成自己的教師夢,放棄IT、航天等工

golang資料快取設計原始碼實現

1. 實際需求 資料快取是指將一些資料儲存到快取中,以調高提高系統讀效能。使用時再從快取中取回。 它也是更高階快取特性的基礎,對於讀多寫少的應用場景,我們經常使用快取來進行優化。 1.1 應用場景 例如對於使用者的餘額資訊表account(uid, mone

資料庫設計優化總結(1)

一、資料庫的設計的幾點措施 1.關聯表的關聯欄位名稱必須相同。 2.欄位的定義的前兩位是表名,第三位是下劃線,保證規範。 3.常用欄位採用固定單詞,如id 4.如果只有一個索引,索引的名字希望和表名相同,如果是多個,那麼就用表明下劃線欄位名。 5.關聯欄位儘可能為數字型別。

Java開發面試:高併發秒殺系統如何設計優化

      如今處在一個大資料時代,應屆生找工作面試高階Java開發工程師時,經常會被問一些和大資料相關的問題,比如大資料處理問題、高併發處理問題、資料優化問題等,筆者曾經遇到兩個比較經典的問題,高併發秒殺系統的設計優化問題和大資料檔案排序問題。在這裡總結了高併發秒殺系統

高併發大資料量的資料庫的設計優化

一、資料庫結構的設計。       資料庫模型設計的不合理,不僅會導致客戶端和服務端的程式設計和維護困難,而且會影響到系統實際執行的效能。在系統開始實施之前,完備的資料庫模型的設計是必要的。       在一個系統分析設計階段,由於資料量小,系統負荷低,我們往往只注重功能的

如何設計優化高效能的HTTP介面型應用?

【一個故障引發的話題】 最近,專案中的簡訊模組收到一個故障日誌,要求我協助調查一下: 2010-05-07 09:22:07,221 [?:?] INFO  httpclient.HttpMethodDirector - Retrying request :org.a

Redis設計優化的幾點建議

Redis+Spring jedis:設計與優化的幾點建議 1.  設計: a)   Redis適用的場合為需要快速的存取資料,資料之間的關係不是很緊密,因此資料結構設計時儘量設計為獨立。 b)   Redis不適合對值的查詢,如果不可避免會使用到,應該設計輔助的key值來

Android圖片快取分析優化

protected int sizeOf(String key, Drawable value) { if(value!=null) { if (value instanceof BitmapDrawable) { Bitmap bitmap = ((BitmapDraw

淺談數據庫索引的結構設計優化

子句 項目 結果 使用 enter tex 設有 簡單的 相同 淺談數據庫索引的結構設計與優化 一. 了解數據庫索引的必要性   對於稍微數據量大一點的表,如果不適用索引,那麽性能效率都會很低;如果繞開了索引,直接進行分區分表,數據庫集群讀寫分離來解決性能問題的

優化效能到應對峰值流量:微博快取服務化的設計實踐

導讀:高可用架構 8 月 20 日在深圳舉辦了『網際網路架構:從 1 到 100』為主題的閉門私董會研討及技術沙龍,本文是陳波分享的微博快取服務的演進歷程。 陳波,08 年加入新浪,參與 IM 系統的後端研發。09 年之後從事新浪微博的系統研發及架構工作,在海量資料儲存、峰值訪問、規模化快取服務及

《數據庫系統概論》 -- 9 查詢處理查詢優化

51cto csdn 查詢 優化 安全性 步驟 mysq sql tails 查詢處理步驟 查詢分析 對查詢語句進行掃描、詞法分析和語法分析。 查詢檢查 對合法的