在 redis 中有五種資料型別
redis 內部使用乙個 redisobject 物件來表示所有的 key 和 value。
redis 記憶體淘汰指的是使用者儲存的一些鍵被可以被 redis 主動地從例項中刪除,從而產生讀 miss 的情況,那麼 redis 為什麼要有這種功能?這就是我們需要**的設計初衷。redis 最常見的兩種應用場景為快取和持久儲存,首先要明確的乙個問題是記憶體淘汰策略更適合於那種場景?是持久儲存還是快取?
假設我們有乙個 redis 伺服器,伺服器物理記憶體大小為 1g 的,我們需要存在 redis 中的資料量很小,這看起來似乎足夠用很長時間了,隨著業務量的增長,我們放在 redis 裡面的資料越來越多了,資料量大小似乎超過了 1g,但是應用還可以正常執行,這是因為作業系統的可見記憶體並不受物理記憶體限制,而是虛擬記憶體,物理記憶體不夠用沒關係,作業系統會從硬碟上劃出一片空間用於構建虛擬記憶體,比如32位的作業系統的可見記憶體大小為2^32
,而使用者空間的可見記憶體要小於2^32
很多,大概是 3g 左右。好了,我們慶幸作業系統為我們做了這些,但是我們需要知道這背後的代價是不菲的,不合理的使用記憶體有可能發生頻繁的 swap,頻繁 swap 的代價是慘痛的。所以回過頭來看,作為有追求的程式設計師,我們還是要小心翼翼地使用好每塊記憶體,把使用者**能解決的問題盡量不要拋給作業系統解決。
記憶體的淘汰機制的初衷是為了更好地使用記憶體,用一定的快取 miss 來換取記憶體的使用效率。
作為 redis 使用者,我們如何使用 redis 提供的這個特性呢?
# maxmemory
我們可以通過配置redis.conf
中的maxmemory
這個值來開啟記憶體淘汰功能,至於這個值有什麼意義,我們可以通過了解記憶體淘汰的過程來理解它的意義:
maxmemory
為 0 的時候表示我們對 redis 的記憶體使用沒有限制
記憶體淘汰只是 redis 提供的乙個功能,為了更好地實現這個功能,必須為不同的應用場景提供不同的策略,記憶體淘汰策略講的是為實現記憶體淘汰我們具體怎麼做,要解決的問題包括淘汰鍵空間如何選擇?在鍵空間中淘汰鍵如何選擇?
redis 提供了下面幾種淘汰策略供使用者選擇,其中預設的策略為noeviction
策略:
這裡補充一下主鍵空間和設定了過期時間的鍵空間,舉個例子,假設我們有一批鍵儲存在redis中,則有那麼乙個雜湊表用於儲存這批鍵及其值,如果這批鍵中有一部分設定了過期時間,那麼這批鍵還會被儲存到另外乙個雜湊表中,這個雜湊表中的值對應的是鍵被設定的過期時間。設定了過期時間的鍵空間為主鍵空間的子集。
我們了解了 redis 大概提供了這麼幾種淘汰策略,那麼如何選擇呢?淘汰策略的選擇可以通過下面的配置指定:
# maxmemory-policy noeviction
但是這個值填什麼呢?為解決這個問題,我們需要了解我們的應用請求對於 redis 中儲存的資料集的訪問方式以及我們的訴求是什麼。同時 redis 也支援 runtime 修改淘汰策略,這使得我們不需要重啟 redis 例項而實時的調整記憶體淘汰策略。
下面看看幾種策略的適用場景:
另外,volatile-lru
策略和volatile-random
策略適合我們將乙個redis例項既應用於快取和又應用於持久化儲存的時候,然而我們也可以通過使用兩個 redis 例項來達到相同的效果,值得一提的是將key設定過期時間實際上會消耗更多的記憶體,因此我們建議使用allkeys-lru
策略從而更有效率的使用記憶體。
上面提到的 lru(least recently used)策略,實際上 redis 實現的 lru 並不是可靠的 lru,也就是名義上我們使用 lru 演算法淘汰鍵,但是實際上被淘汰的鍵並不一定是真正的最久沒用的,這裡涉及到乙個權衡的問題,如果需要在全部鍵空間內搜尋最優解,則必然會增加系統的開銷,redis 是單執行緒的,也就是同乙個例項在每乙個時刻只能服務於乙個客戶端,所以耗時的操作一定要謹慎。為了在一定成本內實現相對的 lru,早期的 redis 版本是基於取樣的 lru,也就是放棄全部鍵空間內搜尋解改為取樣空間搜尋最優解。自從 redis3.0 版本之後,redis 作者對於基於取樣的 lru 進行了一些優化,目的是在一定的成本內讓結果更靠近真實的 lru。
redis 有兩種持久化機制:
rdb 持久化方式會在乙個特定的間隔儲存那個時間點的乙個資料快照
aof 持久化方式則會記錄每乙個伺服器收到的寫操作。在服務啟動時,這些記錄的操作會逐條執行從而重建出原來的資料。寫操作命令記錄的格式跟 redis 協議一致,以追加的方式進行儲存
redis 的持久化是可以禁用的,就是說你可以讓資料的生命週期只存在於伺服器的執行時間裡。兩種方式的持久化是可以同時存在的,但是當 redis 重啟時,aof 檔案會被優先用於重建資料。
將請求傳送到任意節點,接收到請求的節點會將查詢請求傳送到正確的節點上執行。
sentinel
因為 cpu 不是 redis 的瓶頸。redis 的瓶頸最有可能是機器記憶體或者網路頻寬。(以上主要來自官方 faq)既然單執行緒容易實現,而且 cpu 不會成為瓶頸,那就順理成章地採用單執行緒的方案了。
在大促或者某些特殊情況下,某些頁面占用了一些稀缺服務資源,在緊急情況下可以對其整個降級,以達到丟卒保帥;
比如商品詳情頁中的商家部分因為資料錯誤了,此時需要對其進行降級;
比如商品詳情頁上有推薦資訊/配送至等非同步載入的請求,如果這些資訊響應慢或者後端服務有問題,可以進行降級;
比如渲染商品詳情頁時需要呼叫一些不太重要的服務:相關分類、熱銷榜等,而這些服務在異常情況下直接不獲取,即降級即可;
比如多級快取模式,如果後端服務有問題,可以降級為唯讀快取,這種方式適用於對讀一致性要求不高的場景;
比如秒殺搶購,我們可以只進行cache的更新,然後非同步同步扣減庫存到db,保證最終一致性即可,此時可以將db降級為cache。
在大促活動時,可以將爬蟲流量導向靜態頁或者返回空資料,從而保護後端稀缺資源。
自動降級是根據系統負載、資源使用情況、sla等指標進行降級。
當訪問的資料庫/http服務/遠端呼叫響應慢或者長時間響應慢,且該服務不是核心服務的話可以在超時後自動降級;比如商品詳情頁上有推薦內容/評價,但是推薦內容/評價暫時不展示對使用者購物流程不會產生很大的影響;對於這種服務是可以超時降級的。如果是呼叫別人的遠端服務,和對方定義乙個服務響應最大時間,如果超時了則自動降級。
**:有夢想的鹹魚
redis快取使用
compile group org.springframework.boot name spring boot starter data redis version 2.3.2.release spring 主要引數 redis host localhost port 6379 passport 預...
SpringBoot使用Redis快取
1.配置pom檔案 org.springframework.boot spring boot starter data redis org.springframework.boot spring boot starter cache net.sf.ehcache ehcache 2.修改專案啟動類,...
django使用redis快取
遇到問題 開發過程中某乙個功能模組載入速度慢且該功能所需資料更新頻率低。開發環境 window10,python2.7,django1.11.13 找到redis x64 3.2.100.msi django中安裝pip install django redis django中的中配置的redis的...