爲何要用Redis?Redis爲何這麼快?

摘抄自:https://zhuanlan.zhihu.com/p/81195864mysql

如下單線程僅指Redis負責存取這塊的線程只有一個,而非Redis中只有一個進程)面試

我先給個個人結論,單線程的Redis在瓶頸是cpu的io時(這不是大多數應用的實際應用場景),確實速度會比多線程慢。可是,咱們實際應用場景中不多會遇到瓶頸是CPU的io的狀況,這時候單線程優點就凸顯出來了。redis

實現很簡單!性能又不會比多線程差,而且,單線程確實不用處理上下文的切換,cpu利用率會比多線程高,這時候採用單線程實現是一種很划算的作法。固然,若是你的寬帶和內存牛逼到了使得你的io成爲瓶頸,這時候也只能使用多線程了。算法

 

 

面試時考官讓我挑一種本身熟悉的NoSQL數據庫講一講,我當場就蒙了,我就用過sql server,mysql和Oracle這幾種,這幾種就算從名字看也知道是sql數據庫嘛,絞盡腦汁,我福至心靈,答出,Redis!sql

先說說Redis是什麼吧小老弟?數據庫

Redis嘛,就是一種運行速度很快,併發很強的跑在內存上的NoSql數據庫,支持鍵到五種數據類型的映射。

來來來,講一講爲何Redis這麼快?緩存

首先,採用了多路複用io阻塞機制
而後,數據結構簡單,操做節省時間
最後,運行在內存中,天然速度快

Redis爲何是單線程的?服務器

Redis官方很敷衍就隨便給了一點解釋。不過基本要點也都說了,由於Redis的瓶頸不是cpu的運行速度,而每每是網絡帶寬和機器的內存大小。再說了,單線程切換開銷小,容易實現既然單線程容易實現,並且CPU不會成爲瓶頸,那就瓜熟蒂落地採用單線程的方案了。

若是萬一CPU成爲你的Redis瓶頸了,或者,你就是不想讓服務器其餘核閒置,那怎麼辦?網絡

那也很簡單,你多起幾個Redis進程就行了。Redis是keyvalue數據庫,又不是關係數據庫,數據之間沒有約束。只要客戶端分清哪些key放在哪一個Redis進程上就能夠了。redis-cluster能夠幫你作的更好。

單線程能夠處理高併發請求嗎?數據結構

固然能夠了,Redis都實現了。有一點概念須要澄清,併發並非並行。
(相關概念:併發性I/O流,意味着可以讓一個計算單元來處理來自多個客戶端的流請求。並行性,意味着服務器可以同時執行幾個事情,具備多個計算單元)

咱們使用單線程的方式是沒法發揮多核CPU 性能,有什麼辦法發揮多核CPU的性能嘛?

咱們能夠經過在單機開多個Redis 實例來完善!
警告:這裏咱們一直在強調的單線程,只是在處理咱們的網絡請求的時候只有一個線程來處理,一個正式的Redis Server運行的時候確定是不止一個線程的,這裏須要你們明確的注意一下!
例如Redis進行持久化的時候會以子進程或者子線程的方式執行(具體是子線程仍是子進程待讀者深刻研究)

簡述一下Redis值的五種類型

String 整數,浮點數或者字符串
Set 集合
Zset 有序集合
Hash 散列表
List 列表

 

 

有序集合的實現方式是哪一種數據結構?

跳躍表。

請列舉幾個用獲得Redis的經常使用使用場景?

緩存,毫無疑問這是Redis當今最爲人熟知的使用場景。再提高服務器性能方面很是有效;

排行榜,在使用傳統的關係型數據庫(mysql oracle 等)來作這個事兒,很是的麻煩,而利用Redis的SortSet(有序集合)數據結構可以簡單的搞定;

計算器/限速器,利用Redis中原子性的自增操做,咱們能夠統計相似用戶點贊數、用戶訪問數等,這類操做若是用MySQL,頻繁的讀寫會帶來至關大的壓力;限速器比較典型的使用場景是限制某個用戶訪問某個API的頻率,經常使用的有搶購時,防止用戶瘋狂點擊帶來沒必要要的壓力;

好友關係,利用集合的一些命令,好比求交集、並集、差集等。能夠方便搞定一些共同好友、共同愛好之類的功能;

簡單消息隊列,除了Redis自身的發佈/訂閱模式,咱們也能夠利用List來實現一個隊列機制,好比:到貨通知、郵件發送之類的需求,不須要高可靠,可是會帶來很是大的DB壓力,徹底能夠用List來完成異步解耦;

Session共享,以PHP爲例,默認Session是保存在服務器的文件中,若是是集羣服務,同一個用戶過來可能落在不一樣機器上,這就會致使用戶頻繁登錄;採用Redis保存Session後,不管用戶落在那臺機器上都可以獲取到對應的Session信息。

一些頻繁被訪問的數據,常常被訪問的數據若是放在關係型數據庫,每次查詢的開銷都會很大,而放在redis中,由於redis 是放在內存中的能夠很高效的訪問

簡述Redis的數據淘汰機制

volatile-lru 從已設置過時時間的數據集中挑選最近最少使用的數據淘汰
volatile-ttl 從已設置過時時間的數據集中挑選將要過時的數據淘汰
volatile-random從已設置過時時間的數據集中任意選擇數據淘汰
allkeys-lru從全部數據集中挑選最近最少使用的數據淘汰
allkeys-random從全部數據集中任意選擇數據進行淘汰
noeviction禁止驅逐數據

