自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis緩存技術學習系列之事務處理

開發(fā) 前端 Redis
我們可以注意到,Redis是一個C/S架構的數(shù)據(jù)庫,在我們目前的認知中,它是通過終端中的一條條命令來存儲和讀取的,即它是一個非常典型的“請求-響應”模型。可是我們知道在實際的應用中,我們要面對的或許是更為復雜的業(yè)務邏輯,因為Redis中不存在傳統(tǒng)關系型數(shù)據(jù)庫中表的概念,因此在使用Redis的過程中,我們要面對兩個實際的問題,即如何更好的維護數(shù)據(jù)庫中的”鍵“、如何在高效執(zhí)行命令的同時保證命令執(zhí)行成功。

在本系列的***篇文章中,我們主要針對Redis中的“鍵”和“值”進行了學習。我們可以注意到,Redis是一個C/S架構的數(shù)據(jù)庫,在我們目前的認知中,它是通過終端中的一條條命令來存儲和讀取的,即它是一個非常典型的“請求-響應”模型。可是我們知道在實際的應用中,我們要面對的或許是更為復雜的業(yè)務邏輯,因為Redis中不存在傳統(tǒng)關系型數(shù)據(jù)庫中表的概念,因此在使用Redis的過程中,我們要面對兩個實際的問題,即如何更好的維護數(shù)據(jù)庫中的”鍵“、如何在高效執(zhí)行命令的同時保證命令執(zhí)行成功。對于前者,我認為這是一個設計上的問題,而對于后者,我認為這是一個技術上的問題。所以,這篇文章的核心內(nèi)容就是找到這兩個問題的答案。帶著這樣的問題出發(fā),我們就可以正式進入這篇文章的主題:Redis中的事務處理。

Redis緩存技術學習系列之事務處理

從數(shù)據(jù)庫事務說起

​ 通常我們提及數(shù)據(jù)庫都不可避免的要提到事務,那么什么是事務呢?事務是指作為單個邏輯工作單元執(zhí)行的一系列操作。所以,首先事務是一系列操作,這一系列操作具有二態(tài)性,即完全地執(zhí)行或者完全地不執(zhí)行。因此事務處理可以確保除非事務單元內(nèi)的所有操作的成功完成,否則不會***更新面向數(shù)據(jù)的資源。我們這里舉一個例子,數(shù)據(jù)庫中除查詢操作以外,插入(Insert)、刪除(Delete)和更新(Update)這三種操作都會對數(shù)據(jù)造成影響,因為事務處理能夠保證一系列操作可以完全地執(zhí)行或者完全不執(zhí)行,因此在一個事務被提交以后,該事務中的任何一條SQL語句在被執(zhí)行的時候,都會生成一條撤銷日志(Undo Log),而撤銷日志中記錄的是和當前擦作完全相反的操作,比如刪除的相反操作是插入,插入的相反操作是刪除等。我們通常所說的事務回滾其實就是去執(zhí)行這些插銷日志里的相反操作,這同樣告訴我們一個道理,只有事務中的一系列操作完全執(zhí)行的情況下可以回滾,如果是在意外情況下導致事務中的一系列操作沒有完全執(zhí)行,這個時候我們是不能保證數(shù)據(jù)一定可以回滾的。

​ 在數(shù)據(jù)庫相關理論中,一個邏輯工作單元想要成為事務,就必須滿足ACID,即原子性、一致性、隔離性和持久性。(1):原子性這個概念其實就是指,一個事務內(nèi)的所有SQL操作都是一個整體,因此只有所有的SQL操作都完全執(zhí)行成功,該事務方可以認為提交成功。如果在提交事務過程中某一條SQL語句執(zhí)行失敗,則整個事務必須回滾到事務提交前的狀態(tài)。(2):而一致性這個概念則是指,事務在完成的時候,必須要保證所有的數(shù)據(jù)都保持一致的狀態(tài),而落實到數(shù)據(jù)庫的各個組成部分上,則要求開發(fā)人員能夠保證數(shù)據(jù)、索引、約束、日志等在事務前后具備一致性。(3):隔離性這個概念主要針對并發(fā),其核心思想就是不同的并發(fā)事務對數(shù)據(jù)產(chǎn)生的修改必須是相互隔離的,假設有兩個不同的事務A和B并發(fā)執(zhí)行,那么對A來講,它在執(zhí)行前的狀態(tài)只有兩種,即B執(zhí)行前和B執(zhí)行后。同理,對B來講同樣是如此,這樣的特性我們就稱為隔離性。(4):持久性相對簡單,是指事務完成以后它對數(shù)據(jù)的影響是***性的。

