Redis複習總結(一)

爲何選用redis?

因爲傳統的關係型數據庫如mysql已經不能適用所有的場景了,比如秒殺的庫存扣減,app首頁的訪問流量高峯等等,都很容易吧數據庫打崩,所以引入了緩存中間件,目前市面上比較常用的緩存中間件有redis和memcached不過中和考慮了他們的優缺點,最後選擇了redis。

Redis的數據結構有哪些?
String,Hash,List,Set,SortedSet。

加分:HyperLogLog,Geo,Pub/Sub,RedisModule,BloomFilter,RedisSearch,Redis-ML。

Redis的命令?

keys:獲取指定模式的key值,(阻塞式)比如:keys * 獲取所有key值,keys pattern。

scan:獲取key值,(無阻塞式)比如:scan 0 獲取所有key值。

緩存穿透:

概念:黑客惡意調用接口,傳遞一個redis中沒有的key值參數,這樣就直接訪問到了你的數據庫,給你的數據庫增加壓力。(就是繞過了redis緩存)

解決:

  1. 做參數校驗,在接口層增加校驗,比如用戶鑑權校驗,參數做校驗,不合法的參數直接return,比如:id做基礎校驗,id<=0的直接攔截等。
  2. 緩存穿透說白了就是要查詢的數據不存在(redis和數據庫中),那麼我們可以將該key-value的value值寫爲null或者稍後重試等,具體問產品,當然還得設置過期時間,比如:30秒。
  3. 還可以在nginx層做好配置,讓運維限制單個ip每秒的訪問次數,超出閾值的都拉進黑名單。布隆過濾器(Bloom Filter)這個也能很好的防止緩存穿透的發生,他的原理也很簡單就是利用高效的數據結構和算法快速判斷出你這個Key是否在數據庫中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。那又有小夥伴說了如果黑客有很多個IP同時發起攻擊呢?這點我一直也不是很想得通,但是一般級別的黑客沒這麼多肉雞,再者正常級別的Redis集羣都能抗住這種級別的訪問的,小公司我想他們不會感興趣的。把系統的高可用做好了,集羣還是很能頂的。

緩存雪崩:

概念:即redis中大面積的key值同時失效,這時候又有大量的請求打進來,緩存失效那麼會直接打到數據庫中,這樣會把數據庫直接打廢。就算重啓數據庫,重新啓動的數據庫也會立馬被新的流量給打死了。(就是大面積的key值同時失效或在很短的時間內失效導致大量的請求訪問數據庫致使壓力過大,整的數據庫崩盤)

解決:

  1. 在往redis中批量存數據時,設置過期時間隨機值,避免key值失效時間過於集中。
  2. 設置熱點數據永不過期,該數據有更新操作的時候更新緩存就好了。

緩存擊穿:

概念:和緩存雪崩有點像,但是又有一點不一樣,緩存雪崩是指大面積的緩存失效打崩了db,而緩存擊穿是指一個熱點key不停的扛着大併發,大併發集中對這一個點進行訪問,當這個key失效時,持續的大併發就穿破緩存,直接請求到了數據庫。

解決:

  1. 設置熱點數據永遠不過期,當改數據有更新操作的話更新緩存就好了
  2. 給熱點key加互斥鎖

代碼如下:

 

Redis爲啥那麼快:

 

Redis集羣的Sentinel哨兵模式:(需要安裝哨兵集羣)

因爲當主從模式下的redis集羣的主節點掛掉後,那麼整個集羣就沒有可以寫的節點了,因爲從節點備份了主節點全部的數據,那麼從節點可不可以升級爲主節點,那麼哨兵的任務就是這個操作,當主節點掛掉後,將從節點升級爲主節點,並且通知掛掉的主節點的其他從節點主節點的地址變了,以及當客戶端嘗試連接失效的主服務器的時候,集羣也會像客戶端返回新的主服務器的地址,這個過程也叫自動故障遷移。當原來的主節點(掛掉的主節點)重新上線後,會成爲當前主節點的從節點。

哨兵的任務:

1.監控:負責監控 Redis master 和 slave 進程是否正常工作。

2.提醒:如果某個 Redis 實例有故障,那麼哨兵負責發送消息作爲報警  通知給管理員。

3.自動故障遷移:如果 master node 掛掉了,會自動轉移到 slave node 上。

4.配置中心:如果故障轉移發生了,通知 client 客戶端新的 master 地址。

