Redis常見面試題總結

1. AOF 與 RDB 的區別?redis

  AOF:redis會將每個請求都記錄在日誌文件中,當redis重啓時,會讀取日誌文件,將請求從新執行一遍,以恢復數據到最新狀態,aof默認關閉,經過appendonly yes開啓
  aof有三種策略:1)aof always:每一條請求都會寫入日誌,這樣會保證數據不丟失,可是會影響redis的效率
  2)aof everysec:每秒將請求寫入日誌一次,對redis性能影響較小,可是redis宕機的時候會丟失一秒的數據
  3)aof sync:redis定時將請求寫入日誌,默認一分鐘,對性能幾乎無影響,可是會丟失數據比較多
  aof重寫:配置aof重寫策略,當aof日誌文件增加必定大小時,redis將會fork一個子進程重寫日誌文件,將文件保留能夠恢復最新數據的最小大小
  優勢:1)開啓aof always時,能夠保證數據不丟失,及時是aof everysec,也只會丟失一秒數據
    2)即便斷電,也能夠經過工具修復日誌
    3)寫入錯誤的redis命令時,能夠經過刪除錯誤命令,執行aof日誌命令恢復數據
  缺點:對性能影響比RDB大,恢復速度較慢

  RDB:redis會按期保存數據快照到rdb文件中,當redis重啓時,讀取數據快照恢復數據,默認開啓rdb策略
  經過 sava [second] [changes] 來配置rdb快照策略,能夠配置多條來實行多級快照保存策略,能夠經過BGSAVE來手動處罰rdb快照保存
  rdb會在保存時,fork一個進程來將數據寫入臨時文件,當寫入完畢時,用臨時文件替換上次持久化文件,對redis幾乎無影響,比aof高效,可是最後一次的數據會丟失
  優勢:1)因爲是經過fork子進程來操做,對redis影響很小
    2)恢復文件的速度比aof快
    3)每次快照會保存完整的數據快照,能夠做爲災備手段
  缺點:1)會丟失最後一次的數據
    2)當數據較多時,cpu不給力,子進程執行快照會耗時較長,影響redis對外服務能力

  推薦使用rdb + aof everysec組合的持久化方式

2. Redis集羣有哪幾種?
  1)主從模式:一個master,多個slave,支持主從複製,支持讀寫分離
    優勢:slave能夠分擔master的讀壓力,master掛了後,slave依然可讀
    缺點:master掛了以後,slave不會選舉出新master,難以擴容,不推薦使用這個模式
  2)哨兵模式:經過哨兵來監控master和slave,master掛了以後會選舉出slave
    優勢:繼承主從模式的優勢,而且更加健壯,可用性更高
    缺點:一樣難以擴容
  3)集羣模式:redis3.0以後支持redis集羣,能夠在多臺機器上部署多臺master(每一個master存儲一部分數據),每一個master有多個slave,當某個master掛了後,redis cluster會從slave中選舉出新master

3. Redis選舉流程?
  1)Redis的某個slave節點發現本身的主節點變爲FAIL狀態時,會嘗試選舉成爲新的master節點(持有最新數據的slave節點會首先發起選舉)
  2)該slave節點會廣播一條消息給其餘master節點
  3)其餘master節點接收消息以後,會判斷請求者的合法性,若合法,會發送確認消息給該slave節點(若其餘master節點未接到要求選舉slave節點的master節點的FAIL消息,會拒絕投票)
  4)當slave節點收到超過半數的選票以後,會成爲master節點,若選舉失敗,會開始下一輪選舉
  5)新的master節點會繼承原master節點的hash槽
  6)新的master節點會廣播消息告訴其餘節點本身成爲了master節點
  7)新master節點開始處理槽相關的請求

4. Redis Cluster數據分片?
  Redis Cluster經過hash槽分片存儲數據,共有16384個hash槽,每一個節點擁有一部分hash槽,key經過CRC16算法來確認hash值,映射到相應的節點上
若是增長節點,會從現有節點分配hash槽到新節點,若是刪除節點,會將刪除節點的hash槽分配給剩餘節點
Redis Cluster沒有本身實現hash槽的分配與計算,須要客戶端本身實現,客戶端能夠根據機器CPU能力來分配hash槽區間大小

5. 瞭解一致性hash嗎? 爲何不用一致性hash?
  一致性hash是將節點映射在一個2^32大小的圓環上,key經過hash,獲得在圓環上單的位置,數據存儲在順時針的下一個節點上,
當節點有變動時,知會影響節點與下一個節點間的數據。
  爲何不用:實際狀況中節點通常較少,一致性hash當節點較少時,會出現數據傾斜,數據分佈不均勻,
並且節點少時,當節點出現變化狀況下,節點中的數據映射影響很大。

6. Redis如何保證slots遷移過程當中的數據正常讀寫
  當節點A的數據遷移到節點B中時,會將節點A標記爲Migrating(遷移)狀態,將節點B標記爲importing(導入中)狀態,節點的槽映射不作修改
當有數據訪問節點A時,若是數據還在節點A上,會直接返回數據,若是不存在,返回一個ACK轉向消息
客戶端收到ACK消息,轉而訪問轉向所指定節點B,先發送一個ACKING請求,再發送真正的請求
客戶端收到節點B返回的數據後,不會改變槽映射關係
等待節點A全部slots都遷移到節點B後,再次有請求訪問節點A,會返回一個MOVED消息,將映射永久指向節點B

