文章目錄
事務(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參數將結果緩存