為什麼Redis這麼快?5分鐘成為Redis高手
Redis簡介
Redis 是 C 語言開發的一個開源高效能鍵值對的記憶體資料庫,可以用來做資料庫、快取、訊息中介軟體等場景,是一種 NoSQL(not-only sql,非關係型資料庫)的資料庫。
Redis特點
優秀的效能,資料是儲存在記憶體中,讀寫速度非常快,可支援併發10W QPS。
-
單執行緒單程式,是執行緒安全的,採用 IO 多路複用
-
可作為分散式鎖
-
支援十種資料型別
-
支援資料持久化
可以作為訊息中介軟體使用,支援訊息釋出及訂閱。
資料型別
下表是我列舉的 常用五種資料型別的特性及其使用場景:
快取
-
直接透過 RedisTemplate 使用
-
透過 Spring Cache 整合 Redis(也就是註解的方式)
使用快取遇到的問題
(1)資料一致性
(2)快取雪崩
這就是雪崩事件,是 Redis 快取中最致命問題之一(有一個是穿透)。大家可以看看下圖:
出現雪崩事件後不要急不要慌,我們可以在事故前中後三個方面來思考解決方案:
-
事故前:redis 高可用方案,主從+哨兵,叢集方案,避免全盤崩潰; -
事故中:較少資料庫的壓力,本地 Ehcache 快取+限流及降級,避免超過資料庫承受壓力; -
事故後:做 Redis 持久化,一旦 Redis 重啟,可從磁碟中快速恢復資料。
我們來看看改造後的資料流程,假設使用者A傳送一個請求,系統先請求本地 Ehcache 是否有資料,如果沒有再去 Redis 請求資料,如果沒有再去資料庫請求資料,獲取到資料後同步到 Ehcache 和 redis。
這樣做的好處是:
-
資料庫安全 : 在限流元件可用的情況下,資料庫不會掛掉,限流根據確保了每秒多少請求能透過;
-
部分請求可以被處理 : 資料庫沒掛,就意味著至少2/5的請求可以被處理掉; -
高峰時期部分請求無法處理到,需要使用者多次點選,因為只有 2/5 的請求被處理,剩下的請求,使用者刷不出來介面,需要多點選幾次; -
redis 設定的快取失效時間不是設定成同一個時間,可根據功能、業務、請求介面靈活設定快取時間: setRedis(key, value, time+Math.random()*10000);
(3)快取穿透
快取穿透是指快取和資料庫中都沒有的資料,使用者(駭客)不斷髮起請求,導致請求直接查詢資料庫,這種惡意行為攻擊場景的會直接導致資料庫掛掉,資料流程如下圖所示:
-
在請求介面層可以做一些校驗,比如使用者籤權、引數校驗,不合法的請求直接return; -
還可以針對有效id做認證或直接攔截,不符合的 id 直接過濾或採用統一key儲存到redis,下次不合法的id請求時,直接到快取中獲取資料;
-
採用 redis 的高介面 Bloom Filter,利用高效的資料結構和演算法快速判斷出你這個 Key 是否在資料庫中存在,不存在你 return 就好了,存在你就去查 DB 重新整理 KV 再 return。
(4) 快取擊穿
上面講的穿透是針對大面積資料請求,那麼擊穿是針對一點(一個key)來來導致redis異常,但某個key是非常熱點,請求非常頻繁,處於集中式訪問現象,當這個key失效(過期)時,大量的請求就會擊穿了快取,直接請求資料庫,就像在屏障中鑿開了一個洞。
-
資料基本不變 : 熱點資料value基本不更新時,可以設定成永不過期 -
資料更新不頻繁 : 快取重新整理流程耗時較少時,可採用redis、zookeeper等分散式中介軟體的分散式互斥鎖或者本地互斥鎖保證少量的請求能請求到資料庫並重新更新快取,其他的流程等鎖釋放後才可以訪問新快取 -
資料更新頻繁 : 採用定時執行緒,在快取過期前主動重新構建快取或延長過期時間,保證所有的請求能一直訪問快取
為什麼 Redis 這麼快
-
使用類似於 HashMap 的原理,HashMap 的查詢及操作的時間複雜度是O(1),且絕大多數請求是純碎的記憶體操作,資料存在記憶體中;
-
資料結構簡單,對資料操作也簡單,基於KV;
-
不錯死鎖現象採用單執行緒操作,避免了不必要的上下文切換及競爭條件,不存在CPU切換現象,也就不存在考慮各種鎖的問題;
-
使用非阻塞IO,多路複用IO模型。
Redis 淘汰策略
-
volatile為字首的策略都是從已過期的資料集中進行淘汰。
-
allkeys為字首的策略都是面向所有key進行淘汰。
-
LRU(least recently used)最近最少用到的。
-
LFU(Least Frequently Used)最不常用的。
-
它們的觸發條件都是Redis使用的記憶體達到閾值時。
Redis持久化
Redis 持久化策略有兩種:
-
RDB
:快照形式是直接把記憶體中的資料儲存到一個 dump 的檔案中,定時儲存,儲存策略。 -
AOF
:把所有的對 Redis 的伺服器進行修改的命令都存到一個檔案裡,命令的集合。Redis 預設是快照 RDB 的持久化方式。
如果非常關心你的資料,但仍然可以承受數分鐘內的資料丟失,那麼可以額只使用 RDB 持久。
AOF 將 Redis 執行的每一條命令追加到磁碟中,處理巨大的寫入會降低Redis的效能,不知道你是否可以接受。
資料庫備份和災難恢復:定時生成 RDB 快照非常便於進行資料庫備份,並且 RDB 恢復資料集的速度也要比 AOF 恢復的速度快。
當然了,Redis 支援同時開啟 RDB 和 AOF,系統重啟後,Redis 會優先使用 AOF 來恢復資料,這樣丟失的資料會最少。
Redis主從複製
-
從節點執行 slaveof[masterIP][masterPort],儲存主節點資訊;
-
從節點中的定時任務發現主節點資訊,建立和主節點的 Socket 連線;
-
從節點傳送 Ping 訊號,主節點返回 Pong,兩邊能互相通訊;
-
連線建立後,主節點將所有資料傳送給從節點(資料同步);
-
主節點把當前的資料同步給從節點後,便完成了複製的建立過程;
接下來,主節點就會持續的把寫命令傳送給從節點,保證主從資料一致性。
Redis哨兵模式
我們先說說主從複製會存在問題:
-
一旦主節點當機,從節點晉升為主節點,同時需要修改應用方的主節點地址,還需要命令所有從節點去複製新的主節點,整個過程需要人工干預。
-
主節點的寫能力受到單機的限制。
-
主節點的儲存能力受到單機的限制。
-
原生複製的弊端在早期的版本中也會比較突出,比如:
Redis 複製中斷後,從節點會發起 psync。
-
此時如果同步不成功,則會進行全量同步,主庫執行全量備份的同時,可能會造成毫秒或秒級的卡頓。
哨兵的架構模式如下:
該系統可以執行以下四個任務:
-
監控: 不斷檢查主伺服器和從伺服器是否正常執行。
-
通知: 當被監控的某個 Redis 伺服器出現問題,Sentinel 透過 API 指令碼向管理員或者其他應用程式發出通知。
-
自動故障轉移: 當主節點不能正常工作時,Sentinel 會開始一次自動的故障轉移操作,它會將與失效主節點是主從關係的其中一個從節點升級為新的主節點,並且將其他的從節點指向新的主節點,這樣人工干預就可以免了。
-
配置提供者: 在 Redis Sentinel 模式下,客戶端應用在初始化時連線的是 Sentinel 節點集合,從中獲取主節點的資訊 。
來源:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70013542/viewspace-2997831/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Redis為什麼這麼快?Redis
- 為什麼要用Redis?Redis為什麼這麼快?(來自知乎)Redis
- redis為什麼快Redis
- Redis為什麼那麼快?Redis
- 硬核!15張圖解Redis為什麼這麼快圖解Redis
- Redis是單執行緒的,但Redis為什麼這麼快?Redis執行緒
- Redis 為什麼這麼快?這才是最完美的回答Redis
- 為什麼redis是單執行緒的以及為什麼這麼快?Redis執行緒
- 破玩意 | Redis 為什麼那麼快Redis
- redis是單執行緒的,為什麼這麼快Redis執行緒
- 京東二面,Redis為什麼那麼快?Redis
- 比Redis快5倍的中介軟體,究竟為什麼這麼快?Redis
- 為什麼要使用Redis做快取Redis快取
- 為什麼要用RedisRedis
- StackExchange.Redis跑起來,為什麼這麼溜?Redis
- Redis為何這麼快–資料儲存角度Redis
- redis淘汰+過期雙向保證高可用 | redis 為什麼那麼快?Redis
- 為什麼要使用 Redis?Redis
- Nginx 為什麼這麼快?Nginx
- Redis單執行緒,為什麼速度快Redis執行緒
- redis字典快速對映+hash釜底抽薪+漸進式rehash | redis為什麼那麼快Redis
- 快速排序為什麼這麼快?排序
- 我們為什麼要用RedisRedis
- 為什麼要用Redis叢集?Redis
- 為什麼要做Redis分割槽?Redis
- Redis 為何這麼快?聊聊它的資料結構~Redis資料結構
- 為什麼 Redis 要有哨兵機制?Redis
- redis為什麼變慢了?這些原因你都知道嗎Redis
- Google Analytics為什麼會這麼快Go
- Redis為什麼快及其高可用技術的幾種方案Redis
- 我們們一起來談談,redis為什麼快?Redis
- Redis為什麼要使用跳躍表Redis
- 為什麼使用Redis及其產品定位Redis
- 【redis前傳】redis整數集為什麼不能降級Redis
- Redis為什麼是單執行緒?為什麼有如此高的效能?Redis執行緒
- [譯][A crash course in WebAssembly] 為什麼WebAssembly這麼快Web
- 阿里面試這樣問:redis 為什麼把簡單的字串設計成 SDS?阿里面試Redis字串
- redis為什麼要提供pipeline功能Redis