面試官:你能說一下Redis的常見應用場景嗎?

1. 基礎

內存數據庫

Redis是一個key-value型的數據庫(相比較之下,MySQL是關聯數據庫),也就是說,一個key對應一個value,這是保證高效的手段之一。另外,Redis的全部數據在使用時都存放在內存中。2021Java面試寶典mysql

這包含了兩層含義:面試

  1. 單臺Redis能存放多少數據,取決於其內存的大小(假設全部內存都給Redis用)。若是須要存放更多數據,能夠增長內存或作集羣。redis

  2. Redis支持將數據持久化到磁盤中。

可是,不會直接對磁盤進行讀寫。這種持久化,通常是用於在服務器重啓時,先把數據持久化,重啓後再從磁盤中讀取到內存。spring

數據結構

Redis支持五種數據結構,分別是String,List,Hash,Set,Zset。即字符串,列表,哈希,集合,有序集合。sql

String是Redis最基本的類型,一個key對應一個value。數據庫

通常狀況下,大部分的內容均可以經過序列化後,再存在到Redis中,好比圖片或對象等。每一個key對就的value存儲的內容最大爲512M。數組

Hash即哈希表,即key-value對集合。緩存

是否是很奇怪?Redis的數據自己不就是key-value型的嗎?其實不奇怪。咱們這裏在說數據結構的時候,單指的是key-value中的value。也就是說,value是一個key-value對集合。想象一下這種數據結構,特別適合存儲對象。而且,Redis支持像數據庫中update同樣,單獨修改對象的某個屬性。服務器

List即列表。數據結構

value是一個字符串的列表。也就是說,一個value能夠存放多個字符串,能夠按照順序,添加到頭或尾。它就是一個雙向鏈表。很適合作如朋友圈動態列表或消息隊列等。

Set即集合。

它的value和列表的value同樣,也是一個字符串列表,只是Set是無序的,而且,value中的元素是不重複的。和Java中的Set差很少,它的基礎原理也是基於Hash實現的,因此添加、刪除、查找等的效率等都很快。Redis還爲Set提供了多個集合操做的API,如交集、並集、差集等。能夠利用來作統計,有多少個共同好友等。

Zset即有序集合。

它在Set的基礎上,給value中的每一個字符串關聯了一個score屬性,即得分。Zset經過計算得分,將字符串進行從小到大的排序。字符串的得分能夠相同。Zset的排序是在插入時直接就作好的。能夠用來作排行榜等。

2. Redis常出現的應用場景

緩存——熱數據

熱點數據(常常會被查詢,可是不常常被修改或者刪除的數據),首選是使用redis緩存,畢竟強大到冒泡的QPS和極強的穩定性不是全部相似工具都有的,並且相比於memcached還提供了豐富的數據類型可使用,另外,內存中的數據也提供了AOF和RDB等持久化機制能夠選擇,要冷、熱的仍是忽冷忽熱的均可選。

結合具體應用須要注意一下:不少人用spring的AOP來構建redis緩存的自動生產和清除,過程通常以下:step1-> Select 數據庫前查詢redis,有的話使用redis數據,放棄select 數據庫,沒有就select 數據庫,而後將數據插入redis; srep2-> update或者delete數據庫錢,查詢redis是否存在該數據,存在的話先刪除redis中數據,而後再update或者delete數據庫中的數據。 這種操做,若是併發量很小的狀況下基本沒問題,可是高併發的狀況請注意下面場景:

爲了update先刪掉了redis中的該數據,這時候另外一個線程執行查詢,發現redis中沒有,瞬間執行了查詢SQL,而且插入到redis中一條數據,回到剛纔那個update語句,這個悲催的線程壓根不知道剛纔那個該死的select線程犯了一個彌天大錯!因而這個redis中的錯誤數據就永遠的存在了下去,直到下一個update或者delete。

計數器

諸如統計點擊數等應用。因爲單線程,能夠避免併發問題,保證不會出錯,並且100%毫秒級性能。

隊列

至關於消息系統,與ActiveMQ,RocketMQ等工具相似,可是以爲簡單用一下還行,若是對於數據一致性要求高的話仍是用RocketMQ等專業系統。

因爲redis把數據添加到隊列是返回添加元素在隊列的第幾位,因此能夠作判斷用戶是第幾個訪問這種業務。隊列不只能夠把併發請求變成串行,而且還能夠作隊列或者棧使用。

位操做(大數據處理)

用於數據量上億的場景下,例如幾億用戶系統的簽到,去重登陸次數統計,某用戶是否在線狀態等等。騰訊10億用戶,要幾個毫秒內查詢到某個用戶是否在線,能怎麼作?

千萬別說給每一個用戶創建一個key,而後挨個記(你能夠算一下須要的內存會很恐怖,並且這種相似的需求不少。這裏要用到位操做——使用setbit、getbit、bitcount命令。原理是:

redis內構建一個足夠長的數組,每一個數組元素只能是0和1兩個值,而後這個數組的下標index用來表示用戶id(必須是數字哈),那麼很顯然,這個幾億長的大數組就能經過下標和元素值(0和1)來構建一個記憶系統。

最新列表

例如新聞列表頁面的最新的新聞列表,若是總數量很大的狀況下,儘可能不要使用select a from A limit 10這種low貨,嘗試redis的 LPUSH命令構建List,一個個順序都塞進去就能夠啦。不過萬一內存清掉了咋辦?也簡單,查詢不到存儲key的話,用mysql查詢而且初始化一個List到redis中就行了。2021Java面試寶典

相關文章
相關標籤/搜索