Redis核心原理

1.jpg

Redis的一些核心原理。

Redis系列介紹:

Redis的基礎介紹與安裝使用步驟:https://blog.csdn.net/qq_34002221/article/details/84963588
Redis的基礎數據結構與使用: https://blog.csdn.net/qq_34002221/article/details/84981299
Redis核心原理:https://blog.csdn.net/qq_34002221/article/details/84996919
Redis 5.0.2 版本的高可用集羣搭建:https://blog.csdn.net/qq_34002221/article/details/85011041
Redis 5 版本的高可用集羣的水平擴展:https://blog.csdn.net/qq_34002221/article/details/85019752
Redis 5 集羣選舉原理分析:https://blog.csdn.net/qq_34002221/article/details/85042536

優秀博客:

https://blog.csdn.net/hopeztm/article/details/79547052?utm_source=blogxgwz0
https://www.cnblogs.com/qq78292959/archive/2013/09/21/3331032.html


一、Redis的單線程和高性能
Redis 單線程爲什麼還能這麼快?

因爲它所有的數據都在內存中,所有的運算都是內存級別的運算(納秒),而且單線程避免了多線程的切換(上下文切換)性能損耗問題。正因爲 Redis 是單線程,所以要小心使用 Redis 指令,對於那些耗時的指令(比如keys),一定要謹慎使用,一不小心就可能會導致 Redis 卡頓。

Redis 單線程如何處理那麼多的併發客戶端連接?

Redis的IO多路複用:redis利用epoll來實現IO多路複用,將連接信息和事件放到隊列中,依次放到文件事件分派器,事件分派器將事件分發給事件處理器。
Nginx也是採用IO多路複用原理解決C10K問題。
c10k:https://www.jianshu.com/p/ba7fa25d3590

1.png

持久化
RDB快照(snapshot)

在默認情況下, Redis 將內存數據庫快照保存在名字爲dump.rdb的二進制文件中。
你可以對 Redis 進行設置, 讓它在N秒內數據集至少有M個改動這一條件被滿足時, 自動保存一次數據集。
比如說, 以下設置會讓 Redis 在滿足60秒內有至少有1000個鍵被改動”這一條件時, 自動保存一次數據集:

save 60 1000

redis.conf文件裏面有默認的3種情況,3種是或的關係
2.png

AOF(append-only file)

快照功能並不是非常耐久(durable): 如果 Redis 因爲某些原因而造成故障停機, 那麼服務器將丟失最近寫入、且仍未保存到快照中的那些數據。從 1.1 版本開始, Redis 增加了一種完全耐久的持久化方式: AOF 持久化,將修改的每一條指令記錄進文件
你可以通過修改配置文件來打開 AOF 功能:

appendonly yes

開啓後,每當 Redis 執行一個改變數據集的命令時(比如SET), 這個命令就會被追加到 AOF 文件的末尾。
這樣的話, 當 Redis 重新啓時, 程序就可以通過重新執行 AOF 文件中的命令來達到重建數據集的目的。
你可以配置 Redis 多久纔將數據fsync到磁盤一次。

有三個選項:

每次有新命令追加到 AOF 文件時就執行一次fsync:非常慢,也非常安全。

每秒fsync一次:足夠快(和使用 RDB 持久化差不多),並且在故障時只會丟失 1 秒鐘的數據。

從不fsync:將數據交給操作系統來處理。更快,也更不安全的選擇。

推薦(並且也是默認)的措施爲每秒fsync一次, 這種fsync策略可以兼顧速度和安全性。
RDB 和 AOF ,我應該用哪一個?

如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失, 那麼你可以只使用 RDB 持久化。
有很多用戶都只使用 AOF 持久化, 但我們並不推薦這種方式: 因爲定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快。

Redis 4.0 混合持久化

重啓 Redis 時,我們很少使用 rdb 來恢復內存狀態,因爲會丟失大量數據。我們通常使用 AOF 日誌重放,但是重放 AOF 日誌性能相對 rdb 來說要慢很多,這樣在 Redis 實例很大的情況下,啓動需要花費很長的時間。 Redis 4.0 爲了解決這個問題,帶來了一個新的持久化選項——混合持久化。AOF在重寫(aof文件裏可能有太多沒用指令,所以aof會定期根據內存的最新數據生成aof文件)時將重寫這一刻之前的內存rdb快照文件的內容和增量的 AOF修改內存數據的命令日誌文件存在一起,都寫入新的aof文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件纔會進行改名,原子的覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換;

aof 根據配置規則在後臺自動重寫,也可以人爲執行命令bgrewriteaof重寫AOF。 於是在 Redis 重啓的時候,可以先加載 rdb 的內容,然後再重放增量 AOF 日誌就可以完全替代之前的 AOF 全量文件重放,重啓效率因此大幅得到提升。

開啓混合持久化:
aof-use-rdb-preamble yes 
混合持久化aof文件結構

3.png

緩存淘汰策略(解決數據熱點問題)

當 Redis 內存超出物理內存限制時,內存的數據會開始和磁盤產生頻繁的交換 (swap)。交換會讓 Redis 的性能急劇下降,對於訪問量比較頻繁的 Redis 來說,這樣龜速的存取效率基本上等於不可用。

在生產環境中我們是不允許 Redis 出現交換行爲的,爲了限制最大使用內存,Redis 提供了配置參數 maxmemory 來限制內存超出期望大小。

當實際內存超出 maxmemory 時,Redis 提供了幾種可選策略 (maxmemory-policy) 來讓用戶自己決定該如何騰出新的空間以繼續提供讀寫服務。

noeviction

不會繼續服務寫請求 (DEL 請求可以繼續服務),讀請求可以繼續進行。這樣可以保證不會丟失數據,但是會讓線上的業務不能持續進行。這是默認的淘汰策略。

volatile-lru

嘗試淘汰設置了過期時間的 key,最少使用的 key 優先被淘汰。沒有設置過期時間的 key 不會被淘汰,這樣可以保證需要持久化的數據不會突然丟失。

volatile-ttl

跟上面一樣,除了淘汰的策略不是 LRU,而是 key 的剩餘壽命 ttl 的值,ttl 越小越優先被淘汰。

volatile-random

跟上面一樣,不過淘汰的 key 是過期 key 集合中隨機的 key。

 allkeys-lru

區別於 volatile-lru,這個策略要淘汰的 key 對象是全體的 key 集合,而不只是過期的 key 集合。這意味着沒有設置過期時間的 key 也會被淘汰。
allkeys-random跟上面一樣,不過淘汰的策略是隨機的 key。

 volatile-xxx 

策略只會針對帶過期時間的 key 進行淘汰,allkeys-xxx 策略會對所有的 key 進行淘汰。如果你只是拿 Redis 做緩存,那應該使用 allkeys-xxx,客戶端寫緩存時不必攜帶過期時間。如果你還想同時使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,這樣可以保留沒有設置過期時間的 key,它們是永久的 key 不會被 LRU 算法淘汰。


如有問題歡迎留言,感覺有幫助,可以點個喜歡:)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章