Redis核心原理詳細解說
1、Redis為什么這么快
C語言編寫
網(wǎng)絡(luò)IO是nio
單線程避免了多線程上下文切換造成的性能損耗
在內(nèi)存中運算速度快
2、Redis網(wǎng)絡(luò)模型
IO多路復用(reactor)
redis利用epoll實現(xiàn)IO多路復用,將連接信息和事件放到隊列中,依次放到文件事件分派器,事件分派器將事件分發(fā)給事件處理器。

3、Redis數(shù)據(jù)結(jié)構(gòu)

4、Redis持久化
RDB快照(snapshot)
配置# save 60 1000 //關(guān)閉RDB只需要將所有的save保存策略注釋掉即可

AOF(append-only file)
將修改的每一條指令記錄進文件appendonly.aof中(先寫入os cache,每隔一段時間fsync到磁盤)。
AOF重寫:AOF文件里可能有太多沒用指令,所以AOF會定期根據(jù)內(nèi)存的最新數(shù)據(jù)生成aof文件。AOF重寫redis會fork出一個子進程去做(與bgsave命令類似),不會對redis正常命令處理有太多影響。bgrewriteao手動重寫。
Redis 4.0 混合持久化:aof-use-rdb-preamble yes
如果開啟了混合持久化,AOF在重寫時,不再是單純將內(nèi)存數(shù)據(jù)轉(zhuǎn)換為RESP命令寫入AOF文件,而是將重寫這一刻之前的內(nèi)存做RDB快照處理,并且將RDB快照內(nèi)容和增量的AOF修改內(nèi)存數(shù)據(jù)的命令存在一起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會進行改名,覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換。于是在 Redis 重啟的時候,可以先加載 RDB 的內(nèi)容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重啟效率大幅得到提升。

RDB與AOF區(qū)別

Redis數(shù)據(jù)備份策略
- (1)寫crontab定時調(diào)度腳本,每小時都copy一份rdb或aof的備份到一個目錄中去,僅僅保留最近48小時的備份。
- (2)每天都保留一份當日的數(shù)據(jù)備份到一個目錄中去,可以保留最近1個月的備份。
- (3)每次copy備份的時候,都把太舊的備份給刪了。
- (4)每天晚上將當前機器上的備份復制一份到其他機器上,以防機器損壞。
5、Redis管道(Pipeline)
客戶端可以一次性發(fā)送多個請求而不用等待服務(wù)器的響應(yīng),待所有命令都發(fā)送完后再一次性讀取服務(wù)的響應(yīng),這樣可以極大的降低多條命令執(zhí)行的網(wǎng)絡(luò)傳輸開銷,管道執(zhí)行多條命令的網(wǎng)絡(luò)開銷實際上只相當于一次命令執(zhí)行的網(wǎng)絡(luò)開銷。需要注意到是用pipeline方式打包命令發(fā)送,redis必須在處理完所有命令前先緩存起所有命令的處理結(jié)果。打包的命令越多,緩存消耗內(nèi)存也越多。所以并不是打包的命令越多越好。
pipeline中發(fā)送的每個command都會被server立即執(zhí)行,如果執(zhí)行失敗,將會在此后的響應(yīng)中得到信息;也就是pipeline并不是表達“所有command都一起成功”的語義,管道中前面命令失敗,后面命令不會有影響,繼續(xù)執(zhí)行。
6、Redis使用lua腳本
- 1、減少網(wǎng)絡(luò)開銷:本來5次網(wǎng)絡(luò)請求的操作,可以用一個請求完成,原先5次請求的邏輯放在redis服務(wù)器上完成。使用腳本,減少了網(wǎng)絡(luò)往返時延。這點跟管道類似。
- 2、原子操作:Redis會將整個腳本作為一個整體執(zhí)行,中間不會被其他命令插入。管道不是原子的,不過redis的批量操作命令(類似mset)是原子的。
- 3、替代redis的事務(wù)功能:redis自帶的事務(wù)功能很雞肋,而redis的lua腳本幾乎實現(xiàn)了常規(guī)的事務(wù)功能,官方推薦如果要使用redis的事務(wù)功能可以用redis lua替代。
7、Redis分布式鎖
nx通過共享內(nèi)存實現(xiàn)
8、Redis主從架構(gòu)




9、Redis哨兵架構(gòu)
sentinel哨兵是特殊的redis服務(wù),不提供讀寫服務(wù),主要用來監(jiān)控redis實例節(jié)點。

10、Redis集群