集羣故障投票(半數原則):

當哨兵節點有超過一半的認爲某主節點宕機,則該主節點宕機掛掉了,開始執行故障遷移操作。

RedisCluster集羣概念:(未安裝哨兵集羣,非哨兵模式)

(1)由多個Redis服務器組成的分佈式網絡服務集羣;

(2)集羣之中有多個Master主節點,每一個主節點都可讀可寫;

(3)節點之間會互相通信,兩兩相連;

(4)Redis集羣無中心節點。

故障轉移:

集羣的主節點來投票,超過半數認爲某主節點掛掉,則該主節點掛掉了。和哨兵的投票機制一樣。

Redis集羣分片策略:

Redis-cluster分片策略,是用來解決key存儲位置的。集羣將整個數據庫分爲16384個槽位slot,所有key-value數據都存儲在這些slot中的某一個上。一個slot槽位可以存放多個數據,key的槽位計算公式爲:slot_number=crc16(key)%16384,其中crc16爲16位的循環冗餘校驗和函數。集羣中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,集羣進入上線狀態,並開始處理客戶端發送的數據命令請求。

 

 

Redis集羣轉向:

由於Redis集羣無中心節點,請求會隨機發給任意主節點;主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會返回客戶端一個轉向錯誤;客戶端根據錯誤中包含的地址和端口重新向正確的負責的主節點發起命令請求

Redis的持久化:

方式1:RDB:RDB 持久化機制,是對 Redis 中的數據執行週期性的持久化。

方式2:AOF:AOF 機制對每條寫入命令作爲日誌,以 append-only 的模式 寫入一個日誌文件中,因爲這個模式是隻追加的方式,所以沒有任何磁盤尋址的 開銷,所以很快,有點像Mysql中的binlog。

兩種方式都可以把Redis內存中的數據持久化到磁盤上,然後再將這些數據 備份到別的地方去,RDB更適合做冷備,AOF更適合做熱備,比如我杭州的某電 商公司有這兩個數據,我備份一份到我杭州的節點,再備份一個到上海的,就算 發生無法避免的自然災害,也不會兩個地方都一起掛吧,這災備也就是異地容災, 地球毀滅他沒辦法。

tip:兩種機制全部開啓的時候,Redis在重啓的時候會默認使用AOF去重新構建數據,因爲AOF的數據是比RDB更完整的。

RDB方式持久化:

優點:他會生成多個數據文件,適合做冷備,完整的數據運維設置定時任務,定時同步數據到遠端的服務器,這樣服務掛了也不怕,想恢復多少分鐘之前的數據,只需要去拷貝一份之前的數據文件就可以了。

RDB對Redis的性能影響非常小,是因爲在同步數據的時候他只是fork 了一個子進程去做持久化的,而且他在數據恢復的時候速度比AOF來的快。

缺點:RDB都是快照文件,都是默認五分鐘甚至更久的時間纔會生成一次,這意味着你這次同步到下次同步這中間五分鐘的數據都很可能全部丟失掉。AOF則最多丟一秒的數據,數據完整性上高下立判。還有就是RDB在生成數據快照的時候,如果文件很大,客戶端可能會暫停幾毫秒甚至幾秒,你公司在做秒殺的時候他剛好在這個時候fork了一個子進程去生成一個大快照,哦豁,出大問題。

AOF方式持久化:

優點:上面提到了,RDB五分鐘一次生成快照,但是AOF是一秒一次去通過一個後臺的線程fsync操作,那最多丟這一秒的數據。

AOF在對日誌文件進行操作的時候是以append-only的方式去寫的,他只是追加的方式寫數據,自然就少了很多磁盤尋址的開銷了,寫入性能驚人,文件也不容易破損。

AOF的日誌是通過一個叫非常可讀的方式記錄的,這樣的特性就適合做災難性數據誤刪除的緊急恢復了,比如公司的實習生通過flushall清空了所有的數據,只要這個時候後臺重寫還沒發生,你馬上拷貝一份AOF日誌文件,把最後一條flushall命令刪了就完事了。

缺點:一樣的數據,AOF文件比RDB還要大。

AOF開啓後,Redis支持寫的QPS會比RDB支持寫的要低,他不是每秒都要去異步刷新一次日誌嘛fsync,當然即使這樣性能還是很高,我記得ElasticSearch也是這樣的,異步刷新緩存區的數據去持久化,爲啥這麼做呢,不直接來一條懟一條呢,那我會告訴你這樣性能可能低到沒辦法用的。