Redis怎樣防止異常數據不丟失?

RDB 持久化
將某個時間點的全部數據都存放到硬盤上。
能夠將快照複製到其它服務器從而建立具備相同數據的服務器副本。
若是系統發生故障,將會丟失最後一次建立快照以後的數據。
若是數據量很大,保存快照的時間會很長。
AOF 持久化
將寫命令添加到 AOF 文件(Append Only File)的末尾。
使用 AOF 持久化須要設置同步選項,從而確保寫命令同步到磁盤文件上的時機。這是由於對文件進行寫入並不會立刻將內容同步到磁盤上,而是先存儲到緩衝區,而後由操做系統決定何時同步到磁盤。有如下同步選項:
選項同步頻率always每一個寫命令都同步everysec每秒同步一次no讓操做系統來決定什麼時候同步
always 選項會嚴重減低服務器的性能;
everysec 選項比較合適,能夠保證系統崩潰時只會丟失一秒左右的數據,而且 Redis 每秒執行一次同步對服務器性能幾乎沒有任何影響;
no 選項並不能給服務器性能帶來多大的提高,並且也會增長系統崩潰時數據丟失的數量
隨着服務器寫請求的增多,AOF 文件會愈來愈大。Redis 提供了一種將 AOF 重寫的特性,可以去除 AOF 文件中的冗餘寫命令。

講一講緩存穿透,緩存雪崩以及緩存擊穿吧

緩存穿透:就是客戶持續向服務器發起對不存在服務器中數據的請求。客戶先在Redis中查詢,查詢不到後去數據庫中查詢。
緩存擊穿:就是一個很熱門的數據,忽然失效,大量請求到服務器數據庫中
緩存雪崩:就是大量數據同一時間失效。
打個比方,你是個頗有錢的人,開滿了百度雲,騰訊視頻各類雜七雜八的會員,可是你就是沒有netflix的會員,而後你把這些帳號和密碼發佈到一個你本身作的網站上,而後你有一個朋友每過十秒鐘就查詢你的網站,發現你的網站沒有Netflix的會員後打電話向你要。你就至關因而個數據庫,網站就是Redis。這就是緩存穿透。
你們都喜歡看騰訊視頻上的《水果傳》,可是你的會員忽然到期了,你們在你的網站上看不到騰訊視頻的帳號,紛紛打電話向你詢問,這就是緩存擊穿
你的各類會員忽然同一時間都失效了,那這就是緩存雪崩了。

放心,確定有辦法解決的。
緩存穿透:
1.接口層增長校驗,對傳參進行個校驗,好比說咱們的id是從1開始的,那麼id<=0的直接攔截;
2.緩存中取不到的數據,在數據庫中也沒有取到,這時能夠將key-value對寫爲key-null,這樣能夠防止攻擊用戶反覆用同一個id暴力攻擊
緩存擊穿:
最好的辦法就是設置熱點數據永不過時,拿到剛纔的比方里,那就是你買騰訊一個永久會員
緩存雪崩:
1.緩存數據的過時時間設置隨機,防止同一時間大量數據過時現象發生。
2.若是緩存數據庫是分佈式部署,將熱點數據均勻分佈在不一樣搞得緩存數據庫中。

 

嗦一下Redis中的Master-Slave模式

鏈接過程

  1. 主服務器建立快照文件,發送給從服務器,並在發送期間使用緩衝區記錄執行的寫命令。快照文件發送完畢以後,開始向從服務器發送存儲在緩衝區中的寫命令;
  2. 從服務器丟棄全部舊數據,載入主服務器發來的快照文件,以後從服務器開始接受主服務器發來的寫命令;
  3. 主服務器每執行一次寫命令,就向從服務器發送相同的寫命令。

主從鏈

隨着負載不斷上升,主服務器可能沒法很快地更新全部從服務器,或者從新鏈接和從新同步從服務器將致使系統超載。爲了解決這個問題,能夠建立一箇中間層來分擔主服務器的複製工做。中間層的服務器是最上層服務器的從服務器,又是最下層服務器的主服務器。

 

 

 

Sentinel(哨兵)能夠監聽集羣中的服務器,並在主服務器進入下線狀態時,自動從從服務器中選舉出新的主服務器。

 

分片

分片是將數據劃分爲多個部分的方法,能夠將數據存儲到多臺機器裏面,這種方法在解決某些問題時能夠得到線性級別的性能提高。 假設有 4 個 Redis 實例 R0,R1,R2,R3,還有不少表示用戶的鍵 user:1,user:2,... ,有不一樣的方式來選擇一個指定的鍵存儲在哪一個實例中。 最簡單的方式是範圍分片,例如用戶 id 從 0~1000 的存儲到實例 R0 中,用戶 id 從 1001~2000 的存儲到實例 R1 中,等等。可是這樣須要維護一張映射範圍表,維護操做代價很高。 還有一種方式是哈希分片,使用 CRC32 哈希函數將鍵轉換爲一個數字,再對實例數量求模就能知道應該存儲的實例。 根據執行分片的位置,能夠分爲三種分片方式: 客戶端分片:客戶端使用一致性哈希等算法決定鍵應當分佈到哪一個節點。 代理分片:將客戶端請求發送到代理上,由代理轉發請求到正確的節點上。 服務器分片:Redis Cluster
相關文章
相關標籤/搜索