詳解 Redis 面試題(一)




什麼是Redis

Redis(Remote Dictionary Server) 是一個使用 C 語言編寫的,開源的(BSD許可)高性能非關係型(NoSQL)的鍵值對數據庫。前端

Redis 能夠存儲鍵和五種不一樣類型的值之間的映射。鍵的類型只能爲字符串,值支持五種數據類型:字符串、列表、集合、散列表、有序集合。web

與傳統數據庫不一樣的是 Redis 的數據是存在內存中的,因此讀寫速度很是快,所以 redis 被普遍應用於緩存方向,每秒能夠處理超過 10萬次讀寫操做,是已知性能最快的Key-Value DB。另外,Redis 也常常用來作分佈式鎖。除此以外,Redis 支持事務 、持久化、LUA腳本、LRU驅動事件、多種集羣方案。redis

Redis有哪些優缺點

優勢數據庫

  • 讀寫性能優異, Redis能讀的速度是110000次/s,寫的速度是81000次/s。後端

  • 支持數據持久化,支持AOF和RDB兩種持久化方式。緩存

  • 支持事務,Redis的全部操做都是原子性的,同時Redis還支持對幾個操做合併後的原子性執行。服務器

  • 數據結構豐富,除了支持string類型的value外還支持hash、set、zset、list等數據結構。微信

  • 支持主從複製,主機會自動將數據同步到從機,能夠進行讀寫分離。數據結構

缺點多線程

  • 數據庫容量受到物理內存的限制,不能用做海量數據的高性能讀寫,所以Redis適合的場景主要侷限在較小數據量的高性能操做和運算上。

  • Redis 不具有自動容錯和恢復功能,主機從機的宕機都會致使前端部分讀寫請求失敗,須要等待機器重啓或者手動切換前端的IP才能恢復。

  • 主機宕機,宕機前有部分數據未能及時同步到從機,切換IP後還會引入數據不一致的問題,下降了系統的可用性。

  • Redis 較難支持在線擴容,在集羣容量達到上限時在線擴容會變得很複雜。爲避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源形成了很大的浪費。

爲何要用 Redis /爲何要用緩存

主要從「高性能」和「高併發」這兩點來看待這個問題。

高性能:

假如用戶第一次訪問數據庫中的某些數據。這個過程會比較慢,由於是從硬盤上讀取的。將該用戶訪問的數據存在數緩存中,這樣下一次再訪問這些數據的時候就能夠直接從緩存中獲取了。操做緩存就是直接操做內存,因此速度至關快。若是數據庫中的對應數據改變的以後,同步改變緩存中相應的數據便可!

高併發:

直接操做緩存可以承受的請求是遠遠大於直接訪問數據庫的,因此咱們能夠考慮把數據庫中的部分數據轉移到緩存中去,這樣用戶的一部分請求會直接到緩存這裏而不用通過數據庫。

爲何要用 Redis 而不用 map/guava 作緩存?

緩存分爲本地緩存和分佈式緩存。以 Java 爲例,使用自帶的 map 或者 guava 實現的是本地緩存,最主要的特色是輕量以及快速,生命週期隨着 jvm 的銷燬而結束,而且在多實例的狀況下,每一個實例都須要各自保存一份緩存,緩存不具備一致性。

使用 redis 或 memcached 之類的稱爲分佈式緩存,在多實例的狀況下,各實例共用一份緩存數據,緩存具備一致性。缺點是須要保持 redis 或 memcached服務的高可用,整個程序架構上較爲複雜。

Redis爲何這麼快

一、徹底基於內存,絕大部分請求是純粹的內存操做,很是快速。數據存在內存中,相似於 HashMap,HashMap 的優點就是查找和操做的時間複雜度都是O(1);

二、數據結構簡單,對數據操做也簡單,Redis 中的數據結構是專門進行設計的;

三、採用單線程,避免了沒必要要的上下文切換和競爭條件,也不存在多進程或者多線程致使的切換而消耗 CPU,不用去考慮各類鎖的問題,不存在加鎖釋放鎖操做,沒有由於可能出現死鎖而致使的性能消耗;

四、使用多路 I/O 複用模型,非阻塞 IO;

五、使用底層模型不一樣,它們之間底層實現方式以及與客戶端之間通訊的應用協議不同,Redis 直接本身構建了 VM 機制 ,由於通常的系統調用系統函數的話,會浪費必定的時間去移動和請求;

數據類型

Redis有哪些數據類型

Redis主要有5種數據類型,包括String,List,Set,Zset,Hash,知足大部分的使用要求