Redis數據備份:

單獨用RDB你會丟失很多數據,你單獨用AOF,你數據恢復沒RDB來的快,真出什麼時候第一時間用RDB恢復,然後AOF做數據補全,冷備熱備一起上,纔是互聯網時代一個高健壯性系統的王道。

保證集羣的高可用:

哨兵+主從並不能保證數據不丟失,但是可以保證集羣的高可用。

主從之間的數據同步:

爲啥要用主從這樣的架構模式,前面提到了單機QPS是有上限的,而且Redis的特性就是必須支撐讀高併發的,那你一臺機器又讀又寫,這誰頂得住啊,不當人啊!但是你讓這個master機器去寫,數據同步給別的slave機器,他們都拿去讀,分發掉大量的請求那是不是好很多,而且擴容的時候還可以輕鬆實現水平擴容。

啓動一臺slave 的時候,他會發送一個psync命令給master ,如果是這個slave第一次連接到master,他會觸發一個全量複製。master就會啓動一個線程,生成RDB快照,還會把新的寫請求都緩存在內存中,RDB文件生成後,master會將這個RDB發送給slave的,slave拿到之後做的第一件事情就是寫進本地的磁盤,然後加載進內存,然後master會把內存裏面緩存的那些新命令都發給slave。傳輸過程中有什麼網絡問題啥的,會自動重連的,並且連接之後會把缺少的數據補上的。

大家需要記得的就是,RDB快照的數據生成的時候,緩存區也必須同時開始接受新請求,不然你舊的數據過去了,你在同步期間的增量數據咋辦?是吧

 

內存淘汰機制:

Redis的過期策略有兩種,定期刪除和惰性刪除兩種。

定期刪除:默認100ms就隨機抽一些設置了過期時間的key,去檢查是否過期,過期了就刪了。

惰性刪除:見名知意,惰性嘛,我不主動刪,我懶,我等你來查詢了我看看你過期沒,過期就刪了還不給你返回,沒過期該怎麼樣就怎麼樣。

淘汰機制:

·  noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)

·  allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。

·  volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。

·  allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。

·  volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。

·  volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。

·  如果沒有鍵滿足回收的前提條件的話,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。

Redis中還有個LRU,過於複雜不詳細解釋了,

LRU:LRU是Least Recently Used的縮寫,即最近最少使用,是一種常用的頁面置換算法,選擇最近最久未使用的頁面予以淘汰。該算法賦予每個頁面一個訪問字段,用來記錄一個頁面自上次被訪問以來所經歷的時間 t,當須淘汰一個頁面時,選擇現有頁面中其 t 值最大的,即最近最少使用的頁面予以淘汰

Redis的數據類型的使用場景:

String數據類型:最簡單的類型,就是普通的set和get,做簡單的KV緩存。

但是在真實的開發環境中很多人可能會把很多比較複雜的結構也同意轉成String去存儲使用,比如有的人他就喜歡把對象或者List轉換爲JSONString進行存儲,在拿出來反序列化啥的,該方式沒有對錯,只是希望我們可以在最合適的場景使用最合適的數據,也更爲了代碼的規範。

String的實際應用場景比較廣泛:

  1. 緩存功能,String字符串是最常用的數據類型,不僅僅是redis,各個語言都是最基本類型,因此,利用redis作爲緩存,配合其他數據庫作爲存儲層,利用redis支持高併發的特點,可以大大加快系統的讀寫速度,以及降低後端數據庫的壓力。
  2. 計數器:許多系統都會使用redis作爲系統的實時計數器,可以快速實現計數和查詢的功能,而且最終的數據結果可以按照特定的時間落地到數據庫或者其他存儲介質當中警醒永久保存。
  3. 共享用戶session:用戶重新刷新一次界面,可能需要訪問以下數據進行重新登錄,或者訪問頁面緩存Cookie,但是可以利用Redis將用戶的session集中管理,在這種模式只需要保證Redis的高可用,每次用戶Session的更新和獲取都可以快速完成,大大提高效率。

Hash數據類型:

這個是類似Map的一種結構,這個一般就是可以將結構化的數據,比如一個對象(該對象沒嵌套其他的對象)給緩存在Redis中,然後每次讀寫緩存的時候,就可以操作hash裏的某個字段。該類型的使用場景比較單一了一些,因爲現在很多對象都是比較複雜的,比如我的工作事項對象裏面就包含了很多屬性,其中還有對象兩個。個人使用場景不是很多。

 