11、Redis優(yōu)化
- 1、redis配置
合理的配置最大連接數(shù);最大,最小空閑數(shù)。
- 2、規(guī)約
- 3、慢日志
slowlog
Redis慢日志命令說明: config get slow* #查詢有關(guān)慢日志的配置信息 config set slowlog-log-slower-than 20000 #設(shè)置慢日志使時間閾值,單位微秒,此處為20毫秒,即超過20毫秒的操作都會記錄下來,生產(chǎn)環(huán)境建議設(shè)置1000,也就是1ms,這樣理論上redis并發(fā)至少達到1000,如果要求單機并發(fā)達到1萬以上,這個值可以設(shè)置為100 config set slowlog-max-len 1024 #設(shè)置慢日志記錄保存數(shù)量,如果保存數(shù)量已滿,會刪除最早的記錄,最新的記錄追加進來。記錄慢查詢?nèi)罩緯rRedis會對長命令做截斷操作,并不會占用大量內(nèi)存,建議設(shè)置稍大些,防止丟失日志 config rewrite #將服務(wù)器當前所使用的配置保存到redis.conf slowlog len #獲取慢查詢?nèi)罩玖斜淼漠斍伴L度 slowlog get 5 #獲取最新的5條慢查詢?nèi)罩?。慢查詢?nèi)罩居伤膫€屬性組成:標識ID,發(fā)生時間戳,命令耗時,執(zhí)行命令和參數(shù) slowlog reset #重置慢查詢?nèi)罩?/pre>
- 4、操作系統(tǒng)配置
(1)vm.swapiness
如果linux內(nèi)核版本<3.5,那么swapiness設(shè)置為0,這樣系統(tǒng)寧愿swap也不會oom killer(殺掉進程)
如果linux內(nèi)核版本>=3.5,那么swapiness設(shè)置為1,這樣系統(tǒng)寧愿swap也不會oom killer
cat /proc/version #查看linux內(nèi)核版本 echo 1 > /proc/sys/vm/swappiness echo vm.swapiness=1 >> /etc/sysctl.conf cat /proc/sys/vm/overcommitmemory echo "vm.overcommitmemory=1" >> /etc/sysctl.conf sysctl vm.overcommit_memory=1
(2)合理設(shè)置文件句柄數(shù)
ulimit -a #查看系統(tǒng)文件句柄數(shù),看open files那項 ulimit -n 65535 #設(shè)置系統(tǒng)文件句柄數(shù)
12、Redis問題
緩存穿透
緩存穿透是指查詢一個根本不存在的數(shù)據(jù),緩存層和存儲層都不會命中,通常出于容錯的考慮,如果從存儲層查不到數(shù)據(jù)則不寫入緩存層。緩存穿透將導致不存在的數(shù)據(jù)每次請求都要到存儲層去查詢,失去了緩存保護后端存儲的意義。
- 第一,自身業(yè)務(wù)代碼或者數(shù)據(jù)出現(xiàn)問題。
- 第二,一些惡意攻擊、爬蟲等造成大量空命中。
(1)緩存空對象
(2)布隆過濾器
緩存失效(擊穿)
由于大批量緩存在同一時間失效可能導致大量請求同時穿透緩存直達數(shù)據(jù)庫,可能會造成數(shù)據(jù)庫瞬間壓力過大甚至掛掉,對于這種情況我們在批量增加緩存時最好將這一批數(shù)據(jù)的緩存過期時間設(shè)置為一個時間段內(nèi)的不同時間。
緩存雪崩
- (1)保證緩存層服務(wù)高可用性,比如使用Redis Sentinel或Redis Cluster。
- (2)依賴隔離組件為后端限流熔斷并降級。比如使用Sentinel或Hystrix限流降級組件。比如服務(wù)降級,我們可以針對不同的數(shù)據(jù)采取不同的處理方式。當業(yè)務(wù)應(yīng)用訪問的是非核心數(shù)據(jù)(例如電商商品屬性,用戶信息等)時,暫時停止從緩存中查詢這些數(shù)據(jù),而是直接返回預(yù)定義的默認降級信息、空值或是錯誤提示信息;當業(yè)務(wù)應(yīng)用訪問的是核心數(shù)據(jù)(例如電商商品庫存)時,仍然允許查詢緩存,如果緩存缺失,也可以繼續(xù)通過數(shù)據(jù)庫讀取。
- (3)提前演練。在項目上線前,演練緩存層宕掉后,應(yīng)用以及后端的負載情況以及可能出現(xiàn)的問題,在此基礎(chǔ)上做一些預(yù)案設(shè)定。
到此這篇關(guān)于Redis核心原理詳細解說的文章就介紹到這了,更多相關(guān)Redis原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis 如何批量設(shè)置過期時間(PIPLINE的使用)
有時候我們并不希望redis的key一直存在。例如緩存,驗證碼等數(shù)據(jù),我們希望它們能在一定時間內(nèi)自動的被銷毀。本文就詳細的介紹一下Redis 如何批量設(shè)置過期時間,感興趣的可以了解一下2021-11-11