數據類型 能夠存儲的值 操做 應用場景
STRING 字符串、整數或者浮點數 對整個字符串或者字符串的其中一部分執行操做
對整數和浮點數執行自增或者自減操做
作簡單的鍵值對緩存
LIST 列表 從兩端壓入或者彈出元素
對單個或者多個元素進行修剪,
只保留一個範圍內的元素
存儲一些列表型的數據結構,相似粉絲列表、文章的評論列表之類的數據
SET 無序集合 添加、獲取、移除單個元素
檢查一個元素是否存在於集合中
計算交集、並集、差集
從集合裏面隨機獲取元素
交集、並集、差集的操做,好比交集,能夠把兩我的的粉絲列表整一個交集
HASH 包含鍵值對的無序散列表 添加、獲取、移除單個鍵值對
獲取全部鍵值對
檢查某個鍵是否存在
結構化的數據,好比一個對象
ZSET 有序集合 添加、獲取、刪除元素
根據分值範圍或者成員來獲取元素
計算一個鍵的排名
去重但能夠排序,如獲取排名前幾名的用戶

Redis的應用場景

總結一

計數器

能夠對 String 進行自增自減運算,從而實現計數器功能。Redis 這種內存型數據庫的讀寫性能很是高,很適合存儲頻繁讀寫的計數量。

緩存

將熱點數據放到內存中,設置內存的最大使用量以及淘汰策略來保證緩存的命中率。

會話緩存

可使用 Redis 來統一存儲多臺應用服務器的會話信息。當應用服務器再也不存儲用戶的會話信息,也就再也不具備狀態,一個用戶能夠請求任意一個應用服務器,從而更容易實現高可用性以及可伸縮性。

全頁緩存(FPC)

除基本的會話token以外,Redis還提供很簡便的FPC平臺。以Magento爲例,Magento提供一個插件來使用Redis做爲全頁緩存後端。此外,對WordPress的用戶來講,Pantheon有一個很是好的插件 wp-redis,這個插件能幫助你以最快速度加載你曾瀏覽過的頁面。

查找表

例如 DNS 記錄就很適合使用 Redis 進行存儲。查找表和緩存相似,也是利用了 Redis 快速的查找特性。可是查找表的內容不能失效,而緩存的內容能夠失效,由於緩存不做爲可靠的數據來源。

消息隊列(發佈/訂閱功能)

List 是一個雙向鏈表,能夠經過 lpush 和 rpop 寫入和讀取消息。不過最好使用 Kafka、RabbitMQ 等消息中間件。

分佈式鎖實現

在分佈式場景下,沒法使用單機環境下的鎖來對多個節點上的進程進行同步。可使用 Redis 自帶的 SETNX 命令實現分佈式鎖,除此以外,還可使用官方提供的 RedLock 分佈式鎖實現。

其它

Set 能夠實現交集、並集等操做,從而實現共同好友等功能。ZSet 能夠實現有序性操做,從而實現排行榜等功能。

總結二

Redis相比其餘緩存,有一個很是大的優點,就是支持多種數據類型。

數據類型說明string字符串,最簡單的k-v存儲hashhash格式,value爲field和value,適合ID-Detail這樣的場景。list簡單的list,順序列表,支持首位或者末尾插入數據set無序list,查找速度快,適合交集、並集、差集處理sorted set有序的set

其實,經過上面的數據類型的特性,基本就能想到合適的應用場景了。

string——適合最簡單的k-v存儲,相似於memcached的存儲結構,短信驗證碼,配置信息等,就用這種類型來存儲。

hash——通常key爲ID或者惟一標示,value對應的就是詳情了。如商品詳情,我的信息詳情,新聞詳情等。

list——由於list是有序的,比較適合存儲一些有序且數據相對固定的數據。如省市區表、字典表等。由於list是有序的,適合根據寫入的時間來排序,如:最新的***,消息隊列等。

set——能夠簡單的理解爲ID-List的模式,如微博中一我的有哪些好友,set最牛的地方在於,能夠對兩個set提供交集、並集、差集操做。例如:查找兩我的共同的好友等。

Sorted Set——是set的加強版本,增長了一個score參數,自動會根據score的值進行排序。比較適合相似於top 10等不根據插入的時間來排序的數據。

如上所述,雖然Redis不像關係數據庫那麼複雜的數據結構,可是,也能適合不少場景,比通常的緩存數據結構要多。瞭解每種數據結構適合的業務場景,不只有利於提高開發效率,也能有效利用Redis的性能。



來源:https://blog.csdn.net/ThinkWon/article/details/103522351


- END -
本人的專欄已上線,歡迎訂閱

有收穫就點個「在看」吧 

本文分享自微信公衆號 - 老懞大數據(simon_bigdata)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索