標籤:需要 最優 ttl 非同步 db檔案 byte 多工 最佳化 建立
1.redis是什嗎?
redis是nosql(也是個巨大的map) 單線程,但是可處理1秒10w的並發(資料都在記憶體中)
使用java對redis進行操作類似jdbc介面標準對mysql,有各類實現他的實作類別,我們常用的是druid
其中對redis,我們通常用Jedis(也為我們提供了串連池JedisPool)
在redis中,key就是byte[](string)
redis的資料結構(value):
String,list,set,orderset,hash
每種資料結構對應不同的命令語句~
2.redis怎麼使用?
先安裝好redis,然後運行,在pom檔案中引入依賴,在要使用redis緩衝的類的mapper.xml檔案配置redis的全限定名。引入redis的redis.properties檔案(如果要更改配置就可以使用)
3.應用情境:
String :
1儲存json類型對象,2計數器,3優酷視頻點贊等
list(雙向鏈表)
1可以使用redis的list類比隊列,堆,棧
2朋友圈點贊(一條朋友圈內容語句,若干點贊語句)
規定:朋友圈內容的格式:
1,內容: user:x:post:x content來儲存;
2,點贊: post:x:good list來儲存;(把相應頭像取出來顯示)
hash(hashmap)
1儲存對象
2分組
4.為什麼redis是單線程的都那麼快?
1.資料存於記憶體
2.用了多工I/O
3.單線程
5.redis也可以進行發布訂閱訊息嗎?
可以,(然後可以引出哨兵模式(後面會講)怎麼互相監督的,就是因為每隔2秒哨兵節點會發布對某節點的判斷和自身的資訊到某頻道,每個哨兵訂閱該頻道擷取其他哨兵節點和主從節點的資訊,以達到哨兵間互相監控和對主從節點的監控)和很多專業的訊息佇列系統(例如Kafka、RocketMQ)相比,Redis的發布訂閱略顯粗糙,例如無法實現訊息堆積和回溯。但勝在足夠簡單。
Redis 的一些問題與解決方案 : 6.redis能否將資料持久化,如何??
能,將記憶體中的資料非同步寫入硬碟中,兩種方式:RDB(預設)和AOF
RDB持久化原理:通過bgsave命令觸發,然後父進程執行fork操作建立子進程,子進程建立RDB檔案,根據父進程記憶體產生臨時快照檔案,完成後對原有檔案進行原子替換(定時一次性將所有資料進行快照產生一份副本儲存在硬碟中)
優點:是一個緊湊壓縮的二進位檔案,Redis載入RDB恢複資料遠遠快於AOF的方式。
缺點:由於每次產生RDB開銷較大,非即時持久化,
AOF持久化原理:開啟後,Redis每執行一個修改資料的命令,都會把這個命令添加到AOF檔案中。
優點:即時持久化。
缺點:所以AOF檔案體積逐漸層大,需要定期執行重寫操作來降低檔案體積,載入慢
7.主從複製模式下,主掛了怎麼辦?redis提供了哨兵模式(高可用)
何謂哨兵模式?就是通過哨兵節點進行自主監控主從節點以及其他哨兵節點,發現主節點故障時自主進行容錯移轉。
8.哨兵模式實現原理?(2.8版本或更高才有)
1.三個定時監控任務:
1.1 每隔10s,每個S節點(哨兵節點)會向主節點和從節點發送info命令擷取最新的拓撲結構
1.2 每隔2s,每個S節點會向某頻道上發送該S節點對於主節點的判斷以及當前Sl節點的資訊,
同時每個Sentinel節點也會訂閱該頻道,來瞭解其他S節點以及它們對主節點的判斷(做客觀下線依據)
1.3 每隔1s,每個S節點會向主節點、從節點、其餘S節點發送一條ping命令做一次心跳檢測(心跳檢測機制),來確認這些節點當前是否可達
2.主客觀下線:
2.1主觀下線:根據第三個定時任務對沒有有效回複的節點做主觀下線處理
2.2客觀下線:若主觀下線的是主節點,會諮詢其他S節點對該主節點的判斷,超過半數,對該主節點做客觀下線
3.選舉出某一哨兵節點作為領導者,來進行容錯移轉。選舉方式:raft演算法。每個S節點有一票同意權,哪個S節點做出主觀下線的時候,就會詢問其他S節點是否同意其為領導者。獲得半數選票的則成為領導者。基本誰先做出客觀下線,誰成為領導者。
4.容錯移轉(選舉新主節點流程):
9.redis叢集(採用虛擬槽方式,高可用)原理(和哨兵模式原理類似,3.0版本或以上才有)?
1.Redis叢集內節點通過ping/pong訊息實現節點通訊,訊息不但可以傳播節點槽資訊,還可以傳播其他狀態如:主從狀態、節點故障等。因此故障發現也是通過訊息傳播機制實現的,主要環節包括:主觀下線(pfail)和客觀下線(fail)
2.主客觀下線:
2.1主觀下線:叢集中每個節點都會定期向其他節點發送ping訊息,接收節點回複pong訊息作為響應。如果通訊一直失敗,則發送節點會把接收節點標記為主觀下線(pfail)狀態。
2.2客觀下線:超過半數,對該主節點做客觀下線
3.主節點選舉出某一主節點作為領導者,來進行容錯移轉。
4.容錯移轉(選舉從節點作為新主節點)
10.緩衝更新策略(即如何讓緩衝和mysql保持一致性)?
10.1 key到期清除(逾時剔除)策略
惰性到期(類比懶載入,這是懶到期):只有當訪問一個key時,才會判斷該key是否已到期,到期則清除。該策略可以最大化地節省CPU資源,卻對記憶體非常不友好。極端情況可能出現大量的到期key沒有再次被訪問,從而不會被清除,佔用大量記憶體。
定期到期:每隔一定的時間,會掃描一定數量的資料庫的expires字典中一定數量的key,並清除其中已到期的key。該策略是前兩者的一個折中方案。通過調整定時掃描的時間間隔和每次掃描的限定耗時,可以在不同情況下使得CPU和記憶體資源達到最優的平衡效果。
(expires字典會儲存所有設定了到期時間的key的到期時間資料,其中,key是指向鍵空間中的某個鍵的指標,value是該鍵的毫秒精度的UNIX時間戳記表示的到期時間。鍵空間是指該Redis叢集中儲存的所有鍵。)
問:比如這麼個情境,我設計了很多key,到期時間是5分鐘,當前記憶體佔用率是50%。但是5分鐘到了,記憶體佔用率還是很高,請問為什嗎?
Redis中同時使用了惰性到期和定期到期兩種到期策略,即使到期時間到了,但是有部分並沒有真正刪除,等待惰性刪除。
為什麼有定期還要有惰性呢?其實很簡單,比如10萬個key就要到期了,Redis預設是100ms檢查一波。如果他檢查出10萬個即將要清除,那他接下來的時間基本都是在幹這些清空記憶體的事了,那肯定影響效能,所以他只會部分刪除,剩下的等惰性
10.2 Redis的記憶體淘汰策略
Redis的記憶體淘汰策略是指在Redis的用於緩衝的記憶體不足時,怎麼處理需要新寫入且需要申請額外空間的資料。
noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。
allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。
allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key。
volatile-lru:當記憶體不足以容納新寫入資料時,在設定了到期時間的鍵空間中,移除最近最少使用的key。
volatile-random:當記憶體不足以容納新寫入資料時,在設定了到期時間的鍵空間中,隨機移除某個key。
volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了到期時間的鍵空間中,有更早到期時間的key優先移除。
11.緩衝粒度控制?
12.如何防止緩衝穿透?
(緩衝穿透指的是查詢一個根本不存在的資料,緩衝層不命中,又去查儲存層,又不命中。但如果有大量這種查詢不存在的資料的請求過來,會對儲存層有較大壓力,若是惡意攻擊,後果就)
12.1:緩衝空值存在的問題:
12.2:布隆過濾器:
布隆過濾器存在的問題:相對來說布隆過濾器搞起來代碼還是比較複雜的,現階段我們暫時還不需要,後面實在需要再考慮去做,什麼階段做什麼樣的事情,不是說這個系統一下子就能做的各種完美。
13.無底洞最佳化?
造成原因:redis分布式越來越多,導致效能反而下降,因為索引值分布到更多的 節點上,所以無論是Memcache還是Redis的分布式,大量操作通常需要從不 同節點上擷取,相比於單機大量操作只涉及一次網路操作,分布式大量操作 會涉及多次網路時間。 即分布式過猶不及。
14.雪崩最佳化
如果緩衝層由於某些原因不能提供服務,於是所有的請求都會達到儲存層,儲存層的調用量會暴增,造成儲存層也會級聯宕機的情況。
15.熱點key最佳化
當前key是一個熱點key(例如一個熱門的娛樂新聞),並發量非常大。
Redis 由淺入深