7. Redis 是什麼實現主從同步的?怎麼保證數據一致性?
  Redis master節點能夠執行讀寫命令,slave節點只能執行讀命令,主從同步分爲三種
  1)初次全量複製
  當一個slave節點啓動時,會向master節點發送sync命令,master節點接收命令後開始執行bgsva,保存rdb快照,將rdb快照發送給slave節點,
並將同步期間的寫命令緩存起來,slave節點接收rdb快照後,載入數據,而後master節點會發送緩存的寫命令,slave節點執行緩存的寫命令。
  2)命令傳播
  master節點每次執行寫命令後,會將命令發送給slave節點,slave節點執行命令進行同步
  3)從新複製
  當slave節點斷開鏈接重連後,會發送偏移量給master節點,master節點首先會判斷該slave節點是否以前是本身的從節點,若是不是,進行全量複製
若是是,會比較和本身的偏移量,若是不一致,會從積壓緩衝區將偏移量以後的命令發送給slave,slave執行命令進行同步

8. Redis 的過時策略都有哪些?Redis 怎麼刪除過時數據的?
  定時刪除:在給key設置過時時間的同時,給key加一個定時器,當key過時的時候刪除它
    優勢:能夠及時刪除key,保證內存釋放
    缺點:消耗性能,每一個設置過時的key都須要一個定時器
  惰性刪除:當取到過時key的時候,刪除key,返回null
    優勢:對性能無影響
    缺點:當過時key長時間沒有被取時,會發生內存泄露
  按期刪除:固定頻率去刪除過時的key
    優勢:在內存處理方面優於惰性刪除,在cpu處理方面優於定時刪除
    缺點:並不會檢查全部的key是否過時,而是隨機選擇一部分key,可能存在不少key過時沒有被刪除
  Redis採用按期刪除+惰性刪除的策略

9. Redis內存淘汰策略?
  noeviction:內存不足時,新寫入操做會報錯
  allkeys lru:內存不足時,移除全部key中最近最少使用的(推薦使用)
  volatile lru:內存不足時,移除設置了過時時間的key中,最近最少使用的(當redis又當緩存,又當持久層時使用)
  allkeys random:內存不足時,在全部key中隨機移除一個
  volatile random:內存不足時,在設置了過時時間的key中隨機移除一個
  volatile ttl:內存不足時,在設置了過時時間的key中,移除剩餘過時時間最短的key

10. 熱點Key問題的怎麼發現與解決?
  如何發現:
  1)憑藉業務經驗,提早預估熱key
  2)在客戶端進行收集,在操做redis前,加一行代碼進行統計
  3)用proxy層進行收集,不是全部項目的redis架構都有proxy層
  4)本身寫程序抓包分析,開發成本高,維護苦難,容易丟包
  5)用redis自帶命令:monitors命令和hotkeys命令,會影響redis性能
如何解決:
  1)利用二級緩存
    發現以後,利用jvm作二級緩存,將熱key存在hashmap中,後面的請求都從hashmap中取
  2)備份熱key
    將熱key備份到多個redis節點中,請求過來的時候分散到多個節點去取

11. 爲啥 Redis 單線程模型也能效率這麼高? 
  讀110000tps,寫81000tps
  緣由:一、單線程操做,避免了上下文的切換;
    二、純內存操做,減小IO
    三、使用了非阻塞多路複用IO模型:Redis client根據不一樣操做產生不一樣的soket,redis服務端有一段IO多路複用程序,將soket置入隊列中,
而後文件事件分派器依次從隊列中取,分發給不一樣的事件處理器處理

12. 什麼是緩存穿透和雪崩,如何解決緩存穿透和雪崩? 
  緩存穿透是:用戶請求了一個在數據庫中不存在的數據,致使緩存層失效,請求直接打到數據庫,併發量大的狀況下會打垮數據庫
  解決:一、當查詢數據庫不存在時,給這條數據設置一條空值的緩存,避免後續請求都打到數據庫;
    二、使用布隆過濾器實現,布隆過濾器內部經過一個bitmap,將全部存在的key都存在map中,每次請求都查找map中是否存在key,不存在則查看
  緩存擊穿:緩存設置了過時時間,在過時時間失效的一刻,剛好大量請求打過來,因爲新的請求還來不及寫入緩存,致使全部請求打到數據庫,進而打垮數據庫
  解決:一、將熱點數據設爲永不失效
    二、給請求數據庫的操做加鎖,單機用synchronized或ReentrantLock,分佈式集羣環境能夠用redis作分佈式鎖
  緩存雪崩:在同一時刻,大量緩存集中失效,致使大量請求直接打到數據庫,使數據庫被打垮
  解決:給key設置過時時間的時候加上隨機數,使過時時間隨機分佈算法


13. 怎麼高效的批量刪除 Redis上面的 KEY ?
  redis自己不提供批量刪除功能,能夠經過keys、scan加xargs組合命來來實現批量刪除
  1)redis-cli -h xxx.xxx.xxx -p xxxx --raw keys "ops-coffee-*" | xargs redis-cli del
    會致使redis阻塞,不推薦使用
  2)redis-cli -h xxx.xxx.xxx -p xxxx --scan --pattern "*-coffee-*" | xargs -L 2000 redis-cli del
    scan漸進式刪除,會將操做分批執行,不會阻塞redis數據庫

相關文章
相關標籤/搜索