1. 程式人生 > >要點摘煉Redis篇|JavaEE網際網路輕量級框架整合開發

要點摘煉Redis篇|JavaEE網際網路輕量級框架整合開發

背景:在傳統的Java Web專案中,使用資料庫來進行儲存資料,但這有一些來自效能方面的弊端。
為什麼呢?因為資料庫持久化資料主要是面向磁碟,而磁碟的讀寫比較慢,如果是存在高併發,有瞬間需要讀寫大量資料的要求的場景(比如即將到來的淘寶雙十一,還有搶紅包,還有商品搶購場景),一瞬間成千上萬的請求發來,需要系統在極短的時間內完成成千上萬次的讀寫操作,這時候就往往不是普通資料庫能夠承受的了,極其容易造成資料庫系統癱瘓,最終導致伺服器宕機的嚴重生產問題。

一、redis介紹

是一種NoSQL技術,NoSQL工具也是一種簡易的資料庫,主要是一種基於記憶體的資料庫,並提供一定的持久化功能。(PS:MongoDB也是一種NoSQL技術)。redis的效能十分優越,可以支援每秒十幾萬次的讀寫操作,並且支援叢集、分散式、主從同步等配置,原則上可以無限擴充套件,讓更多的資料儲存在記憶體中,還支援一定的事務能力,這在高併發訪問的場景下保證資料安全和一致性特別有用。
從以下三方面體現redis的效能優越性

  • 它是基於ANSI C語言寫的,接近於組合語言,執行十分快速。
  • 它是基於記憶體的讀寫,速度自然比資料庫的磁碟讀寫操作快得多。
  • 它的資料庫結構只有6中資料型別,資料結構比較簡單易用。

redis的常用使用場景

  • 快取常用的資料,如一些命中率高(即使用頻率高)的資料。
  • 在需要高速讀寫的場合使用它快速讀寫,比如搶紅包和商品搶購的場景。

redis的快取應用

在資料庫的讀寫操作中,往往是讀操作次數遠超寫操作次數,當傳送SQL去資料庫進行讀取時,資料庫就回去磁碟把對應的資料索引取出來,而索引磁碟是一個相對緩慢的過程。如果把資料直接放在執行在記憶體的Redis伺服器上,那麼就不再需要去讀寫磁碟了,直接讀取記憶體,速度就相應得快很多,並且也極大地減輕資料庫的壓力。

是否使用redis快取資料的三方面考慮
  • 業務資料常用嗎?命中率高?若命中率低就沒必要寫入快取。
  • 該業務資料是讀操作多還是寫操作多,若是需要頻繁寫入資料庫的操作也沒必要使用快取。
  • 業務資料大小如何?如果儲存幾百兆的檔案也沒必要使用快取,會給快取帶來巨大壓力。
高速讀寫場合

如上面說的淘寶的雙十一和春運搶票等場景,一瞬間成千上萬的請求伺服器,這時應對方法往往是考慮非同步寫入資料庫。即先把高速讀寫的資料快取到Redis中,在滿足一定的條件下,觸發這些快取的資料寫入資料庫中。
(舉例說明:如在商品秒殺的場景把業務資料先在redis中讀寫,當一個請求操作完redis的讀寫後,會去判斷該高速讀寫的業務是否結束,比如這裡的條件可以是秒殺商品的剩餘數為0,此時判斷條件成立則觸發事件講redis快取的資料以批量的形式一次性寫入資料庫,從而完成持久化的工作。)

二、Redis的安裝

①windows上安裝
redis下載地址,download下來後解壓縮即可,為了方便在解壓後的檔案裡新建一個startup.cmd檔案,在裡面寫上redis-server redis.windows,conf 然後儲存,用於快速啟動redis,啟動的時候直接雙擊即可。
圖片.png
在啟動redis後還可以使用解壓縮檔案裡的redis-cli.exe,這是一個redis自帶的客戶端工具。
圖片.png
②linux上安裝,這才是實際中最常用的,redis往往安裝在伺服器端系統。如下步驟:

①使用root使用者登入linux系統 即su root "密碼"
②在指定目錄mkdir新建目錄,在切換進入目錄
③執行一下命令
 wget http://download.redis.io/releases/redis-3.2.4.tar.gz
 tar xzf redis-3.2.4.tar.gz    //解壓檔案到當前資料夾的命令
 cd redis-3.2.4  
 make              //安裝redis的命令 
