Redis是什么,優缺點?
Redis本質是一個K-V類型的內存數據庫
純內存操作,每秒可處理超過10w的讀寫操作
優點:
讀寫性能極高
非阻塞IO
單線程
支持持久化
支持事務
數據結構豐富
缺點:
容易受到物理內存的限制
主機宕機可能會造成數據的丟失
Redis為什么這么快?
基于內存存儲
單線程實現
非阻塞IO,IO多路復用
Redis與Memcached有哪些優勢?
支持的數據類型更豐富,String,Hash,list,set,zset等,memcached只支持K-V類型
Redis有持久化機制,Memcached沒有
Redis 原生支持集群模式,Memcached 沒有原生的集群模式,需要依靠客戶端來實現往集群中分片寫入數據;
Redis 支持發布訂閱模型、Lua 腳本、事務等功能,而 Memcached 不支持;
為什么用Redis做緩存?
1、高并發
2、高性能
Redis的常用場景有哪些?
- 緩存
- 排行榜
- 計數器
- 分布式會話
- 社交網絡
- 消息系統
Redis如何實現持久化?
1、AOF:日志追加的方式,將Redis的寫操作記錄下來,根據日志進行恢復追加
2、RDB:快照形式,在指定的時間間隔內將快照內的數據寫入磁盤,恢復時將快照文件讀入內存
?
Redis持久化數據和緩存怎么做擴容?
如果Redis被當做緩存使用,使用一致性哈希實現動態擴容縮容。
如果Redis被當做一個持久化存儲使用,必須使用固定的keys-to-nodes映射關系,節點的數量一旦確定不能變化。
否則的話(即Redis節點需要動態變化的情況),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有Redis集群可以做到這樣。
Redis過期鍵的刪除策略?
Redis的過期刪除策略就是:惰性刪除和定期刪除兩種策略配合使用。
惰性刪除:惰性刪除不會去主動刪除數據,而是在訪問數據的時候,再檢查當前鍵值是否過期,如果過期則執行刪除并返回null給客戶端,如果沒有過期則返回正常信息給客戶端。它的優點是簡單,不需要對過期的數據做額外的處理,只有在每次訪問的時候才會檢查鍵值是否過期,缺點是刪除過期鍵不及時,造成了一定的空間浪費。
定期刪除:Redis會周期性的隨機測試一批設置了過期時間的key并進行處理。測試到的已過期的key將被刪除。
定時刪除:
在設置某個key 的過期時間同時,我們創建一個定時器,讓定時器在該過期時間到來時,立即執行對其進行刪除的操作。
優點:定時刪除對內存是最友好的,能夠保存內存的key一旦過期就能立即從內存中刪除。
缺點:對CPU最不友好,在過期鍵比較多的時候,刪除過期鍵會占用一部分CPU時間,對服務器的響應時間和吞吐量造成影響。
Redis key的過期時間和永久有效分別怎么設置?
通過expire或pexpire命令,客戶端可以以秒或毫秒的精度為數據庫中的某個鍵設置生存時間,讓某個鍵在某個時間點過期。
Redis內存淘汰策略?
當Redis內存不足的時候會進行淘汰,刪除不常用的數據。
Redis4.0之前:
volatile-lru:利用LRU算法移除設置過過期時間的key (LRU:最近使用Least Recently Used )
allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key(這個是最常用的)
volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數據淘汰
volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據淘汰
allkeys-random:從數據集( server.db[i].dict)中任意選擇數據淘汰
no-eviction:禁止驅逐數據,也就是說當內存不足以容納新寫入數據時,新寫入操作會報錯。這個應該沒人使用吧!
Redis4.0后:
volatile-lfu:從已設置過期時間的數據集(server.db[i].expires)中挑選最不經常使用的數據淘汰(LFU(Least Frequently Used)算法,也就是最頻繁被訪問的數據將來最有可能被訪問到)
allkeys-lfu:當內存不足以容納新寫入數據時,在鍵空間中,移除最不經常使用的key。
如何保證緩存與數據庫雙寫時的數據一致性?
1、先刪除緩存,后更新數據庫
2、先更新數據庫,后刪除緩存
redis的集群模式有哪些?
主從復制,優點是讀寫分離,可以分擔服務器壓力,提高讀寫效率。缺點是當主宕機時可能會造成主從數據不—致。
哨兵模式,主從的基礎上增加了哨兵機制。當主掛了時,從節點會選票投出新主節點。優點就是提高了redis的可用性,心跳機制監測主節點的健康情況。缺點是配置麻煩,在選舉過程中,無法工作。多主多從。
?
什么是熱Key問題?如何解決?
大量請求一個key,導致這個key 的并發訪問量很大,產生緩存擊穿問題。集群部署,分攤請求壓力。
?
什么是緩存擊穿、緩存穿透、緩存雪崩?以及對應的解決方案?
緩存擊穿:某個熱點Key失效,造成緩存讀取不到,大量請求落在數據庫上
通過互斥鎖來控制讀寫的線程數,其他線程等待
不設置熱點key的過期時間
緩存穿透:請求的key在緩存中找不到,在數據庫中也找不到,找不到后就去數據庫找一遍導致數據庫壓力劇增
布隆過濾器:在緩存之前設置過濾器,將key存儲在布隆過濾器上,不存在直接進行返回,減少對數據庫的壓力
緩存雪崩:某一時間大量熱點Key失效,大量請求落在數據庫上,很可能直接打崩數據庫
設置不同的過期時間,讓緩存失效的時間盡量均勻
保證Redis緩存的高可用,防止Redis宕機導致緩存雪崩的問題。可以使用主從+哨兵,Redis集群來避免 Redis全盤崩潰的情況。
?
Redis高可用方案如何實施?
使用官方推薦的哨兵(sentinel)機制就能實現,當主節點出現故障時,由Sentinel自動完成故障發現和轉移,并通知應用方,實現高可用性。
它有四個主要功能:
集群監控,負責監控Redis master和slave進程是否正常工作。
消息通知,如果某個Redis實例有故障,那么哨兵負責發送消息作為報警通知給管理員。
故障轉移,如果master node掛掉了,會自動轉移到slave node上。
配置中心,如果故障轉移發生了,通知client客戶端新的master地址。
什么是分布式鎖?為什么用分布式鎖?
鎖在程序中的作用就是同步工具,保證共享資源在同一時刻只能被一個線程訪問,Java中的鎖我們都很熟悉了,像synchronized 、Lock都是我們經常使用的,但是Java的鎖只能保證單機的時候有效,分布式集群環境就無能為力了,這個時候我們就需要用到分布式鎖。
分布式鎖,顧名思義,就是分布式項目開發中用到的鎖,可以用來控制分布式系統之間同步訪問共享資源。
思路是:在整個系統提供一個全局、唯一的獲取鎖的"東西",然后每個系統在需要加鎖時,都去問這個"東西"拿到一把鎖,這樣不同的系統拿到的就可以認為是同一把鎖。至于這個"東西",可以是Redis、Zookeeper,也可以是數據庫。
一般來說,分布式鎖需要滿足的特性有這么幾點:
1、互斥性:在任何時刻,對于同一條數據,只有一臺應用可以獲取到分布式鎖;
2、高可用性:在分布式場景下,一小部分服務器宕機不影響正常使用,這種情況就需要將提供分布式鎖的服務以集群的方式部署;
3、防止鎖超時:如果客戶端沒有主動釋放鎖,服務器會在一段時間之后自動釋放鎖,防止客戶端宕機或者網絡不可達時產生死鎖;
4、獨占性:加鎖解鎖必須由同一臺服務器進行,也就是鎖的持有者才可以釋放鎖,不能出現你加的鎖,別人給你解鎖了。
?