分佈式緩存的主要有點: 高性能與高併發react
高性能:內存讀取速度遠高於數據庫redis
高併發:數據庫瞬間不能支持高併發,經過緩存,能夠支持每秒十萬級的請求。普通數據庫每秒響應千級的。數據庫
使用緩存存在的常規問題:緩存
1.緩存與數據庫雙寫不一致 經常使用的是先更新數據庫,而後刪除緩存 這個叫 Cache Aside Pattern,老外發明的。若是先更新數據庫,再刪除緩存,那麼就會出現更新數據庫以前有瞬間數據不是很及時。 能夠 先刪緩存,而後寫db,經過訂閱數據庫的binlog在刪除緩存。網絡
2.緩存雪崩 緩存集羣掛了,或者大量緩存同一時間過時的致使大量請求打到db。保證緩存集羣的高可用, 哨兵或者cluster方案。熱點key不要過去,定時去更新。熱點key分部在cluster的不一樣節點上。併發
3.緩存擊穿 一個緩存key失效的瞬間,大量請求進入db。 作限流,分佈式鎖,只容許一個請求去查詢db。socket
4.緩存穿透 大量cache中不存在這個key,請求進入db。 能夠在db中查詢沒有的key,在cache中設置一個快速過時的空值。或者使用布隆過濾器,把全部可能存的數據存在一個足夠大的bitmap中,必定不存在的數據就會被攔截在,從而避免對底層數據庫的查詢。分佈式
redis的線程模型:ide
redis基於reactor模式開發了網絡事件處理模型,這個事件叫作文件事件處理模型(file event handler)。這個文件處理器是單線程的,採用IO多路複用機制同時監聽多個socket,根據socket上的事件來選擇對應事件處理器來處理這個事件。高併發
文件事件處理器是單線程運行的,可是經過IO多路複用機制來監聽多個socket,能夠實現高性能的網絡通訊模型,又能夠和內部其餘單線程的模塊進行對接,保證了redis內部的線程模型的簡單性。
文件事件處理包含四個部分:多個socket,IO多路複用程序,文件事件分派器,事件處理器(命令請求處理器,命令回覆處理器,鏈接答應處理器等等)。
多個socket可能併發的產生不一樣的操做,每一個操做對應不一樣的文件事件,可是IO多路複用機制會監聽多個socket,可是會將socket放入一個隊列中進行排隊,每次從隊列中取出一個socket給事件分派器,事件分派器把socket給對應的事件處理器。而後一個socket的事件處理完成以後,IO多路複用程序纔會將隊列中的下一個socket給事件分配器,事件分配器把socket給具體的事件處理器。
客戶端與redis通訊的一次流程。
Redis的客戶端對服務端的每次調用都經歷了發送命令,執行命令,返回結果三個步驟。其中執行命令階段,因爲redis是單線程來處理命令的,因此每條到達服務端的命令不會當即被執行,全部命令會進入一個隊列而後逐個被執行。多個客戶端發送的命令的執行順序是不肯定的,可是能夠肯定的是兩個命令不會被同時執行,不會產生併發問題,這就是redis的單線程基本模型。
在redis啓動初始化的時候,redis會將鏈接應答處理器和跟AE_READABLE事件關聯起來。
當有一個client和redis發起鏈接,此時會產生一個AE_READABLE事件,而後又對應的事件處理器處理。這個命令處理器就會從socket中讀取相關的數據,而後進行執行和處理。
當客戶端像redis發起請求的時候(無論是讀仍是寫請求都同樣),首先會在socket產生一個AE_READABLE事件,而後由對應的命令請求處理器來處理。這個命令請求處理器就會從socket中讀取相應的數據,而後進行執行和處理。
接着redis準備好了給客戶端的相應數據以後,就會將socket的AE_WRITABLE ;
事件跟命令回覆關聯起來,當客戶端這邊準備好讀取響應數據的時候,就會在socket上產生一個AE_WRITABLE事件,會由對應的命令回覆處理器來處理,就是將準備好的數據寫入socket,供客戶端來讀取。命令回覆處理器寫完以後,就會刪除這個socket的AE_WRITABLE事件和命令回覆處理器的關聯關係。