④等待片刻,之後在當前目錄執行src/redis-server,就可以看到redis啟動好了。
⑤在當前目錄可以另外開啟一個linux視窗,輸入src/redis-cli啟動redis自帶的命令列視窗

三、Redis的6種資料型別

Redis是一種基於記憶體的資料庫,並且提供一定的持久化功能,它是一種鍵值對資料庫,使用key作為索引找到當前快取的資料。分別有6種資料型別:字串(String)、列表(List)、集合(set)、雜湊結構(hash)、有序集合(zset)、基數(HyperLogLog)。redis定義的這6種資料型別除了可以儲存外,還可以對儲存的資料進行一些計算。
此外,Redis還支援一些事務、釋出訂閱訊息模式、主從複製、持久化等作為Java程式猿需要知道的功能。

四、Redis的事務

和其他大多數NoSQL不同,Redis是存在事務的。網際網路系統面向的是大眾,很多使用者同時訪問,這時系統的效能就很重要的。在Redis中,也存在多個客戶端同時向Redis系統傳送命令的併發可能性,因此同一個資料,可能在不同的時刻被不同的執行緒所操縱,這樣就出現了併發下的資料一致的問題。為了保證異性資料的安全性,redis提供了事務方案,而redis的事務是使用multi-exec的命令組合,使用它可以提供以下2個保證:
①事務是一個被隔離的操作,事務中方法都會被redis進行序列化並按順序執行,事務在執行的過程中不會被其他客戶端發生的命令打斷
②事務是一個原子性的操作,要麼全部執行,要麼全不執行。
使用spring中會使用SessionCallback介面進行處理,在redis中使用事務會經過3個過程,分別為:①開啟事務,②命令進入佇列,③執行事務
常用的Redis事務命令:
1、multi(開啟事務)
2、watch(監聽某個鍵,當被監聽的鍵在事務執行前被修改,則事務會被回滾)
3、unwatch(取消監聽某個鍵)
4、exec(執行事務,若被監聽的鍵在事務執行前被修改,則事務會被回滾,沒有的話則執行命令)
5、discard(回滾進入佇列的事務命令,之後不能用exec提交事務)
下圖表明開啟事務後輸入的命令在沒有exec執行的時候是一直都存在佇列裡的。 圖片.png

PS:注意一點:Redis在命令入隊的時候,就會檢查事務的命令是否正確,若不正確則之前之後的命令都會回滾,若事務命令正確則執行。可當命令格式正確,而因為資料結構錯誤,則該命令執行會報錯,而其之前之後的命令都會正常執行,這點就和資料庫很不一樣。

多執行緒使用的CAS與樂觀鎖

當一條執行緒執行某個業務邏輯,但這條業務邏輯操作的資料被其他執行緒共享了,這樣就會引發執行緒中資料不一致的情況。為了解決這問題,在讀取這些多執行緒共享的資料時將其儲存到當前執行緒的副本中,成為舊值,之後在執行更新前比較當前執行緒副本儲存的舊值和當前的執行緒共享的值是否一致,若不一致則更新失敗。
由CAS產生而來的ABA問題:即多個執行緒訪問了同一資料,經過一陣修改,改去又改回,最後的值還是和舊值一致,這樣redis事務就認為正常事務,但是資料已經被修改過了。

在redis執行事務的過程中,並不會阻塞其他連線的併發,而只是通過比較watch監控的鍵值對去保證資料的一致性,所以redis多個事務完全可以在非阻塞的多執行緒環境下併發執行,而且redis的機制是不會產生ABA問題的。

五、Redis總結

Redis和資料庫一樣可以儲存資料,但不代表Redis會取代資料庫。有以下原因:
① 雖然NoSQL資料結構比較簡單,能處理很多問題,但是其功能畢竟有限,沒有SQL語句強大,支援複雜的計算
②NoSQL並不完全安全穩定,由於它基於記憶體,一旦停電或者機器故障資料就很容易丟失了,而且持久化能力也是有限的
③其資料完整性、事務能力、安全性、可靠性、擴充套件性都不如資料庫
所以,NoSQL和傳統資料庫各有優勢,NoSQL的主要應用場景在於對效能有要求的地方,如果一個系統對效能要求不大,則也沒什麼必要使用NoSQL技術,傳統資料庫便可適用。