【Redis】4、Redis設計原理及相關問題

(六)Redis設計原理及相關問題

  經過前面關於Redis五種數據類型、相關高級特性以及一些簡單示例的使用,對Redis的使用和主要的用途應該有所掌握,可是還有一些原理性的問題咱們在本部分作一個探討。html

  本部分參考了一些其餘博客,在文後的參考連接中註明,特此說明。mysql

一、Redis與mysql的區別

  Redis是一種Key-value型的存儲數據庫,咱們天然有一個疑惑,咱們早已會用相似於mysql這樣的關係型數據庫了,那麼他們之間有什麼區別,爲何還要用Redis。nginx

  (1)數據庫類型不一樣redis

  mysql是咱們熟知的關係型數據庫,數據嚴格存儲在表格的行和列中,面向的是結構化的數據。而Redis是一種非關係型數據庫,屬於一種NoSQL數據庫,除告終構化數據,還能夠存儲半結構化和非結構化的數據,好比咱們在數據類型中提到,字符串能夠存儲任何數據,好比jpg圖片或者序列化的對象。sql

  (2)運行機制不一樣數據庫

  mysql主要用於存放持久化的數據,將數據存放在硬盤中,讀取速度比較慢,適合存放大數據。Redis的數據保存在緩存中,緩存的讀取速度快,效率高,要存放大量數據須要進行分區和橫向擴展。另外,Redis天生就是適合分佈式存儲的,能夠動態的橫向擴展。編程

  mysql在每次訪問數據庫時,都存在着複雜的I/O操做,在鏈接數據庫上花費大量時間,效率比較慢。Redis的數據自己就在緩存中,能夠用於存儲使用頻繁的熱數據,不會產生複雜的I/O。緩存

  (3)面向的需求不一樣安全

  mysql面向大量數據的持久化存儲,因爲關係型數據庫的優點,適合用於多表聯合查詢等。Redis因爲緩存容量有限,只能夠做爲一個減輕數據庫壓力的緩衝和少許熱數據存儲的數據庫。所以,實際上,不少狀況下是mysql和Redis聯合使用,redis存儲使用頻繁的數據,這樣減小訪問數據庫的次數,提升運行效率。網絡

  (4)性能差別明顯

  關係型數據庫爲了維護數據的一致性付出了巨大的代價,讀寫性能比較差。在面對高併發讀寫性能很是差,面對海量數據的時候效率很是低。而Nosql存儲的格式都是key-value類型的,而且存儲在內存中,很是容易存儲,並且對於數據的 一致性是 弱要求。Nosql無需sql的解析,提升了讀寫性能。

二、爲何使用Redis

  關於爲何使用Redis,感受有一篇博客講的比較好,這裏借用其中的兩幅圖(參考連接中註明)。

  使用Redis主要考慮到的是兩個因素:性能和併發

  (1)高性能

  在碰到須要執行耗時特別久,且結果不頻繁變更的SQL,就特別適合將運行結果放入緩存。這樣,後面的請求就去緩存中讀取,使得請求可以迅速響應



  (2)高併發

  在大併發的狀況下,全部的請求直接訪問數據庫,數據庫會出現鏈接異常。這個時候,就須要使用redis作一個緩衝操做,讓請求先訪問到redis,而不是直接訪問數據庫。



三、Redis爲何「快」

  (1) 絕大部分請求是純粹的內存操做(很是快速)

  (2) 採用單線程,避免了沒必要要的上下文切換和競爭條件

  (3) 非阻塞多路IO複用

四、Redis的單線程機制

  單線程指的是網絡請求模塊使用了一個線程(因此不需考慮併發安全性),即一個線程處理全部網絡請求,其餘模塊仍用了多個線程。

  這個可能不太好理解,單線程怎麼還比多線程快了呢,這是由於Redis的性能瓶頸在內存的大小和網絡的帶寬,重點是Redis存儲在內存,不涉及I/O操做,(只有在有I/O操做的時候,線程由於I/O而阻塞,此時將CPU讓給別的線程會達到比較好的性能),因此Redis幾乎不涉及任何的外部I/O,所以,單線程是最快的。



五、Redis的多路I/O複用

  IO多路複用是用來解決對多個I/O監聽時,一個I/O阻塞影響其餘I/O的問題,跟多線程不要緊。跟多線程相比較,線程切換須要切換到內核進行線程切換,須要消耗時間和資源.而I/O多路複用不須要切換線/進程,效率相對較高,特別是對高併發的應用nginx就是用I/O多路複用,故而性能極佳.但多線程編程邏輯和處理上比I/O多路複用簡單.而I/O多路複用處理起來較爲複雜。

  這個理解較難,能夠參考文後給出的連接。

六、redis的過時策略以及內存淘汰機制

  redis採用的是按期刪除+惰性刪除策略

  按期刪除,redis默認每一個100ms檢查,是否有過時的key,有過時key則刪除。須要說明的是,redis不是每一個100ms將全部的key檢查一次,而是隨機抽取進行檢查(若是每隔100ms,所有key進行檢查,redis豈不是卡死)。所以,若是隻採用按期刪除策略,會致使不少key到時間沒有刪除。因而,惰性刪除派上用場。也就是說在你獲取某個key的時候,redis會檢查一下,這個key若是設置了過時時間那麼是否過時了?若是過時了此時就會刪除。

  若是按期刪除沒刪除key。而後你也沒即時去請求key,也就是說惰性刪除也沒生效。這樣,redis的內存會愈來愈高。那麼就應該採用內存淘汰機制

  在redis.conf中有一行配置maxmemory-policy allkeys-lru,該配置就是配內存淘汰策略的。
  1)noeviction:當內存不足以容納新寫入數據時,新寫入操做會報錯。

  2)allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的key。推薦使用。

  3)allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個key。

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

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

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

參考連接(本文大多內容參考其餘博客,特此註明):

http://www.javashuo.com/article/p-hlxqtctl-hw.html

http://www.javashuo.com/article/p-cakqnuif-ka.html

https://www.jianshu.com/p/9b71f8ee6e28

做者:itcats_cn
來源:CSDN
原文:http://www.javashuo.com/article/p-wfxrgmxd-q.html

相關文章
相關標籤/搜索