Redis中的事務處理

​ 好了,截止到目前為止,我們對數(shù)據(jù)庫中事務處理的相關理論有了一個基本的認識,或許這個世界上的數(shù)據(jù)庫系統(tǒng)千差萬別,但我相信在事務處理這個問題上它們最終會殊途同歸,就像我們解決并發(fā)過程中的沖突問題,常規(guī)的做法依然是加鎖一樣,這是我之所以要花費精力去理解和解釋這些理論知識的原因,技術可謂是日新月異,如果我們總是一味地為新技術而疲于奔命,那么或許我們會漸漸地失去對這個行業(yè)的熱愛,我相信原理永遠比框架更為重要,沒有系統(tǒng)學習過計算機專業(yè)的課程,這件事情讓我至今都頗為遺憾。Redis中的事務是可以視為一個隊列,即我們可以通過MULTI開始一個事務,這相當于我們聲明了一個命令隊列。接下來,我們向Redis中提交的每條命令,都會被排入這個命令隊列。當我們輸入EXEC命令時,將觸發(fā)當前事務,這相當于我們從命令隊列中取出命令并執(zhí)行,所以Redis中一個事務從開始到執(zhí)行會經(jīng)歷 開始事務 、 命令入隊 和 執(zhí)行事務 三個階段。下面是一個在Redis中使用事務的簡單示例:

 

  1. 127.0.0.1:6379> MULTI 
  2. OK 
  3. 127.0.0.1:6379> SET Book_Name "GIt Pro" 
  4. QUEUED 
  5. 127.0.0.1:6379> SADD Program_Language "C++" "C#" "Jave" "Python"  
  6. QUEUED 
  7. 127.0.0.1:6379> GET Book_Name 
  8. QUEUED 
  9. 127.0.0.1:6379> EXEC 
  10. 1) OK 
  11. 2) (integer) 4 
  12. 3) "GIt Pro" 

我們可以注意到Redis中的事務和通常意義上的事務基本上是一致的,即

  • 事務是由一系列操作組成的單個邏輯工作執(zhí)行單元。特別地,因為在Redis中命令是存儲在一個隊列中,所以,事務中的所有命令都會按順序執(zhí)行,并且在執(zhí)行事務的過程中不會被客戶端發(fā)送的其它命令中斷。
  • 事務是一個原子操作,事物中的命令只有兩種執(zhí)行結果,即全部執(zhí)行或者全部不執(zhí)行。如果客戶端在使用MULTI命令開啟事務后因為意外而沒有執(zhí)行EXEC命令,則事務中的所有命令都不會執(zhí)行。同理,如果客戶端在使用MULTI命令開啟事務后執(zhí)行EXEC命令,則事務中的所有命令都會執(zhí)行。
  • Redis中的事務可以使用DISCARD命令來清空一個命令隊列,并放棄對事務的執(zhí)行。如果命令在入隊時發(fā)生錯誤,Redis將在客戶端調用EXEC命令時拒絕執(zhí)行并取消事務,但是在EXEC命令執(zhí)行后發(fā)生的錯誤,Redis將選擇自動忽略。

我們知道,常見的并發(fā)控制方案主要有悲觀鎖和樂觀鎖兩種方案,這里首先來解釋下這兩種概念。所謂悲觀鎖,顧名思義是一種悲觀的策略,悲觀鎖認為:在對任何記錄做修改前都應該加鎖,如果加鎖失敗則表明該機錄正在被修改,此時應該拋出異常;如果加鎖成功則修改記錄并在事務完成后解鎖;如果有其它人修改則應該等待當前修改解鎖或者是拋出異常。而所謂樂觀鎖,顧名思義是一種樂觀的策略,樂觀鎖認為:每次從記錄中查找數(shù)據(jù)別人都不會修改,因此這個過程中不需要加鎖,但是在更新記錄的時候,會通過版本號來判斷別人是否修改過當前記錄。

