redis中的事務,鍵的過期時間以及排序

事務(MULTI)

Redis中的事務是一組命令的集合,事務同命令一樣都是Redis的最小執行單位,一個事務中的命令要麼都執行,要麼都不執行

原理:

  • 先將MULTI命令發送給Redis,告訴Redis我要開啓一個事務
  • 之後Redis將收到的命令全部放到一個事務隊列中,暫不執行
  • 直到收到EXEC命令,Redis會將等待執行的事務隊列中的命令按照發送順序依次執行,返回值順序和命令的順序相同
  • Redis還能保證一個事務內的命令依次執行而不被其他命令插入
  • Redis不支持回滾操作,語法錯誤其餘命令都不會執行,命令與數據類型不匹配等運行錯誤就算出現,其餘命令還是會執行,如果出現錯誤就只能自己去解決這個問題了

WATCH

  • WATCH命令可以監控一個或多個鍵,一旦其中有一個鍵被修改(或刪除),之後的事務就不會被執行,監控一直持續到EXEC命令
  • 由於WATCH命令的作用只是當被監控的鍵值被修改後阻止之後一個事務的執行,而不能保證其他客戶端不修改這一鍵值,所以我們需要在EXEC執行失敗後重新執行整個函數
  • 執行EXEC命令後會取消對所有鍵的監控,如果不想執行事務中的命令也可以使用UNWATCH命令來取消監控

過期時間

設置過期時間(EXPIRE)

SET name xiaoming
EXPIRE name 20

查詢過期時間(TTL)

TTL name
  • EXPIRE命令使用方法爲EXPIRE key seconds,seconds表示鍵的過期時間,單位是秒
  • PEXPIRE命令更精確的控制過期時間,單位爲毫秒,PTTL key 查看以毫秒爲單位的過期時間
  • EXPIREAT命令是使用Unix時間作爲第二個參數表示鍵的過期時刻

設置緩存淘汰鍵的規則

當服務器內存有限時,如果大量的使用緩存鍵且過期時間設置的很長就會導致redis佔滿內存
另一方面如果爲了防止redis佔用內存過大而將緩存鍵的過期時間設置的太短,就可能導致緩存命中率過低並且大量的內存白白的閒置.
實際開發中會發現很難爲緩存鍵設置合理的過期時間,爲此可以限制redis能夠使用的最大內存,並讓redis按照一定的規則淘汰不需要的緩存鍵,
這種方式在只將redis用作緩存系統時非常實用

具體設置方法: 修改配置文件中的maxmemory參數,限制redis最大可用內存大小(單位是字節),
當超出這個限制時會一句maxmemory-policy參數指定的策略來刪除不需要的鍵,直到redis佔用的內存小於指定內存

規則 說明
volatile-lru 使用LRU算法刪除一個鍵(只對設置了過期時間的鍵)
allkeys-lru 使用LRU算法刪除一個鍵
volatile-random 隨機刪除一個鍵(只對設置了過期時間的鍵)
allkeys-random 隨機刪除一個鍵
volatile-ttl 刪除過期時間最近的一個鍵
noeviction 不刪除鍵,只返回錯誤

LRU算法:最近最少使用,其認爲最近最少使用的鍵在未來一段時間內也不會被用到,即當需要空間時這些鍵是可以被刪除的

提示:使用allkeys-lru規則時,事實上redis並不會準確的將整個數據庫中最久未被使用的鍵刪除,而是每次從數據庫中隨機取3個鍵並刪除這三個鍵中最久未被使用的鍵,
刪除過期時間最接近的鍵的實現方也是這樣,"3"這個數字可以通過redis的配置文件中的maxmemory-samples參數設置

排序

sort命令排序

功能:sort可以對列表類型,集合類型和有序集合類型進行排序,並且可以完成與關係數據庫中的連接查詢相類似的任務

SORT key
  • 在對有序集合類型排序時會忽略元素的分數,只針對元素自身的值進行排序
  • 除了可以排列數字外,sort命令還可以通過ALPHA參數實現按照字典順序排列非數字元素
LPUSH mylistalpha a c e d B C A
SORT mylistalpha ALPHA --> A B C a c d e
  • SORT命令默認是按照從小到大的順序排列的,DESC參數可以將元素按照從大到小排列
SORT numbers DESC
  • SORT命令還支持LIMIT參數來返回指定範圍的結果LIMIT offset count,表示跳過前offset個元素並獲取之後的count個元素
SORT numbers DESC LIMIT 1 2

SORT中的BY參數

  • BY參數的語法爲BY 參考鍵,其中參考鍵可以是字符串類型或者是散列類型鍵的某個字段(表示爲鍵名->字段名),如果提供了BY參數,SORT命令將不再依據元素
    自身的值進行排序,而是對每個元素使用元素的值替換參考鍵中的第一個"*"並獲取其值,然後一句該值對元素排序
SORT tag:name BY post:*->time DESC
參考鍵還可以是字符串類型
LPUSH sortbylist 1 2 3
SET itemscore:1 50
SET itemscore:2 100
SET itemscore:3 -10
SORT sortbylist BY itemscore:* DESC
  • 當參考鍵名不包含"*"時(即常量鍵名,與元素值無關),SORT命令將不會執行排序操作,常用於不需要排序但需要藉助SORT命令獲得與元素相關聯的數據時
  • 如果幾個元素的參考鍵值相同,則SORT命令會再比較元素本身的值來決定元素的順序
  • 參考鍵雖然支持散列類型,但是"*“只能在”->“符號前面(即鍵名部分纔有用),在”->"後(即字段名部分)會被當成字段名本身而不會作爲佔位符被元素的值替換,
    即常量鍵名,這時由於每個元素的參考鍵值都是相同的,所以redis會按照元素本身的大小排列

SORT中的GET參數

  • GET參數不影響排序,它的作用是使SORT命令的返回結果不再是元素自身的值,而是GET參數中指定的鍵值,
  • GET參數也支持字符串類型和散列類型的鍵,並使用"*"作爲佔位符.
  • 在一個SORT命令中可以有多個GET參數(而BY參數只能有一個)
  • GET # 會返回元素本身的值
SORT tag:ports BY post:*->time DESC GET post:*->title GET post:*->time

SORT中的STORE參數

  • 默認情況下SORT會返回排序結果,使用STORE參數保留排序結果,如果要把結果保存到sort.result鍵中,
SORT tag:posts BY post:*->time DESC GET post:*->title GET post:*->time GET # STORE sort.result
  • 加上STORE參數後SORT命令的返回值爲結果的個數,保存的sort.result鍵的類型爲列表類型
  • STORE參數通常用來結合EXPIRE命令緩存排序結果

SORT性能優化

  • SORT命令的時間複雜度爲O(n+mlog(m)),其中n表示要排序的列表(集合或有序集合)中的元素個數,m表示要返回的元素個數
  • 當n較大的時候SORT命令的性能會相對較低,並且redis在排序前會建立一個長度爲n的容器來存儲待排序的元素,如果同時進行較大的大數據量排序操作會嚴重影響性能

注意:

  • 儘可能減少待排序鍵中元素的數量(使n儘可能小)
  • 使用LIMIT參數只獲取需要的數據(使m儘可能小)
  • 如果要排序的數據量較大,儘可能使用STORE參數將結果緩存
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章