Redis字符串的具體使用

  • 2019 年 10 月 8 日
  • 筆記

在上一篇中我們詳細介紹了Redis字符串類型的相關命令及內部編碼,在這一篇中,我們將通過上一篇的學習來了解一下在日常的開發中使用Redis的字符串類型,可以解決我們什麼問題?


使用場景

一. 緩存功能

我們做開發時,都知道,項目中的所有的數據都是從存儲層獲取的,也就是數據庫中。但如果所有的請求都從數據庫中獲取,會導致系統有很大的壓力,因為直接從數據庫中獲取數據,會涉及到數據庫中讀寫操作,而數據庫中讀寫操作是會耗費系統資源的。所以對於大部分公司來說,系統的架構中都會添加一個緩存層,大部分的請求數據都會先從緩存層中獲取,如果緩存層中沒有查到數據,在從存儲層獲取,也就是數據庫中。然後在將存儲層獲取到的數據同步到緩存層中。這樣一來,對於大部分請求來說都會從緩存層中查找到,這樣就大大降低了存儲層的壓力。而緩存層Redis是一種解決方案之一。下面我們簡單模擬一下用戶請求數據的過程。


二. 計數

計數功能在很多網站中都比較常見,最典型的就是頁面的播放量。對於一個視頻網站來說,由於訪問的人數較多,如果每次有人訪問,都直接修改數據庫的話,那這種大並發量並且頻繁的修改數據庫的話,一定會對數據庫造成較大的壓力,極端情況下可能會導致數據庫宕機等,並且由於訪問量較大,我們在開發時,還要考慮多線程的兼容問題,否則會造成數據的不準確。除此之外,由於訪問量很大,也會造成每個用戶請求返回的時間變長,用戶訪問網站時,可能會顯示遲鈍等。而用Redis則不會出現這種情況。首先Redis是將數據保存到內存中的,相比數據庫的磁盤IO操作,性能提升較明顯。其次Redis是單線程架構,我們不用為大並發,而做特殊的多線程處理。其三就是Redis提供了很多支持原子性操作的命令,我們可以直接使用,而不用考慮相關細節。所以用Redis來實現網站或者其它業務的計數功能是比較合適的。但有一點要特別注意,我們將計數的數據保存在Redis中是為了不頻繁的執行數據庫的修改操作。而數據的最終結果還是要保存在數據庫中的(雖然Redis有持久化功能)。所以我們在實際的開發中,可以選擇某個時間點,在將Redis中的計數數據同步到數據庫中,大多數都會採用定時調度的方式,來同步數據,當然也可以考慮其它的計數實現。


三. 共享Session

我們知道在項目開發中Session中保存着用戶的登錄信息,當用戶訪問系統時首先判斷該用戶的Session中有沒有該用戶的信息,當然還要判斷是否超過了Session失效時間。如果有則認為用戶已經成功登錄過,所以允許訪問,反之,則提示用戶登錄,或者直接跳轉到登錄。在單一的架構中,上述場景是沒有問題的,但是在分佈式架構中上述場景就有問題了。我們知道Session是保存在服務端的,也就是說,我們的服務端部署在哪台機器上,Session就保存在哪台機器上。而分佈式的方式是將服務端部署到了多台機器上。這就會導致一個問題,雖然用戶登錄成功了,但是由於負載均衡等原因,給用戶提供服務的服務端和給用戶登錄的服務端,不在一台機器上,這樣就會出現,雖然用戶登錄成功了,但是我們還是會提示用戶沒有登錄。因為除了用戶登錄那台機器有用戶Session信息外,其它的機器沒有用戶的Session信息,所以會出現上述情況。也就是如下圖所示的那樣:

既然上述的場景在分佈式中有問題,那我就要想辦法解決它。解決的方式有很多種,在這裡,只介紹一種解決方案,也就是採用Redis解決。當用戶登錄成功時,我們不在將Session信息保存到本地的服務器中,而是將它保存到Redis中。這樣無論哪個服務器先登錄成功,對於用戶的Session信息只有一份,也就是保存到Redis中的那一份。這樣,當其它服務器判斷用戶是否登錄時,都從Redis中獲取Session信息。如果Redis中有用戶的Session信息,而用戶一定登錄成功過。否則,而用戶未登錄過,或者登錄失敗。這樣就解決了,分佈式用戶登錄的問題。也就是如下圖所示:


上述這些都是Redis中字符串類型的使用場景,但在實際開發中使用場景遠遠不只這些。只要我們熟練的使用Redis中字符串類型的相關命令,就可以解決我們開發中很多複雜的問題。