通常來講,樂觀鎖適合在寫沖突相對較少的場合下,悲觀鎖適合在寫沖突相對較多的場合下。Redis中提供了一種稱為check-and-set的機制,該機制主要通過WATCH命令來實現(xiàn),其原理正是基于樂觀鎖的策略,Redis會在執(zhí)行EXEC命令前檢查被監(jiān)視的鍵對應的值是否發(fā)生變化,如果該值發(fā)生變化表明有人修改過這個鍵中存儲的值,此時Redis將會自動取消當前事務。我們來看這個簡單的例子:

 

  1. WATCH Record_Count 
  2. val = GET Record_Count 
  3. val = val + 1 
  4. MULTI 
  5. SET Record_Count $val 
  6. EXEC 

在這個例子中,我們嘗試在事務中對Record_Count做一個自增操作,這段代碼在非并發(fā)的情況下是沒有問題的,可是在并發(fā)的情況下,如果在執(zhí)行EXEC命令前有一個用戶修改了Record_Count的值,那么我們此時的結果就會比期望的結果小1,現(xiàn)在我們有了WATCH,Redis就會對Record_Count進行監(jiān)聽,當Redis監(jiān)聽到該值發(fā)生變化的時候,這個事務就會被自動取消,進而避免造成沖突。

如何管理Redis的鍵

​ 其實從切題的角度來講,這篇博客基本上說清楚了事務處理問題,因此這篇博客雖然沒有給大家?guī)矶嗌袤@喜,卻依然可以非常恰到好處的結題,可是因為之前有朋友在博客中留言并問到Redis的鍵管理的問題,所以博主決定在這里簡單的討論下這個問題,鑒于博主和大家一樣都是感剛接觸Redis,所以下面的觀點僅僅是一家之言,如果有疑問可以在博客中留言,歡迎大家批評指正。我認為Redis中的鍵的管理,基本上有兩種策略,即惰性刪除和定期刪除,而實際上這正是Redis默認的鍵刪除策略:

redis使用 惰性刪除 和 定期刪除 兩種策略來刪除過期的鍵:惰性刪除策略在碰到過期鍵時方進行刪除操作,定期刪除策略則每隔一段時間主動查找并刪除過期鍵。

所以,基于這兩種鍵刪除策略,我們可以想到的做法有:

  • 對于臨時變量可以采用臨時鍵來存儲,在數(shù)據(jù)庫全局設定一個過期時間,由Redis在鍵過期后自動刪除。
  • 對于持久化數(shù)據(jù)可以采用普通鍵來存儲,通過服務器和客戶端間定義協(xié)議來由客戶端主動刪除鍵。
  • 對于不同模塊中的鍵采取統(tǒng)一規(guī)范的命名規(guī)則來命名鍵,從而解決Redis中鍵管理混亂的問題。

設計合理的鍵回收機制,避免Redis使用超過95%以上的內(nèi)存,或者通過設置Redis中的***內(nèi)存容量及其內(nèi)存策略來主動觸發(fā)Redis對鍵的淘汰。

好了,這篇文章就是這樣了,希望大家喜歡,下篇見!

責任編輯:未麗燕 來源: 秦元培
相關推薦

2011-04-27 15:55:16

2022-06-22 05:42:32

數(shù)據(jù)庫事務處理分析查詢

2009-07-15 17:41:55

iBATIS事務處理

2009-09-14 19:55:03

LINQ事務處理

2009-07-09 18:15:42

JDBC事務處理

2009-11-13 17:01:07

ADO.NET事務處理

2010-04-13 15:44:00

Oracle與SqlS

2014-01-22 13:37:53

2010-01-04 13:06:50

ADO.NET事務

2009-11-17 10:07:18

IBMPureScalePower

2010-05-17 14:59:05

MySQL事務處理

2009-11-04 15:05:45

ADO.NET事務

2022-06-13 10:42:21

分布式事務數(shù)據(jù)庫

2009-04-15 17:03:15

OracleSQL Server事務處理

2011-04-27 16:09:48

SQL ServerSSIS

2015-03-16 14:38:16

大數(shù)據(jù)存儲分布式系統(tǒng)事務處理

2010-01-13 14:13:24

VB.NET事務處理

2014-02-11 09:07:31

2019-07-30 07:26:26

技術分布式指標

2009-06-16 11:42:00

JDBC事務處理JavaBean
點贊
收藏

51CTO技術棧公眾號