redis使用基礎(三) ——Redis事務與過期時間


redis使用基礎(三)

——Redis事務與過期時間

 

(轉載請附上本文鏈接——linhxx) 

 

一、事務(Transaction)

1、概述

         事務的定義和關系型數據庫一樣,保證各個步驟操作的原子性。另外,也保證這幾個步驟之間不會插入其他的步驟。但是,redis的事務沒有回退的功能。

         redis事務開始和結束的命令分別是MULTI和EXEC,在這兩個命令之間的其他命令,redis都會先存在隊列中,待接收到EXEC后一起執行。會返回一串的內容,返回值的順序和語句順序一致。

         當輸入MULTI,尚未輸入EXEC時,如果redis和客戶端斷線,則multi后面的命令全部不執行,並且redis會清空剛剛還沒執行的隊列;但是如果已經輸入EXEC,則即使后面發生斷網,中間的命令也會執行,因為命令已經存儲在redis的隊列中。

         另外,multi和exec之間的命令會同步執行,一起返回結果,所以不能在事務里面先獲取上一個命令操作的值進行下一個命令的操作。

 

2、錯誤處理

         1)語法錯誤

         如果在multi和exec之間有語法錯誤,則所有的命令都不會執行,包括正確的命令。

         2)運行錯誤

         運行錯誤時,除了錯誤的命令,其他正確的命令都會被執行。

 

3、WATCH命令

         watch類似鎖的功能,當watch某個key后,果在事務之前修改了此key,則在事務中無法操作此key。watch只針對一次的事務,即當匹配到第一個exec后,就不再監聽事務。

         因此,執行一次exec后,就會取消對所有key的watch。

         如果要提前取消watch,則可以在事務命令multi之前,發送一個UNWATCH命令,則取消所有的watch。

         但是,如果鍵是在過期時間后被自動刪除,並不會被watch認為鍵被改變。

 

4、取消事務

         DISCARD命令,使用后會放棄執行事務的所有命令。如果遇到watch,則此時除了放棄事務,還會自動再執行一個unwatch命令,取消監視。

 

 

二、過期時間

         redis的過期時間使用場景很廣泛,當需要設置緩存、令某個值僅在一段時間內有效(如優惠券等)、設置最短訪問間隔(防止爬蟲太多導致服務器宕機),則都需要設置過期時間。

 1、命令

         1)設置失效時間

1. EXPIRE key seconds,seconds是一個數字,即設置key在seconds秒之后失效,second要求是整數,即最少是1秒。當鍵不存在或者設置失敗會返回0,否則返回1。

2. PEXPIRE key millsecond,相當於設置毫秒,PEXPIRE key 1000 等效於EXPIRE key 1。

3. EXPIREAT key unixtime,將key的過期時間以unix時間進行設置,單位是秒。

4. PEXPIREAT key unixmilltime,與3的區別是這個是設置毫秒的。

         2)查看還有多久有效

         TTL key,返回值是剩余的時間,單位是秒。如果不存在,則返回-2;如果沒有設置過期時間,則返回-1。(這是redis2.8版的,2.6版則不存在和沒有設置過期都是-1)

         PTTL key,返回剩余的毫秒數。

         3)取消時間限制

         1.  PERSIST key,則此時再對key進行TTL命令查看,會發現返回-1。

         2. 重新SET key value,則此時會清除原來的時間限制。因此如果對值進行重新設置,需要重新設置失效時間。

         3. 重新expire key seconds,則會重置key的失效時間。

         4. 除了set,其他只對鍵值進行操作的命令,如lpush、hset、incr等均不會影響過期時間。

 

2、業務場景

