下面由redis教程欄目給大家介紹分析redis原理及實(shí)現(xiàn),希望對需要的朋友有所幫助!
1 什么是redis
redis是nosql(也是個(gè)巨大的map) 單線程,但是可處理1秒10w的并發(fā)(數(shù)據(jù)都在內(nèi)存中)
使用java對redis進(jìn)行操作類似jdbc接口標(biāo)準(zhǔn)對mysql,有各類實(shí)現(xiàn)他的實(shí)現(xiàn)類,我們常用的是druid
其中對redis,我們通常用Jedis(也為我們提供了連接池JedisPool)
在redis中,key就是byte[](string)
redis的數(shù)據(jù)結(jié)構(gòu)(value):
String,list,set,orderset,hash
2 redis的使用
先安裝好redis,然后運(yùn)行,在pom文件中引入依賴,在要使用redis緩存的類的mapper.xml文件配置redis的全限定名。引入redis的redis.properties文件(如果要更改配置就可以使用)
應(yīng)用場景:
String :
1存儲(chǔ)json類型對象,2計(jì)數(shù)器,3優(yōu)酷視頻點(diǎn)贊等
list(雙向鏈表)
1可以使用redis的list模擬隊(duì)列,堆,棧
2朋友圈點(diǎn)贊(一條朋友圈內(nèi)容語句,若干點(diǎn)贊語句)
規(guī)定:朋友圈內(nèi)容的格式:
1,內(nèi)容: user:x:post:x content來存儲(chǔ);
2,點(diǎn)贊: post:x:good list來存儲(chǔ);(把相應(yīng)頭像取出來顯示)
hash(hashmap)
1保存對象
2分組
3 string與hash的數(shù)據(jù)差別
在網(wǎng)路傳輸時(shí)候,必須要進(jìn)行進(jìn)行序列化,才可以進(jìn)行網(wǎng)路傳輸,那么在使用string類型的類型的時(shí)候需要進(jìn)行相關(guān)序列化,hash也是要進(jìn)行相關(guān)的系列化,所以會(huì)存在很多序列化,在存儲(chǔ)的時(shí)候hash是可以存儲(chǔ)的更加豐富,但是在反序列化的時(shí)候,string的反序列化相對較低,而hash的序列化和返序列化是相對hash類更加復(fù)雜,所以看業(yè)務(wù)場景,如果是數(shù)據(jù)經(jīng)常修改的那種,為了性能可以使用string,如果是數(shù)據(jù)不是經(jīng)常改的那種就可以使用hash,由于hash,存儲(chǔ)數(shù)據(jù)時(shí)比較豐富,可以存儲(chǔ)多種數(shù)據(jù)類型
4 redis的持久化方式:
能,將內(nèi)存中的數(shù)據(jù)異步寫入硬盤中,兩種方式:RDB(默認(rèn))和AOF
RDB持久化原理:通過bgsave命令觸發(fā),然后父進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,子進(jìn)程創(chuàng)建RDB文件,根據(jù)父進(jìn)程內(nèi)存生成臨時(shí)快照文件,完成后對原有文件進(jìn)行原子替換(定時(shí)一次性將所有數(shù)據(jù)進(jìn)行快照生成一份副本存儲(chǔ)在硬盤中)
優(yōu)點(diǎn):是一個(gè)緊湊壓縮的二進(jìn)制文件,Redis加載RDB恢復(fù)數(shù)據(jù)遠(yuǎn)遠(yuǎn)快于AOF的方式。
缺點(diǎn):由于每次生成RDB開銷較大,非實(shí)時(shí)持久化,
AOF持久化原理:開啟后,Redis每執(zhí)行一個(gè)修改數(shù)據(jù)的命令,都會(huì)把這個(gè)命令添加到AOF文件中。
優(yōu)點(diǎn):實(shí)時(shí)持久化。
缺點(diǎn):所以AOF文件體積逐漸變大,需要定期執(zhí)行重寫操作來降低文件體積,加載慢
5 redis單線程為什么這么快
redis是單線程的,但是為什么還是這么快呢,
原因1: 單線程,避免線程之間的競爭
原因2 :是內(nèi)存中的,使用內(nèi)存的,可以減少磁盤的io
原因3:多路復(fù)用模型,用了緩沖區(qū)的概念,selector模型來進(jìn)行的
6 redis主掛了怎么操作
redis提供了哨兵模式,當(dāng)主掛了,可以選舉其他的進(jìn)行代替,哨兵模式的實(shí)現(xiàn)原理,就是三個(gè)定時(shí)任務(wù)監(jiān)控,
6.1 每隔10s,每個(gè)S節(jié)點(diǎn)(哨兵節(jié)點(diǎn))會(huì)向主節(jié)點(diǎn)和從節(jié)點(diǎn)發(fā)送info命令獲取最新的拓?fù)浣Y(jié)構(gòu)
6.2 每隔2s,每個(gè)S節(jié)點(diǎn)會(huì)向某頻道上發(fā)送該S節(jié)點(diǎn)對于主節(jié)點(diǎn)的判斷以及當(dāng)前Sl節(jié)點(diǎn)的信息,
同時(shí)每個(gè)Sentinel節(jié)點(diǎn)也會(huì)訂閱該頻道,來了解其他S節(jié)點(diǎn)以及它們對主節(jié)點(diǎn)的判斷(做客觀下線依據(jù))
6.3 每隔1s,每個(gè)S節(jié)點(diǎn)會(huì)向主節(jié)點(diǎn)、從節(jié)點(diǎn)、其余S節(jié)點(diǎn)發(fā)送一條ping命令做一次心跳檢測(心跳檢測機(jī)制),來確認(rèn)這些節(jié)點(diǎn)當(dāng)前是否可達(dá)
當(dāng)三次心跳檢測之后,就會(huì)進(jìn)行投票,當(dāng)超過半數(shù)以上的時(shí)候就會(huì)將該節(jié)點(diǎn)當(dāng)做主
7 redis集群
redis集群在3.0以后提供了ruby腳本進(jìn)行搭建,引入了糙的概念,
Redis集群內(nèi)節(jié)點(diǎn)通過ping/pong消息實(shí)現(xiàn)節(jié)點(diǎn)通信,消息不但可以傳播節(jié)點(diǎn)槽信息,還可以傳播其他狀態(tài)如:主從狀態(tài)、節(jié)點(diǎn)故障等。因此故障發(fā)現(xiàn)也是通過消息傳播機(jī)制實(shí)現(xiàn)的,主要環(huán)節(jié)包括:主觀下線(pfail)和客觀下線(fail)
主客觀下線:
主觀下線:集群中每個(gè)節(jié)點(diǎn)都會(huì)定期向其他節(jié)點(diǎn)發(fā)送ping消息,接收節(jié)點(diǎn)回復(fù)pong消息作為響應(yīng)。如果通信一直失敗,則發(fā)送節(jié)點(diǎn)會(huì)把接收節(jié)點(diǎn)標(biāo)記為主觀下線(pfail)狀態(tài)。
客觀下線:超過半數(shù),對該主節(jié)點(diǎn)做客觀下線
主節(jié)點(diǎn)選舉出某一主節(jié)點(diǎn)作為領(lǐng)導(dǎo)者,來進(jìn)行故障轉(zhuǎn)移。
故障轉(zhuǎn)移(選舉從節(jié)點(diǎn)作為新主節(jié)點(diǎn))
8 內(nèi)存淘汰策略
Redis的內(nèi)存淘汰策略是指在Redis的用于緩存的內(nèi)存不足時(shí),怎么處理需要新寫入且需要申請額外空間的數(shù)據(jù)。
noeviction:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),新寫入操作會(huì)報(bào)錯(cuò)。
allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key。
allkeys-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,隨機(jī)移除某個(gè)key。
volatile-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,移除最近最少使用的key。
volatile-random:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,隨機(jī)移除某個(gè)key。
volatile-ttl:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在設(shè)置了過期時(shí)間的鍵空間中,有更早過期時(shí)間的key優(yōu)先移除。
9 緩存擊穿的解決方案:
原因:就是別人請求數(shù)據(jù)的時(shí)候,很多數(shù)據(jù)在緩存中無法查詢到,直接進(jìn)入數(shù)據(jù)查詢,
解決方法,對相關(guān)數(shù)據(jù)進(jìn)行查詢的數(shù)據(jù)只查詢緩存,如果是一些特殊的可以進(jìn)行數(shù)據(jù)庫查詢,
也可以采用布隆過濾器進(jìn)行查詢
10緩存雪崩的解決方案:
緩存雪崩的原因:一次性加入緩存的數(shù)據(jù)過多,導(dǎo)致內(nèi)存過高,從而影響內(nèi)存的使用導(dǎo)致服務(wù)宕機(jī)
解決方法:
1 redis集群,通過集群方式將數(shù)據(jù)放置
2 后端服務(wù)降級和限流:當(dāng)一個(gè)接口請求次數(shù)過多,那么就會(huì)添加過多數(shù)據(jù),可以對服務(wù)進(jìn)行限流,限制訪問的數(shù)量,這樣就可以減少問題的出現(xiàn)