List數據類型:

List是有序列表,這個還是可以玩出很多花樣的,看你怎麼用了。

比如可以通過list存儲一些列表型的數據結構,類似粉絲列表,文章的評論列表之類的東西。

比如可以通過lrange命令,讀取某個閉區間內的元素,可以基於list實現分頁查詢,這個是很棒的一個功能,基於redis實現簡單的高性能分頁,可以做類似微博那種下拉不斷分頁的東西,性能高,就一頁一頁走。還可以搞個簡單的消息隊列,從list頭進去,從list結尾處弄出來,先進先出,後進後出。該類型使我們比較常用的數據結構了,熱點數據也是經常用的。

  1. 消息隊列:redis的鏈表結構,可以輕鬆實現阻塞隊列,可以使用左進左出的命令組成來完成隊列的設計。比如:數據的生產者可以通過Lpush命令從左邊插入數據,多個數據消費者,可以使用BRpop命令阻塞的“搶”列表尾部的數據。
  2. 文檔列表或者數據分頁展示的應用:

比如,我們常用的博客網站的文章列表,當用戶量越來越多時,而且每一個用戶都有自己的文章列表,而且當文章多時,都需要分頁展示,這時可以考慮使用redis的列表,列表不但有序同時還支持按照範圍內獲取元素,可以完美解決分頁查詢功能,大大提高查詢效率。

Set數據類型:

Set是無序集合,會自動去重。

直接基於 Set 將系統裏需要去重的數據扔進去,自動就給去重了,如果你需要對一些數據進行快速的全局去重,你當然也可以基於 JVM 內存裏的 HashSet 進行去重,但是如果你的某個系統部署在多臺機器上呢?得基於Redis進行全局的 Set 去重。

可以基於 Set 玩兒交集、並集、差集的操作,比如交集吧,我們可以把兩個人的好友列表整一個交集,看看倆人的共同好友是誰?對吧。

反正這些場景比較多,因爲對比很快,操作也簡單,兩個查詢一個Set搞定。

Sorted Set數據類型:

Sorted set是排序的set,去重但可以排序,寫進去的時候給一個分數,自動根據分許排序。

有序集合的使用場景與集合類似,但是set集合不是自動有序的,而Sorted set可以利用分數進行成員間的排序,而且是插入時就排序好。所以當你需要一個有序且不重複的集合列表時,就可以選擇Sorted set數據結構作爲選擇方案。

排行榜:有序集合經典使用場景。例如視頻網站需要對用戶上傳的視頻做排行榜,榜單維護可能是多方面:按照時間、按照播放量、按照獲得的贊數等。

Sorted Sets來做帶權重的隊列,比如普通消息的score爲1,重要消息的score爲2,然後工作線程可以選擇按score的倒序來獲取工作任務。讓重要的任務優先執行。

微博熱搜榜,就是有個後面的熱度值,前面就是名稱。

 

多個系統同時操作(併發)redis帶來的數據問題:

 

問題:系統A,B,C,分別去操作redis的同一個key,本來順序是1,2,3,但是因爲系統A網絡抖動了一下,B,C系統在他前面操作了redis,這樣數據不就錯了麼。

解決:

 

某個時刻,多個系統實例都去更新某個 key。可以基於 Zookeeper 實現分佈式鎖。每個系統通過 Zookeeper 獲取分佈式鎖,確保同一時間,只能有一個系統實例在操作某個 Key,別人都不允許讀和寫。

你要寫入緩存的數據,都是從 MySQL 裏查出來的,都得寫入 MySQL 中,寫入 MySQL 中的時候必須保存一個時間戳,從 MySQL 查出來的時候,時間戳也查出來。

每次要寫之前,先判斷一下當前這個 Value 的時間戳是否比緩存裏的 Value 的時間戳要新。如果是的話,那麼可以寫,否則,就不能用舊的數據覆蓋新的數據。

當緩存與數據庫雙存儲雙寫的時候,如何解決一致性問題?

一般來說,如果允許緩存可以稍微的跟數據庫偶爾有不一致的情況,也就是說如果你的系統不是嚴格要求 “緩存+數據庫” 必須保持一致性的話,最好不要做這個方案,即:讀請求和寫請求串行化,串到一個內存隊列裏去。

串行化可以保證一定不會出現不一致的情況,但是它也會導致系統的吞吐量大幅度降低,用比正常情況下多幾倍的機器去支撐線上的一個請求。

把一些列的操作都放到隊列裏面,順序肯定不會亂,但是併發高了,這隊列很容易阻塞,反而會成爲整個系統的弱點,瓶頸

 

KV,DB讀寫模式:

最經典的緩存+數據庫讀寫的模式,就是 Cache Aside Pattern

1.讀的時候,先讀緩存,緩存沒有的話,就讀數據庫,然後取出數據後放入緩存,同時返回響應。

2.更新的時候,先更新數據庫,然後再刪除緩存

爲何是刪除緩存,而不是更新緩存?

原因很簡單,很多時候,在複雜點的緩存場景,緩存不單單是數據庫中直接取出來的值。

比如可能更新了某個表的一個字段,然後其對應的緩存,是需要查詢另外兩個表的數據並進行運算,才能計算出緩存最新的值的。

另外更新緩存的代價有時候是很高的。是不是說,每次修改數據庫的時候,都一定要將其對應的緩存更新一份?也許有的場景是這樣,但是對於比較複雜的緩存數據計算的場景,就不是這樣了。如果你頻繁修改一個緩存涉及的多個表,緩存也頻繁更新。但是問題在於,這個緩存到底會不會被頻繁訪問到?

舉個栗子:一個緩存涉及的表的字段,在 1 分鐘內就修改了 20 次,或者是 100 次,那麼緩存更新 20 次、100 次;但是這個緩存在 1 分鐘內只被讀取了 1 次,有大量的冷數據

實際上,如果你只是刪除緩存的話,那麼在 1 分鐘內,這個緩存不過就重新計算一次而已,開銷大幅度降低。用到緩存纔去算緩存。

其實刪除緩存,而不是更新緩存,就是一個 Lazy 計算的思想,不要每次都重新做複雜的計算,不管它會不會用到,而是讓它到需要被使用的時候再重新計算。

MybatisHibernate,都有懶加載思想。查詢一個部門,部門帶了一個員工的 List,沒有必要說每次查詢部門,都裏面的 1000 個員工的數據也同時查出來啊。80% 的情況,查這個部門,就只是要訪問這個部門的信息就可以了。先查部門,同時要訪問裏面的員工,那麼這個時候只有在你要訪問裏面的員工的時候,纔會去數據庫裏面查詢 1000 個員工。

Redis和Memcached的區別,爲何選用redis:

Redis 支持複雜的數據結構:

Redis 相比 Memcached 來說,擁有更多的數據結構,能支持更豐富的數據操作。如果需要緩存能夠支持更復雜的結構和操作, Redis 會是不錯的選擇。

Redis 原生支持集羣模式:

在 redis3.x 版本中,便能支持 Cluster 模式,而 Memcached 沒有原生的集羣模式,需要依靠客戶端來實現往集羣中分片寫入數據。

性能對比:

由於 Redis 只使用單核,而 Memcached 可以使用多核,所以平均每一個核上 Redis 在存儲小數據時比 Memcached 性能更高。而在 100k 以上的數據中,Memcached 性能要高於 Redis,雖然 Redis 最近也在存儲大數據的性能上進行優化,但是比起 Remcached,還是稍有遜色。

Redis的線程模型:

Redis 內部使用文件事件處理器 file event handler,這個文件事件處理器是單線程的,所以 Redis 才叫做單線程的模型。它採用 IO 多路複用機制同時監聽多個 Socket,根據 Socket 上的事件來選擇對應的事件處理器進行處理。

文件事件處理器的結構包含 4 個部分:

1.多個 Socket

2.IO 多路複用程序

3.文件事件分派器

4.事件處理器(連接應答處理器、命令請求處理器、命令回覆處理器)

多個 Socket 可能會併發產生不同的操作,每個操作對應不同的文件事件,但是 IO 多路複用程序會監聽多個 Socket,會將 Socket 產生的事件放入隊列中排隊,事件分派器每次從隊列中取出一個事件,把該事件交給對應的事件處理器進行處理。

 

 

Redis的知識點結構:

 

 

 

 

補充:

緩存的知識點結構:

 

緩存有哪些類型?

緩存是高併發場景下提高熱點數據訪問性能的一個有效手段,在開發項目時會經常使用到。

緩存的類型分爲:本地緩存分佈式緩存多級緩存

本地緩存:

本地緩存就是在進程的內存中進行緩存,比如我們的 JVM 堆中,可以用 LRUMap 來實現,也可以使用 Ehcache 這樣的工具來實現。

本地緩存是內存訪問,沒有遠程交互開銷,性能最好,但是受限於單機容量,一般緩存較小且無法擴展。

分佈式緩存:

分佈式緩存可以很好得解決這個問題。

分佈式緩存一般都具有良好的水平擴展能力,對較大數據量的場景也能應付自如。缺點就是需要進行遠程請求,性能不如本地緩存。

多級緩存:

爲了平衡這種情況,實際業務中一般採用多級緩存,本地緩存只保存訪問頻率最高的部分熱點數據,其他的熱點數據放在分佈式緩存中。

在目前的一線大廠中,這也是最常用的緩存方案,單考單一的緩存方案往往難以撐住很多高併發的場景。

淘汰策略

不管是本地緩存還是分佈式緩存,爲了保證較高性能,都是使用內存來保存數據,由於成本和內存限制,當存儲的數據超過緩存容量時,需要對緩存的數據進行剔除。

一般的剔除策略有 FIFO 淘汰最早數據、LRU 剔除最近最少使用、和 LFU 剔除最近使用頻率最低的數據幾種策略。

  • noeviction:返回錯誤當內存限制達到並且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
  • allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
  • volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限於在過期集合的鍵,使得新添加的數據有空間存放。
  • allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
  • volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限於在過期集合的鍵。
  • volatile-ttl: 回收在過期集合的鍵,並且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。

如果沒有鍵滿足回收的前提條件的話,策略volatile-lruvolatile-random以及volatile-ttl就和noeviction 差不多了。

其實在大家熟悉的LinkedHashMap中也實現了Lru算法的,實現如下:

 

 

當容量超過100時,開始執行LRU策略:將最近最少未使用的 TimeoutInfoHolder 對象 evict 掉。

真實面試中會讓你寫LUR算法,你可別搞原始的那個,那真TM多,寫不完的,你要麼懟上面這個,要麼懟下面這個,找一個數據結構實現下Java版本的LRU還是比較容易的,知道啥原理就好了。

 

 

Memcache

注意後面會把 Memcache 簡稱爲 MC。

先來看看 MC 的特點:

  • MC 處理請求時使用多線程異步 IO 的方式,可以合理利用 CPU 多核的優勢,性能非常優秀;
  • MC 功能簡單,使用內存存儲數據;
  • MC 的內存結構以及鈣化問題我就不細說了,大家可以查看官網瞭解下;
  • MC 對緩存的數據可以設置失效期,過期後的數據會被清除;
  • 失效的策略採用延遲失效,就是當再次使用數據時檢查是否失效;
  • 當容量存滿時,會對緩存中的數據進行剔除,剔除時除了會對過期 key 進行清理,還會按 LRU 策略對數據進行剔除。

另外,使用 MC 有一些限制,這些限制在現在的互聯網場景下很致命,成爲大家選擇RedisMongoDB的重要原因:

  • key 不能超過 250 個字節;
  • value 不能超過 1M 字節;
  • key 的最大失效時間是 30 天;
  • 只支持 K-V 結構,不提供持久化和主從同步功能。

Redis

先簡單說一下 Redis 的特點,方便和 MC 比較。

  • 與 MC 不同的是,Redis 採用單線程模式處理請求。這樣做的原因有 2 個:一個是因爲採用了非阻塞的異步事件處理機制;另一個是緩存數據都是內存操作 IO 時間不會太長,單線程可以避免線程上下文切換產生的代價。
  • Redis 支持持久化,所以 Redis 不僅僅可以用作緩存,也可以用作 NoSQL 數據庫。
  • 相比 MC,Redis 還有一個非常大的優勢,就是除了 K-V 之外,還支持多種數據格式,例如 list、set、sorted set、hash 等。
  • Redis 提供主從同步機制,以及 Cluster 集羣部署能力,能夠提供高可用服務。

 

 

 

Redis基礎:(該帖子屬於下面這個鏈接的第一篇帖子)

https://juejin.im/post/5db66ed9e51d452a2f15d833

Redis系列:

https://zhuanlan.zhihu.com/p/91539644

Redis雙寫一致性,併發競爭,線程模型:

https://zhuanlan.zhihu.com/p/91196300

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章