1)緩存

         redis是將數據存在內存中,因此可以避免I/O的操作,以加快速度。

         通常,在讀數據庫的時候,會先讀緩存,如果有的話則直接返回,如果沒有的話會去數據庫拉數據,並把數據設置在redis上,再返回。此時,需要對redis的鍵名進行考量,通常要設置類似:id:title等作為鍵,把值序列化或者json后進行存儲。存儲的數據類型也需要考慮,是放於set、hash還是list,或者特殊情況下用sorted set。

         但是,也不是所有的操作放入緩存,只有大容量(圖片、長評論、文章等)或者頻繁改動(如訪問量)等放於緩存。相應的失效時間也需要考慮好。

         對於新增,通常使用懶加載的配置,即新增數據不更新緩存,會等到查詢的時候再更新緩存;但是修改、刪除數據的時候,就有很多的解決方案了。

對於修改、刪除數據,可以用類unix系統的方式進行處理,稱為Write Behind Caching Pattern,又稱Write Back。即當更新、刪除數據時,會先查緩存,如果沒有查到,則直接操作數據庫。如果查到有緩存,則更新緩存,並給緩存增加一個已經被改動的標記;當要刪除操作時,則對緩存加一個刪除標記。

系統有獨立的地方記錄上述每一處緩存的改動,當程序執行到結束時,會統一查看緩存的改動情況,並統一對數據庫進行操作。

此方法在高並發時,在命中緩存的情況下,必然數據一致性:

當更新了數據,此時如果有其他並發的再來查詢,會查詢到最新的數據(因為命中緩存,直接從緩存查看結果);如果要更新操作時,由於被加了已經更新的標簽,不允許再次更新,則后面的更新會返回錯誤碼;如果要刪除,則可以刪除,並增加刪除標簽(也可以根據業務需要,配置成不允許刪除)。

當刪除了數據,由於數據已經被加上刪除標簽,則此時再次增刪改查,會發現此刪除標簽,則會返回空結果,不從數據庫查詢。

程序執行結束后,會根據標簽,有修改標簽的對數據庫相應字段進行update,有刪除標簽的刪除數據庫相應數據。

2)設置優惠券

         優惠券的存儲可以用優惠券:優惠券id:優惠券類型的方式作為鍵,值可以設置1,並根據優惠券的使用時間定制expire second。當查詢優惠券有效期或者使用優惠券時,使用ttl命令查詢鍵,如果過期則該鍵不存在,此時則返回-2,否則返回優惠券的有效期。

3)最短訪問間隔

         此場景設置ip:ip值:業務場景為鍵,值可以設置1,並且設置expire second。當某個ip訪問時,在redis中進行查詢,如果鍵存在,則說明在最短訪問間隔內,則不允許訪問;如果鍵不存在,則說明不在最短訪問間隔,則設置一個值,並且本次允許訪問。

4)時間段內訪問總數

         如果要設置用戶某個時間段(如一分鍾內)可以訪問的頁面總數,則可以用列表的方式進行存儲。當用戶進行訪問時,先用llen判斷加上這個是否超過10個,如果不是則lpush,並且允許此次訪問;如果超過,則要判斷這個和最右邊的第一個(lrange -1,1)的時間差是否在1分鍾內,如果在一分鍾內,則不改變此list,並且不允許用戶的此次訪問;如果超過一分鍾,則lpush此次的時間,並且rpop第一個時間,允許用戶此次訪問。

 

3、redis用作緩存的時間設置

         緩存的時間設置太長,會導致redis占用大量的內存;但是設置的太短,又會使得redis的作用減少。因此,可以通過修改配置文件的maxmemory參數,設置redis的最大占用內存,並且設置maxmemory-policy設置內存超出時的策略。

         內存超出時會自動刪除數據,刪除的規則通常采用LRU(Least Recently Used),最近最少使用原則。另外也可以設置其他規則,如不同的參數值確定是否刪除未設置過期時間的鍵,或隨機刪除一個鍵,或刪除過期時間最近的一個鍵,或者不刪除僅返回錯誤。

 

 

——written by linhxx

 

更多最新文章,歡迎關注微信公眾號“決勝機器學習”,或掃描右邊二維碼。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM