1、redis的數(shù)據(jù)類型有哪些
2刁憋、redis為什么快
3、緩存擊穿离例、緩存穿透佩谣、緩存雪崩
4、redis事務了解嗎
5协屡、數(shù)據(jù)的一致性怎么保證
6俏脊、redis的過期策略有哪些
7、內(nèi)存淘汰策略有哪些
8肤晓、持久化的方式
9爷贫、怎么實現(xiàn)redis的高可用
1、redis的數(shù)據(jù)類型有哪些
- string
- List
- set
- hash
- zset
- geodist(經(jīng)緯度)
2补憾、redis為什么快
- 完全基于內(nèi)存操作
- C語?實現(xiàn)漫萄,優(yōu)化過的數(shù)據(jù)結(jié)構(gòu),基于?種基礎的數(shù)據(jù)結(jié)構(gòu)盈匾,redis做了?量的優(yōu)化腾务,性能極?
- 使?單線程,?上下?的切換成本削饵。redis6.0之后啟用了多線程岩瘦,僅限于網(wǎng)絡請求方面未巫。命令執(zhí)行依舊是單線程的。
- 基于?阻塞的IO多路復?機制
3担钮、緩存擊穿橱赠、緩存穿透、緩存雪崩
緩存穿透
對于系統(tǒng)A箫津,假設一秒5000個請求狭姨,結(jié)果其中4000個請求是黑客發(fā)出的惡意攻擊。
黑客發(fā)出的那4000個攻擊苏遥,在緩存中查不到饼拍,每次去數(shù)據(jù)庫查也查不到。舉例:數(shù)據(jù)庫id是從1開始的田炭,結(jié)果黑客發(fā)的請求id全是負數(shù)师抄。
解決:1、如果黑客每次id都一樣教硫,那么寫個空值到緩存中叨吮,set -1 unknown
2、如果黑客每次id都不一樣瞬矩,寫空值就不奏效了茶鉴,在緩存之前添加布隆過濾器。
緩存雪崩
1景用、對于系統(tǒng)A涵叮,假設每天高峰期每秒5000個請求,本來緩存在高峰期可以抗住每秒4000個請求伞插,但是緩存機器意外發(fā)生了全盤宕機割粮。緩存掛了,此時1秒5000個請求全部落數(shù)據(jù)庫導致數(shù)據(jù)庫cpu升高或者宕機媚污。
解決:
事前:redis高可用舀瓢,主從+哨兵,redis cluster耗美,避免全面崩盤
事中:本地ehcache緩存+hystrix限流&降級京髓,避免MYSQL被打死。
事后:redis持久化幽歼,一旦重啟朵锣,自動從磁盤上加載數(shù)據(jù),快速恢復緩存數(shù)據(jù)甸私。
2诚些、大量熱點數(shù)據(jù)同時過期,導致大量請求需查詢數(shù)據(jù)庫并寫到緩存。
解決:過期時間添加隨機值诬烹,避免同一時間發(fā)生砸烦。
緩存擊穿
某個熱點key,處于集中式高并發(fā)訪問時绞吁,當這個key突然失效幢痘,大量請求就擊穿了緩存,直接請求數(shù)據(jù)庫家破。
解決:
1颜说、若緩存的數(shù)據(jù)是基本不會發(fā)生更新的,則嘗試將該熱點數(shù)據(jù)設置為永不過期汰聋。
2门粪、數(shù)據(jù)更新不頻繁,采用基于redis的互斥鎖烹困,只有少量請求能連接數(shù)據(jù)庫玄妈,并更新構(gòu)建緩存,其余線程則在鎖釋放之后訪問緩存髓梅。
if(redis(LockName)) {
從數(shù)據(jù)庫中取出數(shù)據(jù)并寫入redis
} else {
Thread.sleep(200)
}
3拟蜻、更新頻繁的數(shù)據(jù),利用定時任務在過期時間前主動重新構(gòu)建緩存枯饿。
4酝锅、redis事務了解嗎
redis事務,分為三個階段:開啟鸭你,入隊和執(zhí)行屈张。以multi開啟一個事務擒权,然后將多個命令入隊到事務中袱巨,接到這些命令并不會立即執(zhí)行,而是放到等待執(zhí)行的事務隊列中碳抄,最后由exec命令觸發(fā)愉老。
redis不支持回滾∑市В回滾不能解決變成錯誤帶來的嫉入。
原子性:redis事務是原子性的:所有命令,要么全部執(zhí)行璧尸,要么全部不執(zhí)行咒林。
一致性:可以保證命令失敗的情況下得以回滾,數(shù)據(jù)能恢復到?jīng)]有執(zhí)行前的樣子爷光。
隔離性:保證垫竞,單進程單線程模式。
持久性:不支持持久型,因為redis持久化不管是rdb還是aof都是異步執(zhí)行的欢瞪。
5活烙、數(shù)據(jù)的一致性如何保證
數(shù)據(jù)的一致性保證
- 簡單:刪除數(shù)據(jù),更新數(shù)據(jù)庫遣鼓,查詢時插入緩存
- 復雜:如果每天是上億流量啸盏,每秒的并發(fā)讀是幾萬,先刪除緩存骑祟,去修改數(shù)據(jù)庫回懦,此時還沒修改完,一個請求過來次企,去讀數(shù)據(jù)庫粉怕,發(fā)現(xiàn)緩存空了,去查數(shù)據(jù)庫抒巢,查到了修改前的舊數(shù)據(jù)贫贝,放到了緩存中,數(shù)據(jù)庫和緩存中數(shù)據(jù)就又不一樣了蛉谜。
- 解決:更新數(shù)據(jù)的時候稚晚,根據(jù)數(shù)據(jù)的唯一標識,發(fā)送到一個隊列中型诚,讀數(shù)據(jù)的時候客燕,如數(shù)據(jù)不在緩存中,那么講重新執(zhí)行“讀數(shù)+更新緩存”的操作狰贯,根據(jù)唯一標識路由之后也搓,也發(fā)送到一個隊列中,一個隊列對應一個工作線程涵紊,每個工作線程串行拿到對應的操作傍妒,然后一條條的去執(zhí)行。
6摸柄、redis的過期策略有哪些
定期刪除和惰性刪除
惰性刪除指的是當我們查詢key的時候才對key進?檢測颤练,如果已經(jīng)達到過期時間,則刪除驱负。顯然嗦玖,他有?個缺點就是如果這些過期的key沒有被訪問,那么他就?直?法被刪除跃脊,?且?直占?內(nèi)存宇挫。
定期刪除指的是redis每隔?段時間對數(shù)據(jù)庫做?次檢查,刪除??的過期key酪术。由于不可能對所有key去做輪詢來刪除器瘪,所以redis會每次隨機取?些key去做檢查和刪除
7、內(nèi)存淘汰策略有哪些
內(nèi)存淘汰策略
- noeviction:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,新寫入操作會報錯娱局。
- allkeys-lru:當內(nèi)存不足以容納新寫入的數(shù)據(jù)時彰亥,在鍵空間中,移除最近最少使用的key(最常用)
- 當內(nèi)存不足以容納新寫入數(shù)據(jù)時衰齐,在鍵空間中任斋,隨機移除某個key
- volatile-lru:當內(nèi)存不足以容納新寫入數(shù)據(jù)時,在設置了過期時間的鍵空間中耻涛,移除最近最少使用的key
- volatile-random:當內(nèi)存不足以容納新寫入數(shù)據(jù)時废酷,在設置了過期時間的鍵空間中,隨機移除某個key抹缕。
- volatile-ttl:當內(nèi)存不足以容納新寫入的數(shù)據(jù)時澈蟆,在設置了過期時間的鍵空間中,有更早過期時間的key先移除卓研。
8趴俘、持久化的方式
rdb、aof
rdb優(yōu)點:rdb文件是某個時間節(jié)點的快照奏赘,壓縮后的文件體積遠遠小于內(nèi)存大小寥闪。所以rdb文件恢復數(shù)據(jù)要快于aof
缺點:rdb實時性不夠,無法做到秒級持久化磨淌。每次都需要fork子進程疲憋,頻繁操作成本較高。默認5分鐘生成一次
aof
將命令作為日志文件記錄梁只。
9缚柳、怎么實現(xiàn)redis的高可用
主從模式是最簡單的實現(xiàn)?可?的?案,核?就是主從同步搪锣。主從同步的原理如下:
- slave發(fā)送sync命令到master
- master收到sync之后秋忙,執(zhí)?bgsave,?成RDB全量?件
- master把slave的寫命令記錄到緩存
- bgsave執(zhí)?完畢之后淤翔,發(fā)送RDB?件到slave翰绊,slave執(zhí)?
- master發(fā)送緩存中的寫命令到slave佩谷,slave執(zhí)?
哨兵
- 初始化sentinel旁壮,將普通的redis代碼替換成sentinel專?代碼
- 初始化masters字典和服務器信息,服務器信息主要保存ip:port谐檀,并記錄實例的地址和ID
- 創(chuàng)建和master的兩個連接抡谐,命令連接和訂閱連接,并且訂閱sentinel:hello頻道
- 每隔10秒向master發(fā)送info命令桐猬,獲取master和它下?所有slave的當前信息
- 當發(fā)現(xiàn)master有新的slave之后麦撵,sentinel和新的slave同樣建?兩個連接,同時每個10秒發(fā)送info
命令,更新master信息 - sentinel每隔1秒向所有服務器發(fā)送ping命令免胃,如果某臺服務器在配置的響應時間內(nèi)連續(xù)返回?效回
復音五,將會被標記為下線狀態(tài) - 選舉出領(lǐng)頭sentinel,領(lǐng)頭sentinel需要半數(shù)以上的sentinel同意
- 領(lǐng)頭sentinel從已下線的的master所有slave中挑選?個羔沙,將其轉(zhuǎn)換為master
- 讓所有的slave改為從新的master復制數(shù)據(jù)
- 將原來的master設置為新的master的從服務器躺涝,當原來master重新回復連接時,就變成了新
master的從服務器
sentinel會每隔1秒向所有實例(包括主從服務器和其他sentinel)發(fā)送ping命令扼雏,并且根據(jù)回復判斷是
否已經(jīng)下線坚嗜,這種?式叫做主觀下線。當判斷為主觀下線時诗充,就會向其他監(jiān)視的sentinel詢問苍蔬,如果超過
半數(shù)的投票認為已經(jīng)是下線狀態(tài),則會標記為客觀下線狀態(tài)蝴蜓,同時觸發(fā)故障轉(zhuǎn)移碟绑。