1.什麼是redis?
2. 緩存中間件——Memcache和redis的區別?
Memcache:
代碼層次類似哈希,不支持簡單數據類型,不支持分片,不支持主從分佈,不支持持久化存儲。
redis
數據類型豐富,支持主從分佈,支持分片,支持持久化存儲
3.爲什麼redis這麼快?
100000+ qps(每秒內查詢次數)
1)完全基於內存,絕大部分的請求純粹是內存操作,執行效率高。
2)數據結構簡單,對數據操作也接單
3)主線程採用單線程(io處理,io下的請求,賦值協調,集羣協調),想要多核也可啓用實例。
4)使用多路i/o複用模型,非阻塞io
4.什麼是多路複用模型?
FD:文件描述符,一個打開的文件通過唯一的描述符進行引用,該描述符是打開文件的元數據到文件本身的映射。
傳統的阻塞i/o模型:由於發現阻塞(讀寫不可動,不會對其他操作進行改變)一般用select系統調用,selector負責監聽是否可讀或可寫。
redis採用的多路複用函數:eqoll/kqueue/evport/select.因地制宜,優先選擇時間複雜度爲O(1)的多路複用函數作爲底層實現。以時間複雜度爲O(n)的select作爲保底。基於react設計模式監聽i/o事件。
5.redis常用的數據類型?
供用戶使用的數據類型
-
String:最基本的數據類型,二進制安全(jpg圖片,序列化文件)
-
Hash:String元素組成的字典,適用於存儲對象
-
List:列表,按照String元素插入順序排序(大約41個成員)
-
Set:String元素組成的無需集合,通過哈希表實現,不允許重複
-
Sorted Set:通過分數爲集合中的成員進行從小到大的排序
-
用於計數的HyperLogLog:HyperLogLog實際上不會存儲每個元素的值,它使用的是概率算法,通過存儲元素的hash值的第一個1的位置,來計算元素數量。
-
用於支持存儲地理位置信息的Geo。
6.底層數據類型基礎
這一部分不過多講解
-
簡單動態字符串
-
鏈表
-
字典
-
跳躍表
-
整數集合
-
壓縮列表
-
對象
7.從海量key裏查詢出來某一固定前綴的key
留意細節
-
摸清數據規模,即問清楚邊界
使用keys對線上業務的影響:Keys pattern :查找所有符合給定模式pattern的 key
-
Keys指令會一次性返回所有匹配的key
-
鍵的數量過大會使服務器卡頓
第二種方式:Scan cursor [Match pattern] [Count count]
-
基於遊標的迭代器,需要基於上一次的遊標延續之間的迭代過程。
-
以0作爲遊標開始進行一次新的迭代,知道命令返回遊標0完成一次遍歷。
-
不保證每次執行都返回某個給定數量的元素,支持模糊查詢。
-
一次返回的數量不可控,只能是某個大概率符合count的數。
8.如何通過Redis實現分佈式鎖
Setnx key value:如果key不存在,則創建並複製。
-
時間複雜度:O(1)
-
返回值:設置成功,返回1;設置失敗,返回0
9.如何解決Setnx長期有效的問題
Expire key seconds
-
設置key的生存時間,當key過期時(生存時間爲0),會被自動刪除
-
缺點:原子性得不到滿足
10.如何將兩者結合起來?(2.6.12)
Set key value[Ex seconds] [Px milliseconds] [Nx|xx]
-
Ex seconds:設置鍵的過期時間爲seconds秒。
-
Px millisecond:設置鍵的過期時間爲milliseconds毫秒。
-
Nx:只在鍵不存在時,纔對鍵進行操作。
-
Xx:只在鍵已經存在時,纔對鍵進行設置操作。
-
Set操作成功完成時返回OK,否則返回設置操作nil。
11.大量的key同時過期的注意事項
-
集中過期,由於清除大量的key很耗時,會出現短暫的卡頓現象。
-
解決方案:在設置key的過期時間的時候,給每個key加上隨機值。
12.如何使用Redis做異步隊列
-
使用List作爲隊列,Rpush生產消息,Lpop消費消息
-
缺點:沒有等待隊列有值,就能進行消費。
-
彌補:可以通過在應用層引入sleep機制去調用Lpop重試。
-
另外方法
-
Blpop key [key...] timeout:阻塞直到隊列有消息或者超時。
-
缺點:只能供一個消費者消費
怎麼樣才能夠生產一次便讓多個消費者消費?
Pub/Sub模式:主題訂閱者模式
-
發送者(Pub)發送消息,訂閱者(Sub)接收消息。
-
訂閱者可以訂閱任意數量的頻道。
-
缺點:消息的發佈是無狀態的,無法保證可達。(解決:利用KafaKa等)
-
13.Redis如何做持久化?
RDB(快照)持久化:保存某個時間節點的全量數據快照
-
SAVE 900 1 :900秒內有一行寫入
-
SAVE 300 10 :300秒內有10行寫入 否則從上
-
SAVE 60 10000 60秒內有10000行寫入
stop-writes-on-bgsave-error yes
-
當備份進程出錯時,主進程就停止寫入操作了。
rdbcompression yes
-
rdb格式
-
save:阻塞Redis的服務器進程,知道rdb文件被創建完畢。
-
bgsave:Fork出一個子進程來創建rdb文件,不阻塞服務器進程(主要的方式)
-
-
自動化觸發RDB持久化的方式
-
根據redis.conf配置裏的SAVE m n 定時觸發(用的是Bgsave)
-
主從複製時,主節點自動觸發
-
執行Debug Reload
-
執行Shutdown 且沒有開啓AOF持久化
-
系統調用fork():創建進程,實現了Copy-on-write
-
-
缺點
-
內存數據全量同步,量大影響IO性能
-
可能會因爲Redis掛掉而丟失從當前之最近一次快照期間的數據
AOF(Append-Only-File) 持久化:保存寫狀態
記錄除了查詢以外所有變更數據庫狀態的指令
以append的形式追加保存到AOF文件中(增量)
-
修改redis.conf appendonly yes 默認名字 appendonly.aof
-
appendfsnc 寫入方式:always(只要有變更就記錄) everysec(默認) no
日誌重寫解決AOF文件不斷增大的問題?
-
調用fork()創建一個子進程
-
子進程把新的AOF寫到一個臨時文件裏,不依賴原來的AOF文件
-
子進程持續的將新的變化寫到內存和AOF裏
-
主進程獲取子進程重寫AOF的完成信號,往新AOF同步增量變動
-
使用新的AOF文件替換掉舊的AOF文件
Redis數據的恢復
-
14.RDB和AOF的優缺點
-
RDB:
-
優點:全量數據快照,文件小恢復快
-
缺點:無法保存最近一次快照之後的數據
-
-
AOF:
-
優點:可讀性高,適合保存增量數據,數據不易丟失
-
缺點:文件體積大,恢復時間長
-
15.RDB-AOF混合持久方式(Redis4.0之後 最常用的方式)
Bgsave做鏡像全量持久化,AOF做增量持久化
16.Copy-On-Write
如果有多個調用者同時需要要求相同的資源(如內存或磁盤上的數據存儲),他們會獲得相同的指針指向相同的資源,直到某個調用者試圖修改資源的內容時,系統纔會真正的複製一份專用副本給該調用者,而其他調用者所見到的最初的資源保持不變。
17.使用pipeline的好處
-
pipeline和linux的管道相似
-
Redis基於請求/響應模型,單個請求處理需要一一解答
-
pipeline批量執行指令,節省多次IO往返的時間
-
有順序依賴的指令建議分批發送
18.Redis的同步機制
主從同步原理
-
全同步過程
-
Slave發送sync指令到Master
-
master啓動一個進程,將Redis中的數據快照保存到文件中
-
Master將保存數據快照期間接收到的寫命令緩存起來
-
Master完成寫操作後,將該文件發送給Slave
-
使用新的AOF文件替換掉舊的AOF文件
-
Master將這期間收集到的增量寫命令發送給Slave端
-
-
增量同步過程
-
Master接收到用戶傳來的操作指令後,判斷是否需要傳播到Slave
-
將操作記錄追加到AOF文件中
-
將操作傳播到其他Slave:對齊主從庫 往響應緩存寫入指令
-
將緩存中的數據發送給Slave
缺點:無法保證高可用
19.解決高可用問題
引入監控機制
解決主從同步Master宕機後的主從切換問題
-
監控:檢查主從服務器是否運行正常
-
提醒:通過API向管理員或者其他應用程序發送故障通知
-
自動故障遷移:主從切換
20.流言協議Gossip
在雜亂無章中尋求一致
-
每個節點都隨機的與對方通信,最終所有的節點的狀態達成一致
-
種子節點定期隨即向其他節點發送結點列表以及需要傳播的消息
-
不保證信息一定會傳給所有節點,但是最終會趨於一致。
21.Redis的集羣原理
-
如何從海量數據裏找到所需?
-
分片:按照某種規則區劃分數據,存儲在多個節點上。
-
常規的按照哈希劃分無法實現節點的動態增減
一致性哈希算法:對2的32次方取模,將哈希值空間組織成虛擬的圓環。
缺點:Hash環數據傾斜問題
-
-
解決:引入虛擬節點解決數據傾斜的問題
-
-