深刻了解redis(二)——redis的前世此生

爲何要使用分佈式緩存?

1. 高性能

當有一個查詢接口,請求的時候可能要花費1s鐘的時間,那麼若是咱們把這個接口請求的數據放到redis中,那麼咱們可能請求這個接口的時間只須要20ms,那麼咱們爲何不用redis緩存呢?node

2. 高併發

單機mysql的QPS頂天了也就2000左右,再多可能就要報警了,那麼若是一個系統,它的高峯期一秒鐘過來的請求數是幾萬條,那一個mysql單機絕對會掛掉。固然咱們能夠選擇將msql擴容作主從複製等等。可是若是這些請求裏面,大部分都是查詢請求,那麼咱們爲何不把這些查詢的數據放到redis裏面呢,這樣的話請求都是請求redis了,對mysql的壓力就會很小了。mysql

Redus的線程模型是什麼,爲何redis是單線程的可是卻能支撐高併發呢?

Redis其實是一個單線程工做模型。redis

Redis內部與使用文件事件處理器file event handler,這個文件事件處理器是單線程的,因此redis才叫作單線程的模型。它採用的io多路複用機制(netty也採用這個機制)監聽多個socket,將產生事件的socket壓入到內存隊列中,事件分派器根據socket上的時間類型來選擇對應的事件處理器進行處理。sql

文件事件處理器的結構包含四個部分:緩存

1.多個socket
    2.Io多路複用機制
    3.文件事件分派器
    4.事件處理器(鏈接應答處理器,命令請求處理器,命令回覆處理器)
複製代碼

事實上,多個socket可能會併發產生不一樣的操做,每一個操做對應不一樣的文件事件,可是io多路複用程序會監聽多個socket,會將產生事件的socket放入到隊列中排隊,事件分派器每次從隊列中取出一個socket,根據socket的時間類型交給對用的時間處理器進行處理。多線程

說白了,所謂的單線程模型,指的就是io多路複用機制,由於io多路複用程序會監聽全部的socket,可是io多路複用程序倒是單線程的。併發

那麼,爲何io多路複用程序是單線程的,可是redis的性能仍然是如此的好呢?app

1.由於redis是純內存操做的
    2.Io多路複用機制雖然是單線程的,可是它是非阻塞的。
    3.Redis是c語言實現的。
    4.單線程的io多路複用機制,避免了多線程的頻繁切換上下文的問題,也預防了多線程可能產生的競爭問題。
複製代碼

Redis的過時策略是什麼?

Redis的過時策略是:按期刪除+惰性刪除dom

按期刪除,指的是redis默認每隔100ms就會隨機抽取一些設置了過時時間的key,檢查其是否過時,若是過時就會刪除。確定不會去抽取全部的過時時間的key,由於redis上存儲的數據太大了,若是每個設置了過時時間的key都會去抽取,那麼確定會對redis的性能形成了巨大的影響的。異步

惰性刪除,指的是咱們在實際上使用redis的時候,當咱們經過一個key去查詢redis的時候,redis會先判斷這個key是否過時了,若是過時了就會刪除。

可是,若是存在這麼一部分數據,它既沒有被redis抽取的時候抽取到,也沒有被業務使用到,可是它又過時了,那麼是否是它就會永遠的存儲在了redis裏面呢,越存越多,最後致使了redis的內存塊耗盡了?

這個時候,可能就須要redis另一個機制了,內存淘汰機制。

內存淘汰機制

redis 內存淘汰機制有如下幾個:

noeviction: 當內存不足以容納新寫入數據時,新寫入操做會報錯,這個通常沒人用吧,實在是太噁心了。

allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key(這個是最經常使用的)。

allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個 key,這個通常沒人用吧,爲啥要隨機,確定是把最近最少使用的 key 給幹掉啊。

volatile-lru:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,移除最近最少使用的 key(這個通常不太合適)。

volatile-random:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,隨機移除某個 key。

volatile-ttl:當內存不足以容納新寫入數據時,在設置了過時時間的鍵空間中,有更早過時時間的 key 優先移除。

如何保證 redis 的高併發和高可用?

高併發:一主多從,讀寫分離,主負責寫入,從負責讀取。 redis 採用異步方式複製數據到 slave 節點,不過 redis2.8 開始,slave node 會週期性地確認本身每次複製的數據量;

一個 master node(主節點) 是能夠配置多個 slave node (從節點)的;
    slave node (從節點)也能夠鏈接其餘的 slave node(從節點);
    slave node (從節點)作複製的時候,不會 block master node 的正常工做;
    slave node(從節點) 在作複製的時候,也不會 block 對本身的查詢操做,它會用舊的數據集來提供服務;
    可是複製完成的時候,須要刪除舊數據集,加載新數據集,這個時候就會暫停對外服務了;
    slave node (從節點)主要用來進行橫向擴容,作讀寫分離,擴容的 slave node 能夠提升讀的吞吐量。
複製代碼

由於開啓了主從複製,那麼咱們必須開啓redis的持久化策略。

Redis的持久化

Redis的持久化有兩種,RDB和AOF。

RDB

是對redis中的數據執行週期化的持久化。 RDB會生成多個數據文件,每一個數據文件都表明了某一個時刻中的redis的數據,這個多個數據文件的方式,很是適合作冷備份。

RDB對redis進行的持久化的文件,健壯性是很是強的,簡單來講,它就是簡單粗暴的給redis建立了一個有一個的快照。所以若是redis宕機了,用RDB來還原數據,會很簡單。

RDB的持久化,redis中默認是5分鐘一次,也就是說,若是隻用RDB作持久化,那麼redis最多有可能丟失5分鐘的數據,這點仍是很恐怖的,

AOF

AOF機制是對redis的每一條寫入命令做爲日誌,以「append-only」的模式寫入一個日誌文件中,在redis重啓的時候,會回放AOF日誌中的寫入指令來從新構建整個數據集。

AOF通常都是一秒一次,也就是AOF最多會丟失一秒鐘的數據。

相關文章
相關標籤/搜索