redis緩存 面試一則

redis 和 memcached 有什麼區別?redis的線程模型是什麼?爲何單線程比多線程memcached效率要高得多(爲何redis單線程還能夠支撐高併發)?

回答:
redis和memcached區別java

一、redis支持服務器端的數據操做:redis比memcached數據結構多和支持更豐富的數據操做
    二、redis能夠支持複雜的結構和操做
    三、redis官方致辭集羣模式
複製代碼

redis的線程模型(用redis仍是要了解一點線程模型)react

一、文件事件處理器
      redis基於reactor(java的Nio就是一個reactor模型)模式開發了網絡事件處理器,這個處理器叫作文件事件處理器,
      file event handler。這個文件事件處理器,是單線程的,redis因此才叫作單線程的模型,
      採用IO多路複用機制同時監聽多個socket,根據socket上的時間來選擇對應的事件處理器來處理這個事件
      
      若是被監聽的socket準備好執行accept、read、write、close
      等操做的時候,相應的文件事件就會產生,這個時候文件處理器就會調用以前關聯的時間處理器來處理事件
      
      文件處理器的結構包含4個部分:多個socket,IO多路複用程
      序,文件事件分派器、事件處理器(命令請求處理器、命令回覆處理器、鏈接應答處理器,等等)。
      
      相應的多個socket會產生多個不一樣的操做,每一個操做對應不一樣的文件事件,可是IO多路複用程序雖然會監聽多個socket,但
      是會把socket放到一個隊列中,這樣依次選擇對應的事件處理器來處理
    
    二、文件事件
    
    當socket變得可讀時(好比客戶端對redis執行write操做,或者close操做),或者有新的能夠應答的socket出現,socket就會產生一個AE_READABLE事件。
    
    當socket即可能夠讀寫的時候(客戶端對redis執行read操做),socket會產生一個AE_WRITABLE事件
    
    IO多路複用程序能夠監聽AE_REABLE 和 AE_WRITABLE兩種事假,要是一個socket同時產生了兩種事件,那麼文件分派器優先處理前者(讀)其次纔是寫
    
    三、文件事件處理器
    
    若是是客戶端要鏈接redis,那麼會爲socket關聯鏈接應答處理器
    
    若是客戶端要寫數據到redis,爲socket關聯命令請求處理器
    
    若是要讀數據,爲socket關聯命令回覆處理器
    
    四、客戶端與redis通訊的一次流程
    
    在redis啓動初始化的時候,redis會將鏈接應答處理器何AE_READABLE事件關聯起來,
    接着若是一個客戶端跟redis發起鏈接此時會產生一個AE_READABLE事件,而後由鏈接應答處理器跟客戶端創建鏈接,建立客戶端對應的socket,同時將這個socket的AE_READABLE事件跟命令請求處理器關聯起來
    
    當客戶端向redis發起請求的時候(無論讀仍是寫),首先就會在socket產生一個AE_READABLE事件,而後由對應的命令請求處
    理器來處理。這個命令請求處理器就會從socket中讀取相關數據,而後進行執行和處理
    
    接着redis這邊準備好了給客戶端的相應數據後,就會將socket的AE_WRITABLE事件跟命令回覆處理器關聯起來
    當客戶端這邊準備好讀取相應數據時,就會在socket上產生一個AE_WRITABLE事件,
    會由對應的命令回覆處理器來處理,就是講準備好的相應數據寫入socket,供客戶端來讀取
    
    命令回覆處理器寫完以後,就會刪除這個socket的AE_WRITABLE事件和命令回覆處理器的關聯關係
複製代碼

爲何redis單線程模型效率這麼高redis

一、純內存操做
    二、核心是基於非阻塞的IO多路複用機制
    三、不用頻繁切換上下文
複製代碼

redis都有哪些數據類型?分別在哪些場景下使用合適?

(若是問這個問題應該以爲你對技術沒有深刻研究過,看看你會不會用)緩存

一、string 最基本的類型,普通set和get,作簡單的kv緩存
    二、hash: 相似map的一種結構,前提是簡單對象(沒有嵌套其餘對象)給緩存在redis裏,而後每次讀寫緩存的時候,就能夠操做hash裏的某個字段
    
    好比 key=abc value={"id":12,"age":12}, 能夠直接操做age 修改成 20.
    
    三、list 有序列表,這個能夠來個騷操做
    好比,作分頁,相似那種下拉分頁的東西
    簡單的消息隊列,粉絲列表
    
    四、set 無序集合,自動去重
    基於set玩交集、並集和差集,好比交集,兩我的粉絲列表整一個交集,看看共同好友
    
    五、sortedset
    能夠排序的去重,作排行榜
    將每一個用戶以及其對應的什麼分數寫入進去,zadd board score username,接着zrevrange board 0 99,就能夠獲取排名前100的用戶;zrank board username,能夠看到用戶在排行榜裏的排名
    
    zadd board 85 zhangsan
    zadd board 72 wangwu
    zadd board 96 lisi
    zadd board 62 zhaoliu
    
    96 lisi
    85 zhangsan
    72 wangwu
    62 zhaoliu

    zrevrange board 0 3
    
    獲取排名前3的用戶
    
    96 lisi
    85 zhangsan
    72 wangwu
複製代碼

redis過時策略有哪些?內存淘汰機制有哪些?手寫一個LRU代碼實現?

一、設置過時時間,set key的時候均可以給一個過時時間,假如過時後redis怎麼對這個key刪除的? 答:按期刪除+惰性刪除服務器

按期刪除就是每一個100ms隨機抽取一些設置了過時時間的key,若是過時了就刪除,可是會有一個問題,由於隨機查找因此有些會漏。網絡

可是你再獲取這key的時候,卻找不到這個時候就是惰性刪除,在你獲取key的時候,redis會檢查一下,這個key若是過時了,就刪除不給你返回什麼東西。數據結構

可是這樣還有一個問題就是,假如刪除沒有刪除,而後你係統也沒有查key,就這樣一直留在內存裏,redis內存就崩了。 這個時候就會走內存淘汰機制多線程

二、內存淘汰 若是redis的內存佔用過多的時候,這個時候就會進行內存淘汰併發

redis 10個key,如今已經滿了,redis須要刪除掉5個key
    
    1個key,最近1分鐘被查詢了100次
    1個key,最近10分鐘被查詢了50次
    1個key,最近1個小時倍查詢了1次
    
    1)noeviction:當內存不足以容納新寫入數據時,新寫入操做會報錯,這個通常沒人用吧,實在是太噁心了
    2)allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key(這個是最經常使用的)
    3)allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key,這個通常沒人用吧,爲啥要隨機,確定是把最近最少使用的key給幹掉啊
    4)volatile-lru:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的key(這個通常不太合適)
    5)volatile-random:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個key
    6)volatile-ttl:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的key優先移除複製代碼
相關文章
相關標籤/搜索